diff options
410 files changed, 0 insertions, 79813 deletions
diff --git a/Android.bp b/Android.bp deleted file mode 100644 index 9fed0814..00000000 --- a/Android.bp +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "common", - "guest", - "host", -] - -cc_library_headers { - name: "cuttlefish_common_headers", - vendor: true, - export_include_dirs: ["."], - host_supported: true, -} - -cc_library_headers { - name: "cuttlefish_common_headers_product", - product_specific: true, - export_include_dirs: ["."], - host_supported: true, -} - -// TODO(b/67435044) Update the include paths and remove this -cc_library_headers { - name: "cuttlefish_glog", - vendor: true, - export_include_dirs: ["common/libs"], - host_supported: true, -} - -// TODO(b/67435044) Update the include paths and remove this -cc_library_headers { - name: "cuttlefish_glog_product", - product_specific: true, - export_include_dirs: ["common/libs"], - host_supported: true, -} - -cc_defaults { - name: "cuttlefish_base", - gnu_extensions: false, - header_libs: [ - "cuttlefish_common_headers", - "cuttlefish_kernel_headers", - ], - target: { - host: { - host_ldlibs: ["-lrt"], - cflags: ["-DCUTTLEFISH_HOST"], - compile_multilib: "64", - }, - // We don't need Darwin host-side builds - darwin: { - enabled: false, - }, - }, - cflags: ["-Werror", "-Wall", "-D_FILE_OFFSET_BITS=64"], - vendor: true, -} - -cc_defaults { - name: "cuttlefish_guest_product_only", - product_specific: true, - gnu_extensions: false, - header_libs: [ - "cuttlefish_common_headers_product", - "cuttlefish_kernel_headers_product", - ], - target: { - host: { - host_ldlibs: ["-lrt"], - cflags: ["-DCUTTLEFISH_HOST"], - compile_multilib: "64", - }, - // We don't need Darwin host-side builds - darwin: { - enabled: false, - }, - }, - cflags: ["-Werror", "-Wall"], -} - -cc_defaults { - name: "cuttlefish_guest_only", - defaults: ["cuttlefish_base"], -} - -cc_defaults { - name: "cuttlefish_host_only", - device_supported: false, - host_supported: true, - defaults: ["cuttlefish_base"], -} - -cc_defaults { - name: "cuttlefish_host_and_guest", - host_supported: true, - defaults: ["cuttlefish_base"], -} diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 8e69e18b..00000000 --- a/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2017 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. -ifneq ($(filter vsoc_arm64 vsoc_x86 vsoc_x86_64, $(TARGET_BOARD_PLATFORM)),) -LOCAL_PATH:= $(call my-dir) -include $(call first-makefiles-under,$(LOCAL_PATH)) -endif diff --git a/OWNERS b/OWNERS deleted file mode 100644 index 9594320a..00000000 --- a/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -adelva@google.com -ghartman@google.com -jemoreira@google.com -malchev@google.com -muntsinger@google.com -natsu@google.com -rammuthiah@google.com -schuffelen@google.com diff --git a/TEST_MAPPING b/TEST_MAPPING deleted file mode 100644 index ef710ca2..00000000 --- a/TEST_MAPPING +++ /dev/null @@ -1,18 +0,0 @@ -{ - "postsubmit" : [ - { - "name": "tombstone_transmit_tests" - } - ], - "presubmit": [ - { - "name": "vts_treble_vintf_framework_test" - }, - { - "name": "vts_treble_vintf_vendor_test" - }, - { - "name": "hidl_implementation_test" - } - ] -} diff --git a/common/Android.bp b/common/Android.bp deleted file mode 100644 index 2280c23e..00000000 --- a/common/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "commands", - "frontend", - "libs", -] diff --git a/common/commands/Android.bp b/common/commands/Android.bp deleted file mode 100644 index 8264fcc0..00000000 --- a/common/commands/Android.bp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ -] diff --git a/common/frontend/Android.bp b/common/frontend/Android.bp deleted file mode 100644 index 39a4dbb9..00000000 --- a/common/frontend/Android.bp +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (C) 2018 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. - -subdirs = [ - "socket_vsock_proxy", -] diff --git a/common/frontend/socket_vsock_proxy/Android.bp b/common/frontend/socket_vsock_proxy/Android.bp deleted file mode 100644 index 310244ab..00000000 --- a/common/frontend/socket_vsock_proxy/Android.bp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_binary { - name: "socket_vsock_proxy", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "libcuttlefish_utils", - "liblog", - ], - static_libs: [ - "libgflags", - ], - header_libs: [ - "cuttlefish_glog", - ], - target: { - host: { - static_libs: [ - "libcuttlefish_host_config", - "libjsoncpp", - ], - }, - }, - defaults: ["cuttlefish_host_and_guest"] -} diff --git a/common/frontend/socket_vsock_proxy/main.cpp b/common/frontend/socket_vsock_proxy/main.cpp deleted file mode 100644 index 31cff0b5..00000000 --- a/common/frontend/socket_vsock_proxy/main.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <set> -#include <thread> -#include <glog/logging.h> -#include <gflags/gflags.h> - -#include "common/libs/fs/shared_fd.h" - -#ifdef CUTTLEFISH_HOST -#include "host/libs/config/cuttlefish_config.h" -#endif - -struct Header { - std::uint32_t payload_length; - enum MessageType : std::uint32_t { - DATA = 0, - BEGIN, - END, - RECV_CLOSED, // indicate that this side's receive end is closed - RESTART, - }; - MessageType message_type; -}; - -constexpr std::size_t kMaxPacketSize = 8192; -constexpr std::size_t kMaxPayloadSize = kMaxPacketSize - sizeof(Header); - -struct Packet { - private: - Header header_; - using Payload = char[kMaxPayloadSize]; - Payload payload_data_; - - static constexpr Packet MakePacket(Header::MessageType type) { - Packet packet{}; - packet.header_.message_type = type; - return packet; - } - - public: - // port is only revelant on the host-side. - static Packet MakeBegin(std::uint16_t port); - - static constexpr Packet MakeEnd() { return MakePacket(Header::END); } - - static constexpr Packet MakeRecvClosed() { - return MakePacket(Header::RECV_CLOSED); - } - - static constexpr Packet MakeRestart() { return MakePacket(Header::RESTART); } - - // NOTE payload and payload_length must still be set. - static constexpr Packet MakeData() { return MakePacket(Header::DATA); } - - bool empty() const { return IsData() && header_.payload_length == 0; } - - void set_payload_length(std::uint32_t length) { - CHECK_LE(length, sizeof payload_data_); - header_.payload_length = length; - } - - Payload& payload() { return payload_data_; } - - const Payload& payload() const { return payload_data_; } - - constexpr std::uint32_t payload_length() const { - return header_.payload_length; - } - - constexpr bool IsBegin() const { - return header_.message_type == Header::BEGIN; - } - - constexpr bool IsEnd() const { return header_.message_type == Header::END; } - - constexpr bool IsData() const { return header_.message_type == Header::DATA; } - - constexpr bool IsRecvClosed() const { - return header_.message_type == Header::RECV_CLOSED; - } - - constexpr bool IsRestart() const { - return header_.message_type == Header::RESTART; - } - - constexpr std::uint16_t port() const { - CHECK(IsBegin()); - std::uint16_t port_number{}; - CHECK_EQ(payload_length(), sizeof port_number); - std::memcpy(&port_number, payload(), sizeof port_number); - return port_number; - } - - char* raw_data() { return reinterpret_cast<char*>(this); } - - const char* raw_data() const { return reinterpret_cast<const char*>(this); } - - constexpr size_t raw_data_length() const { - return payload_length() + sizeof header_; - } -}; - -static_assert(sizeof(Packet) == kMaxPacketSize, ""); -static_assert(std::is_pod<Packet>{}, ""); - -DEFINE_uint32(tcp_port, 0, "TCP port (server on host, client on guest)"); -DEFINE_uint32(vsock_port, 0, "vsock port (client on host, server on guest"); -DEFINE_uint32(vsock_guest_cid, 0, "Guest identifier"); - -namespace { -// Sends packets, Shutdown(SHUT_WR) on destruction -class SocketSender { - public: - explicit SocketSender(cvd::SharedFD socket) : socket_{socket} {} - - SocketSender(SocketSender&&) = default; - SocketSender& operator=(SocketSender&&) = default; - - SocketSender(const SocketSender&&) = delete; - SocketSender& operator=(const SocketSender&) = delete; - - ~SocketSender() { - if (socket_.operator->()) { // check that socket_ was not moved-from - socket_->Shutdown(SHUT_WR); - } - } - - ssize_t SendAll(const Packet& packet) { - ssize_t written{}; - while (written < static_cast<ssize_t>(packet.payload_length())) { - if (!socket_->IsOpen()) { - return -1; - } - auto just_written = - socket_->Send(packet.payload() + written, - packet.payload_length() - written, MSG_NOSIGNAL); - if (just_written <= 0) { - LOG(INFO) << "Couldn't write to client: " - << strerror(socket_->GetErrno()); - return just_written; - } - written += just_written; - } - return written; - } - - private: - cvd::SharedFD socket_; -}; - -class SocketReceiver { - public: - explicit SocketReceiver(cvd::SharedFD socket) : socket_{socket} {} - - SocketReceiver(SocketReceiver&&) = default; - SocketReceiver& operator=(SocketReceiver&&) = default; - - SocketReceiver(const SocketReceiver&&) = delete; - SocketReceiver& operator=(const SocketReceiver&) = delete; - - // *packet will be empty if Read returns 0 or error - void Recv(Packet* packet) { - auto size = socket_->Read(packet->payload(), sizeof packet->payload()); - if (size < 0) { - size = 0; - } - packet->set_payload_length(size); - } - - private: - cvd::SharedFD socket_; -}; - -void SocketToVsock(SocketReceiver socket_receiver, - SocketSender vsock_sender) { - while (true) { - auto packet = Packet::MakeData(); - socket_receiver.Recv(&packet); - if (packet.empty() || vsock_sender.SendAll(packet) < 0) { - break; - } - } - LOG(INFO) << "Socket to vsock exiting"; -} - -void VsockToSocket(SocketSender socket_sender, - SocketReceiver vsock_receiver) { - auto packet = Packet::MakeData(); - while (true) { - vsock_receiver.Recv(&packet); - CHECK(packet.IsData()); - if (packet.empty()) { - break; - } - if (socket_sender.SendAll(packet) < 0) { - break; - } - } - LOG(INFO) << "Vsock to socket exiting"; -} - -// One thread for reading from shm and writing into a socket. -// One thread for reading from a socket and writing into shm. -void HandleConnection(cvd::SharedFD vsock, - cvd::SharedFD socket) { - auto socket_to_vsock = - std::thread(SocketToVsock, SocketReceiver{socket}, SocketSender{vsock}); - VsockToSocket(SocketSender{socket}, SocketReceiver{vsock}); - socket_to_vsock.join(); -} - -#ifdef CUTTLEFISH_HOST -[[noreturn]] void host() { - LOG(INFO) << "starting server on " << FLAGS_tcp_port << " for vsock port " - << FLAGS_vsock_port; - auto server = cvd::SharedFD::SocketLocalServer(FLAGS_tcp_port, SOCK_STREAM); - CHECK(server->IsOpen()) << "Could not start server on " << FLAGS_tcp_port; - LOG(INFO) << "Accepting client connections"; - int last_failure_reason = 0; - while (true) { - auto client_socket = cvd::SharedFD::Accept(*server); - CHECK(client_socket->IsOpen()) << "error creating client socket"; - cvd::SharedFD vsock_socket = cvd::SharedFD::VsockClient( - FLAGS_vsock_guest_cid, FLAGS_vsock_port, SOCK_STREAM); - if (vsock_socket->IsOpen()) { - last_failure_reason = 0; - LOG(INFO) << "Connected to vsock:" << FLAGS_vsock_guest_cid << ":" - << FLAGS_vsock_port; - } else { - // Don't log if the previous connection failed with the same error - if (last_failure_reason != vsock_socket->GetErrno()) { - last_failure_reason = vsock_socket->GetErrno(); - LOG(ERROR) << "Unable to connect to vsock server: " - << vsock_socket->StrError(); - } - continue; - } - auto thread = std::thread(HandleConnection, std::move(vsock_socket), - std::move(client_socket)); - thread.detach(); - } -} - -#else -cvd::SharedFD OpenSocketConnection() { - while (true) { - auto sock = cvd::SharedFD::SocketLocalClient(FLAGS_tcp_port, SOCK_STREAM); - if (sock->IsOpen()) { - return sock; - } - LOG(WARNING) << "could not connect on port " << FLAGS_tcp_port - << ". sleeping for 1 second"; - sleep(1); - } -} - -bool socketErrorIsRecoverable(int error) { - std::set<int> unrecoverable{EACCES, EAFNOSUPPORT, EINVAL, EPROTONOSUPPORT}; - return unrecoverable.find(error) == unrecoverable.end(); -} - -[[noreturn]] static void SleepForever() { - while (true) { - sleep(std::numeric_limits<unsigned int>::max()); - } -} - -[[noreturn]] void guest() { - LOG(INFO) << "Starting guest mainloop"; - LOG(INFO) << "starting server on " << FLAGS_vsock_port; - cvd::SharedFD vsock; - do { - vsock = cvd::SharedFD::VsockServer(FLAGS_vsock_port, SOCK_STREAM); - if (!vsock->IsOpen() && !socketErrorIsRecoverable(vsock->GetErrno())) { - LOG(ERROR) << "Could not open vsock socket: " << vsock->StrError(); - SleepForever(); - } - } while (!vsock->IsOpen()); - CHECK(vsock->IsOpen()) << "Could not start server on " << FLAGS_vsock_port; - while (true) { - LOG(INFO) << "waiting for vsock connection"; - auto vsock_client = cvd::SharedFD::Accept(*vsock); - CHECK(vsock_client->IsOpen()) << "error creating vsock socket"; - LOG(INFO) << "vsock socket accepted"; - auto client = OpenSocketConnection(); - CHECK(client->IsOpen()) << "error connecting to guest client"; - auto thread = std::thread(HandleConnection, std::move(vsock_client), - std::move(client)); - thread.detach(); - } -} - -#endif -} // namespace - -int main(int argc, char* argv[]) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - - CHECK(FLAGS_tcp_port != 0) << "Must specify -tcp_port flag"; - CHECK(FLAGS_vsock_port != 0) << "Must specify -vsock_port flag"; -#ifdef CUTTLEFISH_HOST - CHECK(FLAGS_vsock_guest_cid != 0) << "Must specify -vsock_guest_cid flag"; - host(); -#else - guest(); -#endif -} diff --git a/common/libs/Android.bp b/common/libs/Android.bp deleted file mode 100644 index 40b7f0c1..00000000 --- a/common/libs/Android.bp +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "device_config", - "fs", - "net", - "strings", - "tcp_socket", - "threads", - "time", - "utils", -] diff --git a/common/libs/device_config/Android.bp b/common/libs/device_config/Android.bp deleted file mode 100644 index 4900d35a..00000000 --- a/common/libs/device_config/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_library_shared { - name: "libcuttlefish_device_config", - srcs: [ - "device_config.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "liblog", - "libcuttlefish_fs", - "libcuttlefish_utils", - ], - target: { - host: { - srcs: [ - "host_device_config.cpp", - ], - static_libs: [ - "libcuttlefish_host_config", - "libjsoncpp", - ], - }, - android: { - srcs: [ - "guest_device_config.cpp", - ], - shared_libs: [ - "libcutils", - ], - }, - }, - defaults: ["cuttlefish_host_and_guest"], -} diff --git a/common/libs/device_config/device_config.cpp b/common/libs/device_config/device_config.cpp deleted file mode 100644 index 69c489fc..00000000 --- a/common/libs/device_config/device_config.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "device_config.h" - -#include <sstream> -#include <type_traits> - -#include <glog/logging.h> - -namespace cvd { - -// TODO(jemoreira): Endianness when on arm64 guest and x86 host is a problem -// Raw data is sent through a vsocket from host to guest, this assert tries to -// ensure the binary representation of the struct is the same in both sides. -static constexpr int kRawDataSize = 68 + 16; // ril + screen -static_assert(sizeof(DeviceConfig::RawData) == kRawDataSize && - std::is_trivial<DeviceConfig::RawData>().value, - "DeviceConfigRawData needs to be the same in host and guess, did " - "you forget to update the size?"); - -namespace { - -static constexpr auto kDataSize = sizeof(DeviceConfig::RawData); - -} // namespace - -bool DeviceConfig::SendRawData(cvd::SharedFD fd) { - std::size_t sent = 0; - auto buffer = reinterpret_cast<uint8_t*>(&data_); - while (sent < kDataSize) { - auto bytes = fd->Write(buffer + sent, kDataSize - sent); - if (bytes < 0) { - // Don't log here, let the caller do it. - return false; - } - sent += bytes; - } - return true; -} - -void DeviceConfig::generate_address_and_prefix() { - std::ostringstream ss; - ss << ril_ipaddr() << "/" << ril_prefixlen(); - ril_address_and_prefix_ = ss.str(); -} - -} // namespace cvd
\ No newline at end of file diff --git a/common/libs/device_config/device_config.h b/common/libs/device_config/device_config.h deleted file mode 100644 index 0e3680fe..00000000 --- a/common/libs/device_config/device_config.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <common/libs/fs/shared_fd.h> -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#ifdef CUTTLEFISH_HOST -#include <host/libs/config/cuttlefish_config.h> -#endif - -namespace cvd { - -class DeviceConfig { - public: - /** - * WARNING: Consider the possibility of different endianness between host and - * guest when adding fields of more than one byte to this struct: - * This struct is meant to be sent from host to guest so the binary - * representation must be the same. There is a static test that checks for - * alignment problems, but there is no such thing for endianness. - */ - struct RawData { - struct { - char ipaddr[16]; // xxx.xxx.xxx.xxx\0 = 16 bytes - char gateway[16]; - char dns[16]; - char broadcast[16]; - uint8_t prefixlen; - uint8_t reserved[3]; - } ril; - struct { - int32_t x_res; - int32_t y_res; - int32_t dpi; - int32_t refresh_rate; - } screen; - }; - - static std::unique_ptr<DeviceConfig> Get(); - - bool SendRawData(cvd::SharedFD fd); - - const char* ril_address_and_prefix() const { - return ril_address_and_prefix_.c_str(); - }; - const char* ril_ipaddr() const { return data_.ril.ipaddr; } - const char* ril_gateway() const { return data_.ril.gateway; } - const char* ril_dns() const { return data_.ril.dns; } - const char* ril_broadcast() const { return data_.ril.broadcast; } - int ril_prefixlen() const { return data_.ril.prefixlen; } - int32_t screen_x_res() { return data_.screen.x_res; } - int32_t screen_y_res() { return data_.screen.y_res; } - int32_t screen_dpi() { return data_.screen.dpi; } - int32_t screen_refresh_rate() { return data_.screen.refresh_rate; } - - private: - void generate_address_and_prefix(); -#ifdef CUTTLEFISH_HOST - DeviceConfig() = default; - bool InitializeNetworkConfiguration(const vsoc::CuttlefishConfig& config); - void InitializeScreenConfiguration(const vsoc::CuttlefishConfig& config); -#else - explicit DeviceConfig(const RawData& data); -#endif - - RawData data_; - std::string ril_address_and_prefix_; -}; - -} // namespace cvd diff --git a/common/libs/device_config/guest_device_config.cpp b/common/libs/device_config/guest_device_config.cpp deleted file mode 100644 index d5558b96..00000000 --- a/common/libs/device_config/guest_device_config.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "device_config.h" - -#include <chrono> -#include <thread> - -#include <cutils/properties.h> -#include <glog/logging.h> - -namespace cvd { - -namespace { - -static constexpr auto kDataSize = sizeof(DeviceConfig::RawData); -static constexpr int kRetries = 5; -static constexpr int kRetryDelaySeconds = 5; - -bool GetRawFromServer(DeviceConfig::RawData* data) { - auto port_property = "ro.boot.cuttlefish_config_server_port"; - auto port = property_get_int32(port_property, -1); - if (port < 0) { - LOG(ERROR) << "Unable to get config server port from property: " << - port_property; - return false; - } - auto config_server = - cvd::SharedFD::VsockClient(2 /*host cid*/, port, SOCK_STREAM); - if (!config_server->IsOpen()) { - LOG(ERROR) << "Unable to connect to config server: " - << config_server->StrError(); - return false; - } - uint8_t* buffer = reinterpret_cast<uint8_t*>(data); - size_t read_idx = 0; - while (read_idx < kDataSize) { - auto read = config_server->Read(buffer + read_idx, kDataSize - read_idx); - if (read == 0) { - LOG(ERROR) << "Unexpected EOF while reading from config server, read " - << read_idx << " bytes, expected " << kDataSize; - return false; - } - if (read < 0) { - LOG(ERROR) << "Error reading from config server: " - << config_server->StrError(); - return false; - } - read_idx += read; - } - return true; -} - -} // namespace - -std::unique_ptr<DeviceConfig> DeviceConfig::Get() { - DeviceConfig::RawData data; - - int attempts_remaining = 1 + kRetries; - while (attempts_remaining > 0) { - if (GetRawFromServer(&data)) { - return std::unique_ptr<DeviceConfig>(new DeviceConfig(data)); - } - - std::this_thread::sleep_for(std::chrono::seconds(kRetryDelaySeconds)); - - --attempts_remaining; - } - return nullptr; -} - -DeviceConfig::DeviceConfig(const DeviceConfig::RawData& data) : data_(data) { - generate_address_and_prefix(); -} - -} // namespace cvd diff --git a/common/libs/device_config/host_device_config.cpp b/common/libs/device_config/host_device_config.cpp deleted file mode 100644 index eaa43edc..00000000 --- a/common/libs/device_config/host_device_config.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <arpa/inet.h> -#include <glog/logging.h> -#include <ifaddrs.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> - -#include "device_config.h" - -namespace cvd { - -namespace { - -uint8_t number_of_ones(unsigned long val) { - uint8_t ret = 0; - while (val) { - ret += val % 2; - val >>= 1; - } - return ret; -} - -class NetConfig { - public: - uint8_t ril_prefixlen = -1; - std::string ril_ipaddr; - std::string ril_gateway; - std::string ril_dns = "8.8.8.8"; - std::string ril_broadcast; - - bool ObtainConfig(const std::string& interface) { - bool ret = ParseIntefaceAttributes(interface); - LOG(INFO) << "Network config:"; - LOG(INFO) << "ipaddr = " << ril_ipaddr; - LOG(INFO) << "gateway = " << ril_gateway; - LOG(INFO) << "dns = " << ril_dns; - LOG(INFO) << "broadcast = " << ril_broadcast; - LOG(INFO) << "prefix length = " << static_cast<int>(ril_prefixlen); - return ret; - } - - private: - bool ParseIntefaceAttributes(struct ifaddrs* ifa) { - struct sockaddr_in* sa; - char* addr_str; - - // Gateway - sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_addr); - addr_str = inet_ntoa(sa->sin_addr); - this->ril_gateway = strtok(addr_str, "\n"); - auto gateway_s_addr = ntohl(sa->sin_addr.s_addr); - - // Broadcast - sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr); - addr_str = inet_ntoa(sa->sin_addr); - this->ril_broadcast = strtok(addr_str, "\n"); - auto broadcast_s_addr = ntohl(sa->sin_addr.s_addr); - - // Netmask - sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_netmask); - this->ril_prefixlen = number_of_ones(sa->sin_addr.s_addr); - auto netmask_s_addr = ntohl(sa->sin_addr.s_addr); - - // Address (Find an address in the network different than the network, the - // gateway and the broadcast) - auto network = gateway_s_addr & netmask_s_addr; - auto s_addr = network + 1; - // s_addr & ~netmask_s_addr is zero when s_addr wraps around the network - while (s_addr & ~netmask_s_addr) { - if (s_addr != gateway_s_addr && s_addr != broadcast_s_addr) { - break; - } - ++s_addr; - } - if (s_addr == network) { - LOG(ERROR) << "No available address found in interface " << ifa->ifa_name; - return false; - } - struct in_addr addr; - addr.s_addr = htonl(s_addr); - addr_str = inet_ntoa(addr); - this->ril_ipaddr = strtok(addr_str, "\n"); - return true; - } - - bool ParseIntefaceAttributes(const std::string& interface) { - struct ifaddrs *ifa_list{}, *ifa{}; - bool ret = false; - getifaddrs(&ifa_list); - for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) { - if (strcmp(ifa->ifa_name, interface.c_str()) == 0 && - ifa->ifa_addr->sa_family == AF_INET) { - ret = ParseIntefaceAttributes(ifa); - break; - } - } - freeifaddrs(ifa_list); - return ret; - } -}; - -inline void CopyChars(char* dest, size_t size, const char* src) { - auto res = snprintf(dest, size, "%s", src); - if (res >= static_cast<int>(size)) { - LOG(ERROR) << "Longer(" << res << ") than expected(" << (size - 1) - << ") config string was truncated: " << dest; - } -} - -} // namespace - -std::unique_ptr<DeviceConfig> DeviceConfig::Get() { - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) return nullptr; - std::unique_ptr<DeviceConfig> dev_config(new DeviceConfig()); - if (!dev_config->InitializeNetworkConfiguration(*config)) { - return nullptr; - } - dev_config->InitializeScreenConfiguration(*config); - return dev_config; -} - -bool DeviceConfig::InitializeNetworkConfiguration( - const vsoc::CuttlefishConfig& config) { - NetConfig netconfig; - if (!netconfig.ObtainConfig(config.mobile_bridge_name())) { - LOG(ERROR) << "Unable to obtain the network configuration"; - return false; - } - - auto res = snprintf(data_.ril.ipaddr, sizeof(data_.ril.ipaddr), "%s", - netconfig.ril_ipaddr.c_str()); - if (res >= (int)sizeof(data_.ril.ipaddr)) { - LOG(ERROR) << "Longer than expected config string was truncated: " - << data_.ril.ipaddr; - } - CopyChars(data_.ril.gateway, sizeof(data_.ril.gateway), - netconfig.ril_gateway.c_str()); - CopyChars(data_.ril.dns, sizeof(data_.ril.dns), netconfig.ril_dns.c_str()); - CopyChars(data_.ril.broadcast, sizeof(data_.ril.broadcast), - netconfig.ril_broadcast.c_str()); - data_.ril.prefixlen = netconfig.ril_prefixlen; - - generate_address_and_prefix(); - - return true; -} - -void DeviceConfig::InitializeScreenConfiguration( - const vsoc::CuttlefishConfig& config) { - data_.screen.x_res = config.x_res(); - data_.screen.y_res = config.y_res(); - data_.screen.dpi = config.dpi(); - data_.screen.refresh_rate = config.refresh_rate_hz(); -} - -} // namespace cvd diff --git a/common/libs/fs/Android.bp b/common/libs/fs/Android.bp deleted file mode 100644 index 9f5d55e7..00000000 --- a/common/libs/fs/Android.bp +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_library { - name: "libcuttlefish_fs", - srcs: [ - "shared_buf.cc", - "shared_fd.cpp", - ], - shared: { - shared_libs: [ - "libbase", - "liblog", - ], - }, - static: { - static_libs: [ - "libbase", - "liblog", - ], - }, - target: { - vendor: { - // Liblog does not have a vendor-static variant. - shared_libs: ["liblog"], - exclude_static_libs: ["liblog"], - }, - }, - defaults: ["cuttlefish_host_and_guest"], -} - -cc_library_static { - name: "libcuttlefish_fs_product", - srcs: [ - "shared_buf.cc", - "shared_fd.cpp", - ], - shared_libs: [ - "libbase", - "liblog", - ], - stl: "libc++_static", - defaults: ["cuttlefish_guest_product_only"], -} - -cc_test_host { - name: "libcuttlefish_fs_tests", - srcs: [ - "shared_fd_test.cpp", - ], - header_libs: ["cuttlefish_glog"], - shared_libs: [ - "libcuttlefish_fs", - "libbase", - ], - static_libs: [ - "libgmock", - "libgtest_host", - ], - defaults: ["cuttlefish_host_only"], - test_suites: ["general-tests"], -} diff --git a/common/libs/fs/TEST_MAPPING b/common/libs/fs/TEST_MAPPING deleted file mode 100644 index 162fcf6b..00000000 --- a/common/libs/fs/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presubmit": [ - { - "name": "libcuttlefish_fs_tests", - "host": true - } - ] -} diff --git a/common/libs/fs/shared_buf.cc b/common/libs/fs/shared_buf.cc deleted file mode 100644 index 84397a07..00000000 --- a/common/libs/fs/shared_buf.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sstream> -#include <string> -#include <thread> -#include <vector> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" - -namespace cvd { - -namespace { - -const size_t BUFF_SIZE = 1 << 14; - -} // namespace - -ssize_t ReadAll(SharedFD fd, std::string* buf) { - char buff[BUFF_SIZE]; - std::stringstream ss; - ssize_t read; - while ((read = fd->Read(buff, BUFF_SIZE - 1)) > 0) { - // this is necessary to avoid problems with having a '\0' in the middle of the buffer - ss << std::string(buff, read); - } - if (read < 0) { - errno = fd->GetErrno(); - return read; - } - *buf = ss.str(); - return buf->size(); -} - -ssize_t ReadExact(SharedFD fd, std::string* buf) { - size_t total_read = 0; - ssize_t read = 0; - while ((read = fd->Read((void*)&((*buf)[total_read]), buf->size() - total_read)) > 0) { - if (read < 0) { - errno = fd->GetErrno(); - return read; - } - total_read += read; - if (total_read == buf->size()) { - break; - } - } - return total_read; -} - -ssize_t WriteAll(SharedFD fd, const std::string& buf) { - size_t total_written = 0; - ssize_t written = 0; - while ((written = fd->Write((void*)&(buf[total_written]), buf.size() - total_written)) > 0) { - if (written < 0) { - errno = fd->GetErrno(); - return written; - } - total_written += written; - if (total_written == buf.size()) { - break; - } - } - return total_written; -} - -} // namespace cvd diff --git a/common/libs/fs/shared_buf.h b/common/libs/fs/shared_buf.h deleted file mode 100644 index 3577fa11..00000000 --- a/common/libs/fs/shared_buf.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string> -#include <thread> -#include <vector> - -#include "common/libs/fs/shared_fd.h" - -namespace cvd { - -/** - * Reads from fd until it is closed or errors, storing all data in buf. - * - * On a successful read, returns the number of bytes read. - * - * If a read error is encountered, returns -1. buf will contain any data read - * up until that point and errno will be set. - */ -ssize_t ReadAll(SharedFD fd, std::string* buf); - -/** - * Reads from fd until reading buf->size() bytes or errors. - * - * On a successful read, returns buf->size(). - * - * If a read error is encountered, returns -1. buf will contain any data read - * up until that point and errno will be set. - */ -ssize_t ReadExact(SharedFD fd, std::string* buf); - -/** - * Writes to fd until writing all bytes in buf. - * - * On a successful write, returns buf.size(). - * - * If a write error is encountered, returns -1. Some data may have already been - * written to fd at that point. - */ -ssize_t WriteAll(SharedFD fd, const std::string& buf); - -} // namespace cvd diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp deleted file mode 100644 index 2f6d1003..00000000 --- a/common/libs/fs/shared_fd.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/fs/shared_fd.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <cstddef> -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <unistd.h> -#include <algorithm> -#include <vector> - -#include "common/libs/glog/logging.h" -#include "common/libs/fs/shared_select.h" - -// #define ENABLE_GCE_SHARED_FD_LOGGING 1 - -namespace { -using cvd::SharedFDSet; - -void MarkAll(const SharedFDSet& input, fd_set* dest, int* max_index) { - for (SharedFDSet::const_iterator it = input.begin(); it != input.end(); - ++it) { - (*it)->Set(dest, max_index); - } -} - -void CheckMarked(fd_set* in_out_mask, SharedFDSet* in_out_set) { - if (!in_out_set) { - return; - } - SharedFDSet save; - save.swap(in_out_set); - for (SharedFDSet::iterator it = save.begin(); it != save.end(); ++it) { - if ((*it)->IsSet(in_out_mask)) { - in_out_set->Set(*it); - } - } -} -} // namespace - -namespace cvd { - -bool FileInstance::CopyFrom(FileInstance& in) { - std::vector<char> buffer(8192); - while (true) { - ssize_t num_read = in.Read(buffer.data(), buffer.size()); - if (!num_read) { - return true; - } - if (num_read == -1) { - return false; - } - if (num_read > 0) { - if (Write(buffer.data(), num_read) != num_read) { - // The caller will have to log an appropriate message. - return false; - } - } - } - return true; -} - -bool FileInstance::CopyFrom(FileInstance& in, size_t length) { - std::vector<char> buffer(8192); - while (length > 0) { - ssize_t num_read = in.Read(buffer.data(), std::min(buffer.size(), length)); - length -= num_read; - if (num_read <= 0) { - return false; - } - if (Write(buffer.data(), num_read) != num_read) { - // The caller will have to log an appropriate message. - return false; - } - } - return true; -} - -void FileInstance::Close() { - std::stringstream message; - if (fd_ == -1) { - errno_ = EBADF; - } else if (close(fd_) == -1) { - errno_ = errno; - if (identity_.size()) { - message << __FUNCTION__ << ": " << identity_ << " failed (" << StrError() << ")"; - std::string message_str = message.str(); - Log(message_str.c_str()); - } - } else { - if (identity_.size()) { - message << __FUNCTION__ << ": " << identity_ << "succeeded"; - std::string message_str = message.str(); - Log(message_str.c_str()); - } - } - fd_ = -1; -} - -void FileInstance::Identify(const char* identity) { - std::stringstream identity_stream; - identity_stream << "fd=" << fd_ << " @" << this << " is " << identity; - identity_ = identity_stream.str(); - std::stringstream message; - message << __FUNCTION__ << ": " << identity_; - std::string message_str = message.str(); - Log(message_str.c_str()); -} - -bool FileInstance::IsSet(fd_set* in) const { - if (IsOpen() && FD_ISSET(fd_, in)) { - return true; - } - return false; -} - -#if ENABLE_GCE_SHARED_FD_LOGGING -void FileInstance::Log(const char* message) { - LOG(INFO) << message; -} -#else -void FileInstance::Log(const char*) {} -#endif - -void FileInstance::Set(fd_set* dest, int* max_index) const { - if (!IsOpen()) { - return; - } - if (fd_ >= *max_index) { - *max_index = fd_ + 1; - } - FD_SET(fd_, dest); -} - -int Select(SharedFDSet* read_set, SharedFDSet* write_set, - SharedFDSet* error_set, struct timeval* timeout) { - int max_index = 0; - fd_set readfds; - FD_ZERO(&readfds); - if (read_set) { - MarkAll(*read_set, &readfds, &max_index); - } - fd_set writefds; - FD_ZERO(&writefds); - if (write_set) { - MarkAll(*write_set, &writefds, &max_index); - } - fd_set errorfds; - FD_ZERO(&errorfds); - if (error_set) { - MarkAll(*error_set, &errorfds, &max_index); - } - - int rval = TEMP_FAILURE_RETRY( - select(max_index, &readfds, &writefds, &errorfds, timeout)); - FileInstance::Log("select\n"); - CheckMarked(&readfds, read_set); - CheckMarked(&writefds, write_set); - CheckMarked(&errorfds, error_set); - return rval; -} - -static void MakeAddress(const char* name, bool abstract, - struct sockaddr_un* dest, socklen_t* len) { - memset(dest, 0, sizeof(*dest)); - dest->sun_family = AF_UNIX; - // sun_path is NOT expected to be nul-terminated. - // See man 7 unix. - size_t namelen; - if (abstract) { - // ANDROID_SOCKET_NAMESPACE_ABSTRACT - namelen = strlen(name); - CHECK_LE(namelen, sizeof(dest->sun_path) - 1) - << "MakeAddress failed. Name=" << name << " is longer than allowed."; - dest->sun_path[0] = 0; - memcpy(dest->sun_path + 1, name, namelen); - } else { - // ANDROID_SOCKET_NAMESPACE_RESERVED - // ANDROID_SOCKET_NAMESPACE_FILESYSTEM - // TODO(pinghao): Distinguish between them? - namelen = strlen(name); - CHECK_LE(namelen, sizeof(dest->sun_path)) - << "MakeAddress failed. Name=" << name << " is longer than allowed."; - strncpy(dest->sun_path, name, strlen(name)); - } - *len = namelen + offsetof(struct sockaddr_un, sun_path) + 1; -} - -SharedFD SharedFD::SocketSeqPacketServer(const char* name, mode_t mode) { - return SocketLocalServer(name, false, SOCK_SEQPACKET, mode); -} - -SharedFD SharedFD::SocketSeqPacketClient(const char* name) { - return SocketLocalClient(name, false, SOCK_SEQPACKET); -} - -SharedFD SharedFD::TimerFD(int clock, int flags) { - int fd = timerfd_create(clock, flags); - if (fd == -1) { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, errno))); - } else { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, 0))); - } -} - -SharedFD SharedFD::Accept(const FileInstance& listener, struct sockaddr* addr, - socklen_t* addrlen) { - return SharedFD( - std::shared_ptr<FileInstance>(listener.Accept(addr, addrlen))); -} - -SharedFD SharedFD::Accept(const FileInstance& listener) { - return SharedFD::Accept(listener, NULL, NULL); -} - -SharedFD SharedFD::Dup(int unmanaged_fd) { - int fd = fcntl(unmanaged_fd, F_DUPFD_CLOEXEC, 3); - int error_num = errno; - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, error_num))); -} - -bool SharedFD::Pipe(SharedFD* fd0, SharedFD* fd1) { - int fds[2]; - int rval = pipe(fds); - if (rval != -1) { - (*fd0) = std::shared_ptr<FileInstance>(new FileInstance(fds[0], errno)); - (*fd1) = std::shared_ptr<FileInstance>(new FileInstance(fds[1], errno)); - return true; - } - return false; -} - -SharedFD SharedFD::Event(int initval, int flags) { - int fd = eventfd(initval, flags); - return std::shared_ptr<FileInstance>(new FileInstance(fd, errno)); -} - -SharedFD SharedFD::Epoll(int flags) { - int fd = epoll_create1(flags); - return std::shared_ptr<FileInstance>(new FileInstance(fd, errno)); -} - -bool SharedFD::SocketPair(int domain, int type, int protocol, - SharedFD* fd0, SharedFD* fd1) { - int fds[2]; - int rval = socketpair(domain, type, protocol, fds); - if (rval != -1) { - (*fd0) = std::shared_ptr<FileInstance>(new FileInstance(fds[0], errno)); - (*fd1) = std::shared_ptr<FileInstance>(new FileInstance(fds[1], errno)); - return true; - } - return false; -} - -SharedFD SharedFD::Open(const char* path, int flags, mode_t mode) { - int fd = TEMP_FAILURE_RETRY(open(path, flags, mode)); - if (fd == -1) { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, errno))); - } else { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, 0))); - } -} - -SharedFD SharedFD::Creat(const char* path, mode_t mode) { - return SharedFD::Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode); -} - -SharedFD SharedFD::Socket(int domain, int socket_type, int protocol) { - int fd = TEMP_FAILURE_RETRY(socket(domain, socket_type, protocol)); - if (fd == -1) { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, errno))); - } else { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(fd, 0))); - } -} - -SharedFD SharedFD::ErrorFD(int error) { - return SharedFD(std::shared_ptr<FileInstance>(new FileInstance(-1, error))); -} - -SharedFD SharedFD::SocketLocalClient(const char* name, bool abstract, - int in_type) { - struct sockaddr_un addr; - socklen_t addrlen; - MakeAddress(name, abstract, &addr, &addrlen); - SharedFD rval = SharedFD::Socket(PF_UNIX, in_type, 0); - if (!rval->IsOpen()) { - return rval; - } - if (rval->Connect(reinterpret_cast<sockaddr*>(&addr), addrlen) == -1) { - return SharedFD::ErrorFD(rval->GetErrno()); - } - return rval; -} - -SharedFD SharedFD::SocketLocalClient(int port, int type) { - sockaddr_in addr{}; - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - SharedFD rval = SharedFD::Socket(AF_INET, type, 0); - if (!rval->IsOpen()) { - return rval; - } - if (rval->Connect(reinterpret_cast<const sockaddr*>(&addr), - sizeof addr) < 0) { - return SharedFD::ErrorFD(rval->GetErrno()); - } - return rval; -} - -SharedFD SharedFD::SocketLocalServer(int port, int type) { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - SharedFD rval = SharedFD::Socket(AF_INET, type, 0); - if(!rval->IsOpen()) { - return rval; - } - int n = 1; - if (rval->SetSockOpt(SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) { - LOG(ERROR) << "SetSockOpt failed " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - if(rval->Bind(reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0) { - LOG(ERROR) << "Bind failed " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - if (type == SOCK_STREAM) { - if (rval->Listen(4) < 0) { - LOG(ERROR) << "Listen failed " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - } - return rval; -} - -SharedFD SharedFD::SocketLocalServer(const char* name, bool abstract, - int in_type, mode_t mode) { - // DO NOT UNLINK addr.sun_path. It does NOT have to be null-terminated. - // See man 7 unix for more details. - if (!abstract) (void)unlink(name); - - struct sockaddr_un addr; - socklen_t addrlen; - MakeAddress(name, abstract, &addr, &addrlen); - SharedFD rval = SharedFD::Socket(PF_UNIX, in_type, 0); - if (!rval->IsOpen()) { - return rval; - } - - int n = 1; - if (rval->SetSockOpt(SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) { - LOG(ERROR) << "SetSockOpt failed " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - if (rval->Bind(reinterpret_cast<sockaddr*>(&addr), addrlen) == -1) { - LOG(ERROR) << "Bind failed; name=" << name << ": " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - - /* Only the bottom bits are really the socket type; there are flags too. */ - constexpr int SOCK_TYPE_MASK = 0xf; - - // Connection oriented sockets: start listening. - if ((in_type & SOCK_TYPE_MASK) == SOCK_STREAM) { - // Follows the default from socket_local_server - if (rval->Listen(1) == -1) { - LOG(ERROR) << "Listen failed: " << rval->StrError(); - return SharedFD::ErrorFD(rval->GetErrno()); - } - } - - if (!abstract) { - if (TEMP_FAILURE_RETRY(chmod(name, mode)) == -1) { - LOG(ERROR) << "chmod failed: " << strerror(errno); - // However, continue since we do have a listening socket - } - } - return rval; -} - -SharedFD SharedFD::VsockServer(unsigned int port, int type) { - auto vsock = cvd::SharedFD::Socket(AF_VSOCK, type, 0); - if (!vsock->IsOpen()) { - return vsock; - } - sockaddr_vm addr{}; - addr.svm_family = AF_VSOCK; - addr.svm_port = port; - addr.svm_cid = VMADDR_CID_ANY; - auto casted_addr = reinterpret_cast<sockaddr*>(&addr); - if (vsock->Bind(casted_addr, sizeof(addr)) == -1) { - LOG(ERROR) << "Bind failed (" << vsock->StrError() << ")"; - return SharedFD::ErrorFD(vsock->GetErrno()); - } - if (type == SOCK_STREAM) { - if (vsock->Listen(4) < 0) { - LOG(ERROR) << "Listen failed (" << vsock->StrError() << ")"; - return SharedFD::ErrorFD(vsock->GetErrno()); - } - } - return vsock; -} - -SharedFD SharedFD::VsockServer(int type) { - return VsockServer(VMADDR_PORT_ANY, type); -} - -SharedFD SharedFD::VsockClient(unsigned int cid, unsigned int port, int type) { - auto vsock = cvd::SharedFD::Socket(AF_VSOCK, type, 0); - if (!vsock->IsOpen()) { - return vsock; - } - sockaddr_vm addr{}; - addr.svm_family = AF_VSOCK; - addr.svm_port = port; - addr.svm_cid = cid; - auto casted_addr = reinterpret_cast<sockaddr*>(&addr); - if (vsock->Connect(casted_addr, sizeof(addr)) == -1) { - return SharedFD::ErrorFD(vsock->GetErrno()); - } - return vsock; -} - -} // namespace cvd diff --git a/common/libs/fs/shared_fd.h b/common/libs/fs/shared_fd.h deleted file mode 100644 index eec17b1c..00000000 --- a/common/libs/fs/shared_fd.h +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -// TODO: We can't use std::shared_ptr on the older guests due to HALs. - -#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_ -#define CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_ - -#include <sys/epoll.h> -#include <sys/eventfd.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/select.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/timerfd.h> -#include <sys/uio.h> -#include <sys/un.h> - -#include <memory> -#include <sstream> - -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> - -#include "vm_sockets.h" - -/** - * Classes to to enable safe access to files. - * POSIX kernels have an unfortunate habit of recycling file descriptors. - * That can cause problems like http://b/26121457 in code that doesn't manage - * file lifetimes properly. These classes implement an alternate interface - * that has some advantages: - * - * o References to files are tightly controlled - * o Files are auto-closed if they go out of scope - * o Files are life-time aware. It is impossible to close the instance twice. - * o File descriptors are always initialized. By default the descriptor is - * set to a closed instance. - * - * These classes are designed to mimic to POSIX interface as closely as - * possible. Specifically, they don't attempt to track the type of file - * descriptors and expose only the valid operations. This is by design, since - * it makes it easier to convert existing code to SharedFDs and avoids the - * possibility that new POSIX functionality will lead to large refactorings. - */ -namespace cvd { - -class FileInstance; - -/** - * Describes the fields in msghdr that are honored by the *MsgAndFDs - * calls. - */ -struct InbandMessageHeader { - void* msg_name; - socklen_t msg_namelen; - struct iovec* msg_iov; - size_t msg_iovlen; - int msg_flags; - - void Convert(struct msghdr* dest) const { - dest->msg_name = msg_name; - dest->msg_namelen = msg_namelen; - dest->msg_iov = msg_iov; - dest->msg_iovlen = msg_iovlen; - dest->msg_flags = msg_flags; - } -}; - -/** - * Counted reference to a FileInstance. - * - * This is also the place where most new FileInstances are created. The creation - * mehtods correspond to the underlying POSIX calls. - * - * SharedFDs can be compared and stored in STL containers. The semantics are - * slightly different from POSIX file descriptors: - * - * o The value of the SharedFD is the identity of its underlying FileInstance. - * - * o Each newly created SharedFD has a unique, closed FileInstance: - * SharedFD a, b; - * assert (a != b); - * a = b; - * asssert(a == b); - * - * o The identity of the FileInstance is not affected by closing the file: - * SharedFD a, b; - * set<SharedFD> s; - * s.insert(a); - * assert(s.count(a) == 1); - * assert(s.count(b) == 0); - * a->Close(); - * assert(s.count(a) == 1); - * assert(s.count(b) == 0); - * - * o FileInstances are never visibly recycled. - * - * o If all of the SharedFDs referring to a FileInstance go out of scope the - * file is closed and the FileInstance is recycled. - * - * Creation methods must ensure that no references to the new file descriptor - * escape. The underlying FileInstance should have the only reference to the - * file descriptor. Any method that needs to know the fd must be in either - * SharedFD or FileInstance. - * - * SharedFDs always have an underlying FileInstance, so all of the method - * calls are safe in accordance with the null object pattern. - * - * Errors on system calls that create new FileInstances, such as Open, are - * reported with a new, closed FileInstance with the errno set. - */ -class SharedFD { - public: - inline SharedFD(); - SharedFD(const std::shared_ptr<FileInstance>& in) : value_(in) {} - // Reference the listener as a FileInstance to make this FD type agnostic. - static SharedFD Accept(const FileInstance& listener, struct sockaddr* addr, - socklen_t* addrlen); - static SharedFD Accept(const FileInstance& listener); - static SharedFD Dup(int unmanaged_fd); - static SharedFD GetControlSocket(const char* name); - // All SharedFDs have the O_CLOEXEC flag after creation. To remove use the - // Fcntl or Dup functions. - static SharedFD Open(const char* pathname, int flags, mode_t mode = 0); - static SharedFD Creat(const char* pathname, mode_t mode); - static bool Pipe(SharedFD* fd0, SharedFD* fd1); - static SharedFD Event(int initval = 0, int flags = 0); - static SharedFD Epoll(int flags = 0); - static bool SocketPair(int domain, int type, int protocol, SharedFD* fd0, - SharedFD* fd1); - static SharedFD Socket(int domain, int socket_type, int protocol); - static SharedFD SocketLocalClient(const char* name, bool is_abstract, - int in_type); - static SharedFD SocketLocalClient(int port, int type); - static SharedFD SocketLocalServer(const char* name, bool is_abstract, - int in_type, mode_t mode); - static SharedFD SocketLocalServer(int port, int type); - static SharedFD SocketSeqPacketServer(const char* name, mode_t mode); - static SharedFD SocketSeqPacketClient(const char* name); - static SharedFD VsockServer(unsigned int port, int type); - static SharedFD VsockServer(int type); - static SharedFD VsockClient(unsigned int cid, unsigned int port, int type); - static SharedFD TimerFD(int clock, int flags); - - bool operator==(const SharedFD& rhs) const { return value_ == rhs.value_; } - - bool operator!=(const SharedFD& rhs) const { return value_ != rhs.value_; } - - bool operator<(const SharedFD& rhs) const { return value_ < rhs.value_; } - - bool operator<=(const SharedFD& rhs) const { return value_ <= rhs.value_; } - - bool operator>(const SharedFD& rhs) const { return value_ > rhs.value_; } - - bool operator>=(const SharedFD& rhs) const { return value_ >= rhs.value_; } - - std::shared_ptr<FileInstance> operator->() const { return value_; } - - const cvd::FileInstance& operator*() const { return *value_; } - - cvd::FileInstance& operator*() { return *value_; } - - private: - static SharedFD ErrorFD(int error); - - std::shared_ptr<FileInstance> value_; -}; - -/** - * Tracks the lifetime of a file descriptor and provides methods to allow - * callers to use the file without knowledge of the underlying descriptor - * number. - * - * FileInstances have two states: Open and Closed. They may start in either - * state. However, once a FileIntance enters the Closed state it cannot be - * reopened. - * - * Construction of FileInstances is limited to select classes to avoid - * escaping file descriptors. At this point SharedFD is the only class - * that has access. We may eventually have ScopedFD and WeakFD. - */ -class FileInstance { - // Give SharedFD access to the aliasing constructor. - friend class SharedFD; - - public: - virtual ~FileInstance() { Close(); } - - // This can't be a singleton because our shared_ptr's aren't thread safe. - static std::shared_ptr<FileInstance> ClosedInstance() { - return std::shared_ptr<FileInstance>(new FileInstance(-1, EBADF)); - } - - int Bind(const struct sockaddr* addr, socklen_t addrlen) { - errno = 0; - int rval = bind(fd_, addr, addrlen); - errno_ = errno; - return rval; - } - - int Connect(const struct sockaddr* addr, socklen_t addrlen) { - errno = 0; - int rval = connect(fd_, addr, addrlen); - errno_ = errno; - return rval; - } - - void Close(); - - // Returns true if the entire input was copied. - // Otherwise an error will be set either on this file or the input. - // The non-const reference is needed to avoid binding this to a particular - // reference type. - bool CopyFrom(FileInstance& in); - bool CopyFrom(FileInstance& in, size_t length); - - int UNMANAGED_Dup() { - errno = 0; - int rval = TEMP_FAILURE_RETRY(dup(fd_)); - errno_ = errno; - return rval; - } - - int UNMANAGED_Dup2(int newfd) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(dup2(fd_, newfd)); - errno_ = errno; - return rval; - } - - int EpollCtl(int op, cvd::SharedFD new_fd, struct epoll_event* event) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(epoll_ctl(fd_, op, new_fd->fd_, event)); - errno_ = errno; - return rval; - } - - int EpollWait(struct epoll_event* events, int maxevents, int timeout) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(epoll_wait(fd_, events, maxevents, timeout)); - errno_ = errno; - return rval; - } - - int Fchown(uid_t owner, gid_t group) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(fchown(fd_, owner, group)); - errno_ = errno; - return rval; - } - - int Fcntl(int command, int value) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(fcntl(fd_, command, value)); - errno_ = errno; - return rval; - } - - int Fstat(struct stat* buf) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(fstat(fd_, buf)); - errno_ = errno; - return rval; - } - - int GetErrno() const { return errno_; } - - int GetSockOpt(int level, int optname, void* optval, socklen_t* optlen) { - errno = 0; - int rval = getsockopt(fd_, level, optname, optval, optlen); - if (rval == -1) { - errno_ = errno; - } - return rval; - } - - int GetSockName(struct sockaddr* addr, socklen_t* addrlen) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(getsockname(fd_, addr, addrlen)); - if (rval == -1) { - errno_ = errno; - } - return rval; - } - - unsigned int VsockServerPort() { - struct sockaddr_vm vm_socket; - socklen_t length = sizeof(vm_socket); - GetSockName(reinterpret_cast<struct sockaddr*>(&vm_socket), &length); - return vm_socket.svm_port; - } - - void Identify(const char* identity); - - int Ioctl(int request, void* val = nullptr) { - errno = 0; - int rval = TEMP_FAILURE_RETRY(ioctl(fd_, request, val)); - errno_ = errno; - return rval; - } - - bool IsOpen() const { return fd_ != -1; } - - // in probably isn't modified, but the API spec doesn't have const. - bool IsSet(fd_set* in) const; - - int Listen(int backlog) { - errno = 0; - int rval = listen(fd_, backlog); - errno_ = errno; - return rval; - } - - static void Log(const char* message); - - off_t LSeek(off_t offset, int whence) { - errno = 0; - off_t rval = TEMP_FAILURE_RETRY(lseek(fd_, offset, whence)); - errno_ = errno; - return rval; - } - - void* Mmap(void* addr, size_t length, int prot, int flags, off_t offset) { - errno = 0; - void* rval = mmap(addr, length, prot, flags, fd_, offset); - errno_ = errno; - return rval; - } - - ssize_t Pread(void* buf, size_t count, off_t offset) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(pread(fd_, buf, count, offset)); - errno_ = errno; - return rval; - } - - ssize_t Recv(void* buf, size_t len, int flags) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(recv(fd_, buf, len, flags)); - errno_ = errno; - return rval; - } - - ssize_t RecvFrom(void* buf, size_t len, int flags, struct sockaddr* src_addr, - socklen_t* addr_len) { - errno = 0; - ssize_t rval = - TEMP_FAILURE_RETRY(recvfrom(fd_, buf, len, flags, src_addr, addr_len)); - errno_ = errno; - return rval; - } - - ssize_t RecvMsg(struct msghdr* msg, int flags) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(recvmsg(fd_, msg, flags)); - errno_ = errno; - return rval; - } - - template <size_t SZ> - ssize_t RecvMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags, - SharedFD (*new_fds)[SZ]) { - // We need to make some modifications to land the fds. Make it clear - // that there are no updates to the msg being passed in during this call. - struct msghdr msg; - msg_in.Convert(&msg); - union { - char buffer[CMSG_SPACE(SZ * sizeof(int))]; - struct cmsghdr this_aligns_buffer; - } u; - msg.msg_control = u.buffer; - msg.msg_controllen = sizeof(u.buffer); - - cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg)); - for (size_t i = 0; i < SZ; ++i) { - fd_array[i] = -1; - } - ssize_t rval = RecvMsg(&msg, flags); - for (size_t i = 0; i < SZ; ++i) { - (*new_fds)[i] = - std::shared_ptr<FileInstance>(new FileInstance(fd_array[i], errno)); - } - return rval; - } - - ssize_t Read(void* buf, size_t count) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(read(fd_, buf, count)); - errno_ = errno; - return rval; - } - - ssize_t Send(const void* buf, size_t len, int flags) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(send(fd_, buf, len, flags)); - errno_ = errno; - return rval; - } - - ssize_t SendMsg(const struct msghdr* msg, int flags) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(sendmsg(fd_, msg, flags)); - errno_ = errno; - return rval; - } - - template <size_t SZ> - ssize_t SendMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags, - const SharedFD (&fds)[SZ]) { - struct msghdr msg; - msg_in.Convert(&msg); - union { - char buffer[CMSG_SPACE(SZ * sizeof(int))]; - struct cmsghdr this_aligns_buffer; - } u; - msg.msg_control = u.buffer; - msg.msg_controllen = sizeof(u.buffer); - - cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg)); - for (size_t i = 0; i < SZ; ++i) { - fd_array[i] = fds[i]->fd_; - } - return SendMsg(&msg, flags); - } - - int Shutdown(int how) { - errno = 0; - int rval = shutdown(fd_, how); - errno_ = errno; - return rval; - } - - ssize_t SendTo(const void* buf, size_t len, int flags, - const struct sockaddr* dest_addr, socklen_t addrlen) { - errno = 0; - ssize_t rval = - TEMP_FAILURE_RETRY(sendto(fd_, buf, len, flags, dest_addr, addrlen)); - errno_ = errno; - return rval; - } - - void Set(fd_set* dest, int* max_index) const; - - int SetSockOpt(int level, int optname, const void* optval, socklen_t optlen) { - errno = 0; - int rval = setsockopt(fd_, level, optname, optval, optlen); - errno_ = errno; - return rval; - } - - const char* StrError() const { - errno = 0; - FileInstance* s = const_cast<FileInstance*>(this); - char* out = strerror_r(errno_, s->strerror_buf_, sizeof(strerror_buf_)); - - // From man page: - // strerror_r() returns a pointer to a string containing the error message. - // This may be either a pointer to a string that the function stores in - // buf, or a pointer to some (immutable) static string (in which case buf - // is unused). - if (out != s->strerror_buf_) { - strncpy(s->strerror_buf_, out, sizeof(strerror_buf_)); - } - return strerror_buf_; - } - - int TimerGet(struct itimerspec* curr_value) { - errno = 0; - int rval = timerfd_gettime(fd_, curr_value); - errno_ = errno; - return rval; - } - - int TimerSet(int flags, const struct itimerspec* new_value, - struct itimerspec* old_value) { - errno = 0; - int rval = timerfd_settime(fd_, flags, new_value, old_value); - errno_ = errno; - return rval; - } - - ssize_t Truncate(off_t length) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(ftruncate(fd_, length)); - errno_ = errno; - return rval; - } - - ssize_t Write(const void* buf, size_t count) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(write(fd_, buf, count)); - errno_ = errno; - return rval; - } - - ssize_t WriteV(struct iovec* iov, int iovcount) { - errno = 0; - ssize_t rval = TEMP_FAILURE_RETRY(writev(fd_, iov, iovcount)); - errno_ = errno; - return rval; - } - - private: - FileInstance(int fd, int in_errno) : fd_(fd), errno_(in_errno) { - // Ensure every file descriptor managed by a FileInstance has the CLOEXEC - // flag - TEMP_FAILURE_RETRY(fcntl(fd, F_SETFD, FD_CLOEXEC)); - std::stringstream identity; - identity << "fd=" << fd << " @" << this; - identity_ = identity.str(); - } - - FileInstance* Accept(struct sockaddr* addr, socklen_t* addrlen) const { - int fd = TEMP_FAILURE_RETRY(accept(fd_, addr, addrlen)); - if (fd == -1) { - return new FileInstance(fd, errno); - } else { - return new FileInstance(fd, 0); - } - } - - int fd_; - int errno_; - std::string identity_; - char strerror_buf_[160]; -}; - -/* Methods that need both a fully defined SharedFD and a fully defined - FileInstance. */ - -inline SharedFD::SharedFD() : value_(FileInstance::ClosedInstance()) {} - -} // namespace cvd - -#endif // CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_ diff --git a/common/libs/fs/shared_fd_test.cpp b/common/libs/fs/shared_fd_test.cpp deleted file mode 100644 index 34236195..00000000 --- a/common/libs/fs/shared_fd_test.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" - -#include <stdlib.h> -#include <unistd.h> -#include <gtest/gtest.h> - -#include <string> - -using cvd::InbandMessageHeader; -using cvd::SharedFD; - -char hello[] = "Hello, world!"; -char pipe_message[] = "Testing the pipe"; - -TEST(SendFD, Basic) { - char dirname[] = "/tmp/sfdtestXXXXXX"; - char* socket = mkdtemp(dirname); - EXPECT_TRUE(socket != NULL); - std::string path(dirname); - path += "/s"; - SharedFD server = SharedFD::SocketSeqPacketServer(path.c_str(), 0700); - EXPECT_TRUE(server->IsOpen()); - int rval = fork(); - EXPECT_NE(-1, rval); - if (!rval) { - struct iovec iov { hello, sizeof(hello) }; - SharedFD client = SharedFD::SocketSeqPacketClient(path.c_str()); - InbandMessageHeader hdr{}; - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - SharedFD fds[2]; - SharedFD::Pipe(fds, fds + 1); - ssize_t rval = client->SendMsgAndFDs(hdr, 0, fds); - printf("SendMsg sent %zd (%s)\n", rval, client->StrError()); - exit(0); - } - server->Listen(2); - SharedFD peer = SharedFD::Accept(*server); - EXPECT_TRUE(peer->IsOpen()); - char buf[80]; - struct iovec iov { buf, sizeof(buf) }; - InbandMessageHeader hdr{}; - hdr.msg_iov = &iov; - hdr.msg_iovlen = 1; - SharedFD fds[2]; - peer->RecvMsgAndFDs(hdr, 0, &fds); - EXPECT_EQ(0, strcmp(buf, hello)); - EXPECT_TRUE(fds[0]->IsOpen()); - EXPECT_TRUE(fds[1]->IsOpen()); - EXPECT_EQ(sizeof(pipe_message), fds[1]->Write(pipe_message, sizeof(pipe_message))); - EXPECT_EQ(sizeof(pipe_message), fds[0]->Read(buf, sizeof(buf))); - EXPECT_EQ(0, strcmp(buf, pipe_message)); -} diff --git a/common/libs/fs/shared_select.h b/common/libs/fs/shared_select.h deleted file mode 100644 index d103f1db..00000000 --- a/common/libs/fs/shared_select.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ -#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_SELECT_H_ -#define CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_SELECT_H_ - -#include <set> - -#include "common/libs/fs/shared_fd.h" - -namespace cvd { -/** - * The SharedFD version of fdset for the Select call. - * - * There are two types of methods. STL inspired methods and types use - * all_lowercase_underscore notation. - * - * Methods that are inspired by POSIX Use UpperCamelCase. - * - * Assume that any mutation invalidates all iterators. - */ -class SharedFDSet { - public: - // These methods and types have more to do with the STL than POSIX, - // so I'm using STL-compatible notation. - typedef std::set<SharedFD>::iterator iterator; - typedef std::set<SharedFD>::const_iterator const_iterator; - - iterator begin() { return value_.begin(); } - iterator end() { return value_.end(); } - const_iterator begin() const { return value_.begin(); } - const_iterator end() const { return value_.end(); } - - void swap(SharedFDSet* rhs) { - value_.swap(rhs->value_); - } - - void Clr(const SharedFD& in) { - value_.erase(in); - } - - bool IsSet(const SharedFD& in) const { - return value_.count(in) != 0; - } - - void Set(const SharedFD& in) { - value_.insert(in); - } - - void Zero() { - value_.clear(); - } - - private: - std::set<SharedFD> value_; -}; - -/** - * SharedFD version of select. - * - * read_set, write_set, and timeout are in/out parameters. This caller should keep - * a copy of the original values if it wants to preserve them. - */ -int Select(SharedFDSet* read_set, SharedFDSet* write_set, - SharedFDSet* error_set, struct timeval* timeout); - -} // namespace cvd - -#endif // CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_SELECT_H_ diff --git a/common/libs/fs/vm_sockets.h b/common/libs/fs/vm_sockets.h deleted file mode 100644 index 151f6769..00000000 --- a/common/libs/fs/vm_sockets.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** - **************************************************************************** - *** - *** This header was automatically generated from a Linux kernel header - *** of the same name, to make information necessary for userspace to - *** call into the kernel available to libc. It contains only constants, - *** structures, and macros generated from the original header, and thus, - *** contains no copyrightable information. - *** - *** Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h - *** - **************************************************************************** - ****************************************************************************/ -#ifndef _UAPI_VM_SOCKETS_H -#define _UAPI_VM_SOCKETS_H -#include <linux/socket.h> -#define SO_VM_SOCKETS_BUFFER_SIZE 0 -#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1 -#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2 -#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3 -#define SO_VM_SOCKETS_TRUSTED 5 -#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6 -#define SO_VM_SOCKETS_NONBLOCK_TXRX 7 -#define VMADDR_CID_ANY - 1U -#define VMADDR_PORT_ANY - 1U -#define VMADDR_CID_HYPERVISOR 0 -#define VMADDR_CID_RESERVED 1 -#define VMADDR_CID_HOST 2 -#define VM_SOCKETS_INVALID_VERSION - 1U -#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v) & 0xFF000000) >> 24) -#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v) & 0x00FF0000) >> 16) -#define VM_SOCKETS_VERSION_MINOR(_v) (((_v) & 0x0000FFFF)) -struct sockaddr_vm { - __kernel_sa_family_t svm_family; - unsigned short svm_reserved1; - unsigned int svm_port; - unsigned int svm_cid; - unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) - sizeof(unsigned int) - sizeof(unsigned int)]; -}; -#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9) -#ifndef AF_VSOCK -#define AF_VSOCK 40 -#endif -#endif diff --git a/common/libs/glog/logging.h b/common/libs/glog/logging.h deleted file mode 100644 index 8cd4a8a7..00000000 --- a/common/libs/glog/logging.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 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. - */ - -#ifdef ANDROID -#include <android-base/logging.h> - -#if defined(CUTTLEFISH_HOST) -using ::android::base::VERBOSE; -using ::android::base::INFO; -using ::android::base::WARNING; -using ::android::base::FATAL; - -#define LOG_IF(LEVEL, CONDITION) if (CONDITION) LOG(LEVEL) - -#endif // CUTTLEFISH_HOST -#else // DEBIAN_HOST (by elimination) -#include <glog/logging.h> -#endif diff --git a/common/libs/net/Android.bp b/common/libs/net/Android.bp deleted file mode 100644 index ba7bbd39..00000000 --- a/common/libs/net/Android.bp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2017 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. - -cc_library_shared { - name: "cuttlefish_net", - srcs: [ - "netlink_client.cpp", - "netlink_request.cpp", - "network_interface_manager.cpp", - ], - shared_libs: [ - "libcuttlefish_fs", - "libbase", - ], - defaults: ["cuttlefish_host_and_guest"], -} - -cc_test_host { - name: "cuttlefish_net_tests", - srcs: [ - "netlink_request_test.cpp", - ], - header_libs: ["cuttlefish_glog"], - shared_libs: [ - "libcuttlefish_fs", - "cuttlefish_net", - "libbase", - ], - static_libs: [ - "libgmock", - "libgtest_host", - ], - defaults: ["cuttlefish_host_only"], - test_suites: ["general-tests"], -} diff --git a/common/libs/net/TEST_MAPPING b/common/libs/net/TEST_MAPPING deleted file mode 100644 index a06d72a0..00000000 --- a/common/libs/net/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presubmit": [ - { - "name": "cuttlefish_net_tests", - "host": true - } - ] -} diff --git a/common/libs/net/netlink_client.cpp b/common/libs/net/netlink_client.cpp deleted file mode 100644 index 96eb4a95..00000000 --- a/common/libs/net/netlink_client.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/net/netlink_client.h" - -#include <errno.h> -#include <linux/rtnetlink.h> -#include <linux/sockios.h> -#include <net/if.h> -#include <sys/socket.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/glog/logging.h" - -namespace cvd { -namespace { -// NetlinkClient implementation. -// Talks to libnetlink to apply network changes. -class NetlinkClientImpl : public NetlinkClient { - public: - NetlinkClientImpl() = default; - virtual ~NetlinkClientImpl() = default; - - virtual bool Send(const NetlinkRequest& message); - - // Initialize NetlinkClient instance. - // Open netlink channel and initialize interface list. - // Parameter |type| specifies which netlink target to address, eg. - // NETLINK_ROUTE. - // Returns true, if initialization was successful. - bool OpenNetlink(int type); - - private: - bool CheckResponse(uint32_t seq_no); - - SharedFD netlink_fd_; - sockaddr_nl address_; -}; - -bool NetlinkClientImpl::CheckResponse(uint32_t seq_no) { - uint32_t len; - char buf[4096]; - struct iovec iov = { buf, sizeof(buf) }; - struct sockaddr_nl sa; - struct msghdr msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; - struct nlmsghdr *nh; - - int result = netlink_fd_->RecvMsg(&msg, 0); - if (result < 0) { - LOG(ERROR) << "Netlink error: " << strerror(errno); - return false; - } - - len = static_cast<uint32_t>(result); - LOG(INFO) << "Received netlink response (" << len << " bytes)"; - - for (nh = reinterpret_cast<nlmsghdr*>(buf); - NLMSG_OK(nh, len); - nh = NLMSG_NEXT(nh, len)) { - if (nh->nlmsg_seq != seq_no) { - // This really shouldn't happen. If we see this, it means somebody is - // issuing netlink requests using the same socket as us, and ignoring - // responses. - LOG(WARNING) << "Sequence number mismatch: " - << nh->nlmsg_seq << " != " << seq_no; - continue; - } - - // This is the end of multi-part message. - // It indicates there's nothing more netlink wants to tell us. - // It also means we failed to find the response to our request. - if (nh->nlmsg_type == NLMSG_DONE) - break; - - // This is the 'nlmsgerr' package carrying response to our request. - // It carries an 'error' value (errno) along with the netlink header info - // that caused this error. - if (nh->nlmsg_type == NLMSG_ERROR) { - nlmsgerr* err = reinterpret_cast<nlmsgerr*>(nh + 1); - if (err->error < 0) { - LOG(ERROR) << "Failed to complete netlink request: " - << "Netlink error: " << err->error - << ", errno: " << strerror(errno); - return false; - } - return true; - } - } - - LOG(ERROR) << "No response from netlink."; - return false; -} - -bool NetlinkClientImpl::Send(const NetlinkRequest& message) { - struct sockaddr_nl netlink_addr; - struct iovec netlink_iov = { - message.RequestData(), - message.RequestLength() - }; - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - memset(&netlink_addr, 0, sizeof(netlink_addr)); - - msg.msg_name = &address_; - msg.msg_namelen = sizeof(address_); - msg.msg_iov = &netlink_iov; - msg.msg_iovlen = sizeof(netlink_iov) / sizeof(iovec); - - if (netlink_fd_->SendMsg(&msg, 0) < 0) { - LOG(ERROR) << "Failed to send netlink message: " - << strerror(errno); - - return false; - } - - return CheckResponse(message.SeqNo()); -} - -bool NetlinkClientImpl::OpenNetlink(int type) { - netlink_fd_ = SharedFD::Socket(AF_NETLINK, SOCK_RAW, type); - if (!netlink_fd_->IsOpen()) return false; - - address_.nl_family = AF_NETLINK; - address_.nl_groups = 0; - - netlink_fd_->Bind(reinterpret_cast<sockaddr*>(&address_), sizeof(address_)); - - return true; -} - -class NetlinkClientFactoryImpl : public NetlinkClientFactory { - public: - NetlinkClientFactoryImpl() = default; - ~NetlinkClientFactoryImpl() override = default; - - std::unique_ptr<NetlinkClient> New(int type) override { - auto client_raw = new NetlinkClientImpl(); - // Use RVO when possible. - std::unique_ptr<NetlinkClient> client(client_raw); - - if (!client_raw->OpenNetlink(type)) { - // Note: deletes client_raw. - client.reset(); - } - return client; - } -}; - -} // namespace - -NetlinkClientFactory* NetlinkClientFactory::Default() { - static NetlinkClientFactory &factory = *new NetlinkClientFactoryImpl(); - return &factory; -} - -} // namespace cvd diff --git a/common/libs/net/netlink_client.h b/common/libs/net/netlink_client.h deleted file mode 100644 index c8805c5b..00000000 --- a/common/libs/net/netlink_client.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef COMMON_LIBS_NET_NETLINK_CLIENT_H_ -#define COMMON_LIBS_NET_NETLINK_CLIENT_H_ - -#include <stddef.h> -#include <memory> -#include <string> -#include "common/libs/net/netlink_request.h" - -namespace cvd { - -// Abstraction of Netlink client class. -class NetlinkClient { - public: - NetlinkClient() {} - virtual ~NetlinkClient() {} - - // Send netlink message to kernel. - virtual bool Send(const NetlinkRequest& message) = 0; - - private: - NetlinkClient(const NetlinkClient&); - NetlinkClient& operator= (const NetlinkClient&); -}; - -class NetlinkClientFactory { - public: - // Create new NetlinkClient instance of a specified type. - // type can be any of the NETLINK_* types (eg. NETLINK_ROUTE). - virtual std::unique_ptr<NetlinkClient> New(int type) = 0; - - static NetlinkClientFactory* Default(); - - protected: - NetlinkClientFactory() = default; - virtual ~NetlinkClientFactory() = default; -}; - -} // namespace cvd - -#endif // COMMON_LIBS_NET_NETLINK_CLIENT_H_ diff --git a/common/libs/net/netlink_request.cpp b/common/libs/net/netlink_request.cpp deleted file mode 100644 index 501b2c35..00000000 --- a/common/libs/net/netlink_request.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/net/netlink_request.h" - -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <net/if.h> -#include <string.h> - -#include <algorithm> -#include <string> -#include <vector> - -#include "common/libs/glog/logging.h" - -namespace cvd { -namespace { -uint32_t kRequestSequenceNumber = 0; -} // namespace - -uint32_t NetlinkRequest::SeqNo() const { - return header_->nlmsg_seq; -} - -void* NetlinkRequest::AppendRaw(const void* data, size_t length) { - auto* output = static_cast<char*>(ReserveRaw(length)); - const auto* input = static_cast<const char*>(data); - std::copy(input, input + length, output); - return output; -} - -void* NetlinkRequest::ReserveRaw(size_t length) { - size_t original_size = request_.size(); - request_.resize(original_size + RTA_ALIGN(length), '\0'); - return reinterpret_cast<void*>(request_.data() + original_size); -} - -nlattr* NetlinkRequest::AppendTag( - uint16_t type, const void* data, uint16_t data_length) { - nlattr* attr = Reserve<nlattr>(); - attr->nla_type = type; - attr->nla_len = RTA_LENGTH(data_length); - AppendRaw(data, data_length); - return attr; -} - -NetlinkRequest::NetlinkRequest(int32_t command, int32_t flags) { - request_.reserve(512); - header_ = Reserve<nlmsghdr>(); - flags |= NLM_F_ACK | NLM_F_REQUEST; - header_->nlmsg_flags = flags; - header_->nlmsg_type = command; - header_->nlmsg_pid = getpid(); - header_->nlmsg_seq = kRequestSequenceNumber++; -} - -NetlinkRequest::NetlinkRequest(NetlinkRequest&& other) { - using std::swap; - swap(lists_, other.lists_); - swap(header_, other.header_); - swap(request_, other.request_); -} - -void NetlinkRequest::AddString(uint16_t type, const std::string& value) { - AppendTag(type, value.c_str(), value.length() + 1); -} - -void NetlinkRequest::AddIfInfo(int32_t if_index, bool operational) { - ifinfomsg* if_info = Reserve<ifinfomsg>(); - if_info->ifi_family = AF_UNSPEC; - if_info->ifi_index = if_index; - if_info->ifi_flags = operational ? IFF_UP : 0; - if_info->ifi_change = IFF_UP; -} - -void NetlinkRequest::AddAddrInfo(int32_t if_index, int prefix_len) { - ifaddrmsg* ad_info = Reserve<ifaddrmsg>(); - ad_info->ifa_family = AF_INET; - ad_info->ifa_prefixlen = prefix_len; - ad_info->ifa_flags = IFA_F_PERMANENT | IFA_F_SECONDARY; - ad_info->ifa_scope = 0; - ad_info->ifa_index = if_index; -} - -void NetlinkRequest::PushList(uint16_t type) { - int length = request_.size(); - nlattr* list = AppendTag(type, NULL, 0); - lists_.push_back(std::make_pair(list, length)); -} - -void NetlinkRequest::PopList() { - if (lists_.empty()) { - LOG(ERROR) << "List pop with no lists left on stack."; - return; - } - - std::pair<nlattr*, int> list = lists_.back(); - lists_.pop_back(); - list.first->nla_len = request_.size() - list.second; -} - -void* NetlinkRequest::RequestData() const { - // Update request length before reporting raw data. - header_->nlmsg_len = request_.size(); - return header_; -} - -size_t NetlinkRequest::RequestLength() const { - return request_.size(); -} - -} // namespace cvd diff --git a/common/libs/net/netlink_request.h b/common/libs/net/netlink_request.h deleted file mode 100644 index 5e5b3557..00000000 --- a/common/libs/net/netlink_request.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef COMMON_LIBS_NET_NETLINK_REQUEST_H_ -#define COMMON_LIBS_NET_NETLINK_REQUEST_H_ - -#include <linux/netlink.h> -#include <stddef.h> - -#include <memory> -#include <string> -#include <vector> - -namespace cvd { -// Abstraction of Network link request. -// Used to supply kernel with information about which interface needs to be -// changed, and how. -class NetlinkRequest { - public: - // Create new Netlink Request structure. - // Parameter |type| specifies netlink request type (eg. RTM_NEWLINK), while - // |flags| are netlink and request specific flags (eg. NLM_F_DUMP). - NetlinkRequest(int type, int flags); - NetlinkRequest(NetlinkRequest&& other); - - ~NetlinkRequest() = default; - - // Add an IFLA tag followed by a string. - // Returns true, if successful. - void AddString(uint16_t type, const std::string& value); - - // Add an IFLA tag followed by an integer. - template <typename T> - void AddInt(uint16_t type, T value) { - static_assert(std::is_integral<T>::value, - "AddInt must be used on integer types."); - AppendTag(type, &value, sizeof(value)); - } - - // Add an interface info structure. - // Parameter |if_index| specifies particular interface index to which the - // attributes following the IfInfo apply. - void AddIfInfo(int32_t if_index, bool is_operational); - - // Add an address info to a specific interface. - void AddAddrInfo(int32_t if_index, int prefix_len = 24); - - // Creates new list. - // List mimmic recursive structures in a flat, contiuous representation. - // Each call to PushList() should have a corresponding call to PopList - // indicating end of sub-attribute list. - void PushList(uint16_t type); - - // Indicates end of previously declared list. - void PopList(); - - // Request data. - void* RequestData() const; - - // Request length. - size_t RequestLength() const; - - // Request Sequence Number. - uint32_t SeqNo() const; - - // Append raw data to buffer. - // data must not be null. - // Returns pointer to copied location. - void* AppendRaw(const void* data, size_t length); - - // Reserve |length| number of bytes in the buffer. - // Returns pointer to reserved location. - void* ReserveRaw(size_t length); - - // Append specialized data. - template <typename T> T* Append(const T& data) { - return static_cast<T*>(AppendRaw(&data, sizeof(T))); - } - - // Reserve specialized data. - template <typename T> T* Reserve() { - return static_cast<T*>(ReserveRaw(sizeof(T))); - } - - private: - nlattr* AppendTag(uint16_t type, const void* data, uint16_t length); - - std::vector<std::pair<nlattr*, int32_t>> lists_; - std::vector<char> request_; - nlmsghdr* header_; - - NetlinkRequest(const NetlinkRequest&) = delete; - NetlinkRequest& operator= (const NetlinkRequest&) = delete; -}; -} // namespace cvd -#endif // COMMON_LIBS_NET_NETLINK_REQUEST_H_ diff --git a/common/libs/net/netlink_request_test.cpp b/common/libs/net/netlink_request_test.cpp deleted file mode 100644 index 03a7dadc..00000000 --- a/common/libs/net/netlink_request_test.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/net/netlink_client.h" - -#include <linux/rtnetlink.h> - -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <glog/logging.h> - -#include <iostream> -#include <memory> - -using ::testing::ElementsAreArray; -using ::testing::MatchResultListener; -using ::testing::Return; - -namespace cvd { -namespace { -extern "C" void klog_write(int /* level */, const char* /* format */, ...) {} - -// Dump hex buffer to test log. -void Dump(MatchResultListener* result_listener, const char* title, - const uint8_t* data, size_t length) { - for (size_t item = 0; item < length;) { - *result_listener << title; - do { - result_listener->stream()->width(2); - result_listener->stream()->fill('0'); - *result_listener << std::hex << +data[item] << " "; - ++item; - } while (item & 0xf); - *result_listener << "\n"; - } -} - -// Compare two memory areas byte by byte, print information about first -// difference. Dumps both bufferst to user log. -bool Compare(MatchResultListener* result_listener, - const uint8_t* exp, const uint8_t* act, size_t length) { - for (size_t index = 0; index < length; ++index) { - if (exp[index] != act[index]) { - *result_listener << "\nUnexpected data at offset " << index << "\n"; - Dump(result_listener, "Data Expected: ", exp, length); - Dump(result_listener, " Data Actual: ", act, length); - return false; - } - } - - return true; -} - -// Matcher validating Netlink Request data. -MATCHER_P2(RequestDataIs, data, length, "Matches expected request data") { - size_t offset = sizeof(nlmsghdr); - if (offset + length != arg.RequestLength()) { - *result_listener << "Unexpected request length: " - << arg.RequestLength() - offset << " vs " << length; - return false; - } - - // Note: Request begins with header (nlmsghdr). Header is not covered by this - // call. - const uint8_t* exp_data = static_cast<const uint8_t*>( - static_cast<const void*>(data)); - const uint8_t* act_data = static_cast<const uint8_t*>(arg.RequestData()); - return Compare( - result_listener, exp_data, &act_data[offset], length); -} - -MATCHER_P4(RequestHeaderIs, length, type, flags, seq, - "Matches request header") { - nlmsghdr* header = static_cast<nlmsghdr*>(arg.RequestData()); - if (arg.RequestLength() < sizeof(header)) { - *result_listener << "Malformed header: too short."; - return false; - } - - if (header->nlmsg_len != length) { - *result_listener << "Invalid message length: " - << header->nlmsg_len << " vs " << length; - return false; - } - - if (header->nlmsg_type != type) { - *result_listener << "Invalid header type: " - << header->nlmsg_type << " vs " << type; - return false; - } - - if (header->nlmsg_flags != flags) { - *result_listener << "Invalid header flags: " - << header->nlmsg_flags << " vs " << flags; - return false; - } - - if (header->nlmsg_seq != seq) { - *result_listener << "Invalid header sequence number: " - << header->nlmsg_seq << " vs " << seq; - return false; - } - - return true; -} -} // namespace - -TEST(NetlinkClientTest, BasicStringNode) { - constexpr uint16_t kDummyTag = 0xfce2; - constexpr char kLongString[] = "long string"; - - struct { - // 11 bytes of text + padding 0 + 4 bytes of header. - const uint16_t attr_length = 0x10; - const uint16_t attr_type = kDummyTag; - char text[sizeof(kLongString)]; // sizeof includes padding 0. - } expected; - - memcpy(&expected.text, kLongString, sizeof(kLongString)); - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.AddString(kDummyTag, kLongString); - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, BasicIntNode) { - // Basic { Dummy: Value } test. - constexpr uint16_t kDummyTag = 0xfce2; - constexpr int32_t kValue = 0x1badd00d; - - struct { - const uint16_t attr_length = 0x8; // 4 bytes of value + 4 bytes of header. - const uint16_t attr_type = kDummyTag; - const uint32_t attr_value = kValue; - } expected; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.AddInt(kDummyTag, kValue); - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, AllIntegerTypes) { - // Basic { Dummy: Value } test. - constexpr uint16_t kDummyTag = 0xfce2; - constexpr uint8_t kValue = 0x1b; - - // The attribute is necessary for correct binary alignment. - constexpr struct __attribute__((__packed__)) { - uint16_t attr_length_i64 = 12; - uint16_t attr_type_i64 = kDummyTag; - int64_t attr_value_i64 = kValue; - uint16_t attr_length_i32 = 8; - uint16_t attr_type_i32 = kDummyTag + 1; - int32_t attr_value_i32 = kValue; - uint16_t attr_length_i16 = 6; - uint16_t attr_type_i16 = kDummyTag + 2; - int16_t attr_value_i16 = kValue; - uint8_t attr_padding_i16[2] = {0, 0}; - uint16_t attr_length_i8 = 5; - uint16_t attr_type_i8 = kDummyTag + 3; - int8_t attr_value_i8 = kValue; - uint8_t attr_padding_i8[3] = {0, 0, 0}; - uint16_t attr_length_u64 = 12; - uint16_t attr_type_u64 = kDummyTag + 4; - uint64_t attr_value_u64 = kValue; - uint16_t attr_length_u32 = 8; - uint16_t attr_type_u32 = kDummyTag + 5; - uint32_t attr_value_u32 = kValue; - uint16_t attr_length_u16 = 6; - uint16_t attr_type_u16 = kDummyTag + 6; - uint16_t attr_value_u16 = kValue; - uint8_t attr_padding_u16[2] = {0, 0}; - uint16_t attr_length_u8 = 5; - uint16_t attr_type_u8 = kDummyTag + 7; - uint8_t attr_value_u8 = kValue; - uint8_t attr_padding_u8[3] = {0, 0, 0}; - } expected = {}; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.AddInt<int64_t>(kDummyTag, kValue); - request.AddInt<int32_t>(kDummyTag + 1, kValue); - request.AddInt<int16_t>(kDummyTag + 2, kValue); - request.AddInt<int8_t>(kDummyTag + 3, kValue); - request.AddInt<uint64_t>(kDummyTag + 4, kValue); - request.AddInt<uint32_t>(kDummyTag + 5, kValue); - request.AddInt<int16_t>(kDummyTag + 6, kValue); - request.AddInt<int8_t>(kDummyTag + 7, kValue); - - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, SingleList) { - // List: { Dummy: Value} - constexpr uint16_t kDummyTag = 0xfce2; - constexpr uint16_t kListTag = 0xcafe; - constexpr int32_t kValue = 0x1badd00d; - - struct { - const uint16_t list_length = 0xc; - const uint16_t list_type = kListTag; - const uint16_t attr_length = 0x8; // 4 bytes of value + 4 bytes of header. - const uint16_t attr_type = kDummyTag; - const uint32_t attr_value = kValue; - } expected; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.PushList(kListTag); - request.AddInt(kDummyTag, kValue); - request.PopList(); - - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, NestedList) { - // List1: { List2: { Dummy: Value}} - constexpr uint16_t kDummyTag = 0xfce2; - constexpr uint16_t kList1Tag = 0xcafe; - constexpr uint16_t kList2Tag = 0xfeed; - constexpr int32_t kValue = 0x1badd00d; - - struct { - const uint16_t list1_length = 0x10; - const uint16_t list1_type = kList1Tag; - const uint16_t list2_length = 0xc; - const uint16_t list2_type = kList2Tag; - const uint16_t attr_length = 0x8; - const uint16_t attr_type = kDummyTag; - const uint32_t attr_value = kValue; - } expected; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.PushList(kList1Tag); - request.PushList(kList2Tag); - request.AddInt(kDummyTag, kValue); - request.PopList(); - request.PopList(); - - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, ListSequence) { - // List1: { Dummy1: Value1}, List2: { Dummy2: Value2 } - constexpr uint16_t kDummy1Tag = 0xfce2; - constexpr uint16_t kDummy2Tag = 0xfd38; - constexpr uint16_t kList1Tag = 0xcafe; - constexpr uint16_t kList2Tag = 0xfeed; - constexpr int32_t kValue1 = 0x1badd00d; - constexpr int32_t kValue2 = 0xfee1; - - struct { - const uint16_t list1_length = 0xc; - const uint16_t list1_type = kList1Tag; - const uint16_t attr1_length = 0x8; - const uint16_t attr1_type = kDummy1Tag; - const uint32_t attr1_value = kValue1; - const uint16_t list2_length = 0xc; - const uint16_t list2_type = kList2Tag; - const uint16_t attr2_length = 0x8; - const uint16_t attr2_type = kDummy2Tag; - const uint32_t attr2_value = kValue2; - } expected; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.PushList(kList1Tag); - request.AddInt(kDummy1Tag, kValue1); - request.PopList(); - request.PushList(kList2Tag); - request.AddInt(kDummy2Tag, kValue2); - request.PopList(); - - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, ComplexList) { - // List1: { List2: { Dummy1: Value1 }, Dummy2: Value2 } - constexpr uint16_t kDummy1Tag = 0xfce2; - constexpr uint16_t kDummy2Tag = 0xfd38; - constexpr uint16_t kList1Tag = 0xcafe; - constexpr uint16_t kList2Tag = 0xfeed; - constexpr int32_t kValue1 = 0x1badd00d; - constexpr int32_t kValue2 = 0xfee1; - - struct { - const uint16_t list1_length = 0x18; - const uint16_t list1_type = kList1Tag; - const uint16_t list2_length = 0xc; // Note, this only covers until kValue1. - const uint16_t list2_type = kList2Tag; - const uint16_t attr1_length = 0x8; - const uint16_t attr1_type = kDummy1Tag; - const uint32_t attr1_value = kValue1; - const uint16_t attr2_length = 0x8; - const uint16_t attr2_type = kDummy2Tag; - const uint32_t attr2_value = kValue2; - } expected; - - cvd::NetlinkRequest request(RTM_SETLINK, 0); - request.PushList(kList1Tag); - request.PushList(kList2Tag); - request.AddInt(kDummy1Tag, kValue1); - request.PopList(); - request.AddInt(kDummy2Tag, kValue2); - request.PopList(); - - EXPECT_THAT(request, RequestDataIs(&expected, sizeof(expected))); -} - -TEST(NetlinkClientTest, SimpleNetlinkCreateHeader) { - cvd::NetlinkRequest request(RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL); - constexpr char kValue[] = "random string"; - request.AddString(0, kValue); // Have something to work with. - - constexpr size_t kMsgLength = - sizeof(nlmsghdr) + sizeof(nlattr) + RTA_ALIGN(sizeof(kValue)); - uint32_t base_seq = request.SeqNo(); - - EXPECT_THAT(request, RequestHeaderIs( - kMsgLength, - RTM_NEWLINK, - NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST, - base_seq)); - - cvd::NetlinkRequest request2(RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL); - request2.AddString(0, kValue); // Have something to work with. - EXPECT_THAT(request2, RequestHeaderIs( - kMsgLength, - RTM_NEWLINK, - NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST, - base_seq + 1)); -} - -TEST(NetlinkClientTest, SimpleNetlinkUpdateHeader) { - cvd::NetlinkRequest request(RTM_SETLINK, 0); - constexpr char kValue[] = "random string"; - request.AddString(0, kValue); // Have something to work with. - - constexpr size_t kMsgLength = - sizeof(nlmsghdr) + sizeof(nlattr) + RTA_ALIGN(sizeof(kValue)); - uint32_t base_seq = request.SeqNo(); - - EXPECT_THAT(request, RequestHeaderIs( - kMsgLength, RTM_SETLINK, NLM_F_REQUEST | NLM_F_ACK, base_seq)); - - cvd::NetlinkRequest request2(RTM_SETLINK, 0); - request2.AddString(0, kValue); // Have something to work with. - EXPECT_THAT(request2, RequestHeaderIs( - kMsgLength, RTM_SETLINK, NLM_F_REQUEST | NLM_F_ACK, base_seq + 1)); -} - -} // namespace cvd diff --git a/common/libs/net/network_interface.h b/common/libs/net/network_interface.h deleted file mode 100644 index 2f4430d1..00000000 --- a/common/libs/net/network_interface.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef GUEST_GCE_NETWORK_NETWORK_INTERFACE_H_ -#define GUEST_GCE_NETWORK_NETWORK_INTERFACE_H_ - -#include <string> - -namespace cvd { - -// Abstraction of network interfaces. -// This interface provides means to modify network interface parameters. -class NetworkInterface { - public: - explicit NetworkInterface(size_t if_index) - : if_index_(if_index) {} - - NetworkInterface() = default; - ~NetworkInterface() = default; - - // Get network interface index. - size_t Index() const { - return if_index_; - } - - // Set name of the network interface. - NetworkInterface& SetName(const std::string& new_name) { - name_ = new_name; - return *this; - } - - // Get name of the network interface. - // Returns name, if previously set. - const std::string& Name() const { - return name_; - } - - int PrefixLength() const { - return prefix_len_; - } - - // Set operational state of the network interface (ie. whether interface is - // up). - NetworkInterface& SetOperational(bool is_operational) { - is_operational_ = is_operational; - return *this; - } - - // Get operational state of the interface. Value of 'true' indicates interface - // should be 'up'. - bool IsOperational() const { - return is_operational_; - } - - // Set IPv4 address of the network interface. - NetworkInterface& SetAddress(const std::string& address) { - ip_address_ = address; - return *this; - } - - // Get IPv4 address of the network interface. - const std::string& Address() const { - return ip_address_; - } - - // Set IPv4 broadcast address of the network interface. - NetworkInterface& SetBroadcastAddress(const std::string& address) { - bc_address_ = address; - return *this; - } - - // Set IPv4 prefix length - NetworkInterface& SetPrefixLength(int len) { - prefix_len_ = len; - return *this; - } - - // Get IPv4 broadcast address of the network interface. - const std::string& BroadcastAddress() const { - return bc_address_; - } - - private: - // Index of the network interface in the system table. 0 indicates new - // interface. - size_t if_index_ = 0; - // Name of the interface, e.g. "eth0". - std::string name_; - // Operational status, i.e. whether interface is up. - bool is_operational_ = false; - // IPv4 address of this interface. - std::string ip_address_; - // IPv4 broadcast address of this interface. - std::string bc_address_; - // IPv4 prefix (aka netmask. 0 means use the default) - int prefix_len_ = 24; - - NetworkInterface(const NetworkInterface&); - NetworkInterface& operator= (const NetworkInterface&); -}; - -} // namespace cvd - -#endif // GUEST_GCE_NETWORK_NETWORK_INTERFACE_H_ diff --git a/common/libs/net/network_interface_manager.cpp b/common/libs/net/network_interface_manager.cpp deleted file mode 100644 index 0d1dc56b..00000000 --- a/common/libs/net/network_interface_manager.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/net/network_interface_manager.h" - -#include <arpa/inet.h> -#include <linux/if_addr.h> -#include <linux/if_link.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <net/if.h> - -#include <memory> - -#include "common/libs/glog/logging.h" -#include "common/libs/net/network_interface.h" - -namespace cvd { -namespace { -NetlinkRequest BuildLinkRequest( - const NetworkInterface& interface) { - NetlinkRequest request(RTM_SETLINK, 0); - request.AddIfInfo(interface.Index(), interface.IsOperational()); - if (!interface.Name().empty()) { - request.AddString(IFLA_IFNAME, interface.Name()); - } - - return request; -} - -NetlinkRequest BuildAddrRequest( - const NetworkInterface& interface) { - NetlinkRequest request(RTM_NEWADDR, 0); - request.AddAddrInfo(interface.Index(), interface.PrefixLength()); - in_addr_t address{inet_addr(interface.Address().c_str())}; - request.AddInt(IFA_LOCAL, address); - request.AddInt(IFA_ADDRESS, address); - request.AddInt(IFA_BROADCAST, - inet_addr(interface.BroadcastAddress().c_str())); - - return request; -} -} // namespace - -std::unique_ptr<NetworkInterfaceManager> NetworkInterfaceManager::New( - NetlinkClientFactory* nl_factory) { - std::unique_ptr<NetworkInterfaceManager> mgr; - - if (nl_factory == NULL) { - nl_factory = NetlinkClientFactory::Default(); - } - - auto client = nl_factory->New(NETLINK_ROUTE); - if (client) { - mgr.reset(new NetworkInterfaceManager(std::move(client))); - } - - return mgr; -} - -NetworkInterfaceManager::NetworkInterfaceManager( - std::unique_ptr<NetlinkClient> nl_client) - : nl_client_(std::move(nl_client)) {} - -std::unique_ptr<NetworkInterface> NetworkInterfaceManager::Open( - const std::string& if_name, const std::string& if_name_alt) { - std::unique_ptr<NetworkInterface> iface; - // NOTE: do not replace this code with an IOCTL call. - // On SELinux enabled Androids, RILD is not permitted to execute an IOCTL - // and this call will fail. - int32_t index = if_nametoindex(if_name.c_str()); - if (index == 0) { - // Try the alternate name. This will be renamed to our preferred name - // by the kernel, because we specify IFLA_IFNAME, but open by index. - LOG(ERROR) << "Failed to get interface (" << if_name << ") index, " - << "trying alternate."; - index = if_nametoindex(if_name_alt.c_str()); - if (index == 0) { - LOG(ERROR) << "Failed to get interface (" << if_name_alt << ") index."; - return iface; - } - } - - iface.reset(new NetworkInterface(index)); - return iface; -} - -bool NetworkInterfaceManager::ApplyChanges(const NetworkInterface& iface) { - if (!nl_client_->Send(BuildLinkRequest(iface))) return false; - // Terminate immediately if interface is down. - if (!iface.IsOperational()) return true; - return nl_client_->Send(BuildAddrRequest(iface)); -} - -} // namespace cvd diff --git a/common/libs/net/network_interface_manager.h b/common/libs/net/network_interface_manager.h deleted file mode 100644 index f28b0ff1..00000000 --- a/common/libs/net/network_interface_manager.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef COMMON_LIBS_NET_NETWORK_INTERFACE_MANAGER_H_ -#define COMMON_LIBS_NET_NETWORK_INTERFACE_MANAGER_H_ - -#include <memory> -#include <string> - -#include "common/libs/net/netlink_client.h" -#include "common/libs/net/network_interface.h" - -namespace cvd { - -// Network interface manager class. -// - Provides access for existing network interfaces, -// - provides means to create new virtual interfaces. -// -// Example usage: -// -// std::unique_ptr<NetlinkClient> client(NetlinkClient::GetDefault()); -// NetworkInterfaceManager manager(client.get()); -// std::unique_ptr<NetworkInterface> iface(manager.Open("eth0", "em0")); -// -class NetworkInterfaceManager { - public: - // Open existing network interface. - // - // NOTE: this method does not fill in any NetworkInterface details yet. - std::unique_ptr<NetworkInterface> Open(const std::string& if_name, - const std::string& if_name_alt); - - // Apply changes made to existing network interface. - // This method cannot be used to instantiate new network interfaces. - bool ApplyChanges(const NetworkInterface& interface); - - // Create new connected pair of virtual (veth) interfaces. - // Supplied pair of interfaces describe both endpoints' properties. - bool CreateVethPair(const NetworkInterface& first, - const NetworkInterface& second); - - // Creates new NetworkInterfaceManager. - static std::unique_ptr<NetworkInterfaceManager> New( - NetlinkClientFactory* factory); - - private: - NetworkInterfaceManager(std::unique_ptr<NetlinkClient> nl_client); - - // Build (partial) netlink request. - bool BuildRequest(NetlinkRequest* request, const NetworkInterface& interface); - - std::unique_ptr<NetlinkClient> nl_client_; - - NetworkInterfaceManager(const NetworkInterfaceManager&); - NetworkInterfaceManager& operator= (const NetworkInterfaceManager&); -}; - -} // namespace cvd - -#endif // COMMON_LIBS_NET_NETWORK_INTERFACE_MANAGER_H_ diff --git a/common/libs/tcp_socket/Android.bp b/common/libs/tcp_socket/Android.bp deleted file mode 100644 index c5f95507..00000000 --- a/common/libs/tcp_socket/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_library_shared { - name: "cuttlefish_tcp_socket", - srcs: [ - "tcp_socket.cpp", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "liblog", - ], - header_libs: [ - "cuttlefish_glog", - ], - defaults: ["cuttlefish_host_and_guest"], -} diff --git a/common/libs/tcp_socket/tcp_socket.cpp b/common/libs/tcp_socket/tcp_socket.cpp deleted file mode 100644 index 64da7d72..00000000 --- a/common/libs/tcp_socket/tcp_socket.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/tcp_socket/tcp_socket.h" - -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/types.h> - -#include <cerrno> - -#include <glog/logging.h> - -using cvd::ClientSocket; -using cvd::ServerSocket; - -ClientSocket::ClientSocket(int port) - : fd_(SharedFD::SocketLocalClient(port, SOCK_STREAM)) {} - -cvd::Message ClientSocket::RecvAny(std::size_t length) { - Message buf(length); - auto read_count = fd_->Read(buf.data(), buf.size()); - if (read_count < 0) { - read_count = 0; - } - buf.resize(read_count); - return buf; -} - -bool ClientSocket::closed() const { - std::lock_guard<std::mutex> guard(closed_lock_); - return other_side_closed_; -} - -cvd::Message ClientSocket::Recv(std::size_t length) { - Message buf(length); - ssize_t total_read = 0; - while (total_read < static_cast<ssize_t>(length)) { - auto just_read = fd_->Read(&buf[total_read], buf.size() - total_read); - if (just_read <= 0) { - if (just_read < 0) { - LOG(ERROR) << "read() error: " << strerror(errno); - } - { - std::lock_guard<std::mutex> guard(closed_lock_); - other_side_closed_ = true; - } - return Message{}; - } - total_read += just_read; - } - CHECK(total_read == static_cast<ssize_t>(length)); - return buf; -} - -ssize_t ClientSocket::SendNoSignal(const uint8_t* data, std::size_t size) { - std::lock_guard<std::mutex> lock(send_lock_); - ssize_t written{}; - while (written < static_cast<ssize_t>(size)) { - if (!fd_->IsOpen()) { - LOG(ERROR) << "fd_ is closed"; - } - auto just_written = fd_->Send(data + written, size - written, MSG_NOSIGNAL); - if (just_written <= 0) { - LOG(INFO) << "Couldn't write to client: " << strerror(errno); - { - std::lock_guard<std::mutex> guard(closed_lock_); - other_side_closed_ = true; - } - return just_written; - } - written += just_written; - } - return written; -} - -ssize_t ClientSocket::SendNoSignal(const Message& message) { - return SendNoSignal(&message[0], message.size()); -} - -ServerSocket::ServerSocket(int port) - : fd_{SharedFD::SocketLocalServer(port, SOCK_STREAM)} { - if (!fd_->IsOpen()) { - LOG(FATAL) << "Couldn't open streaming server on port " << port; - } -} - -ClientSocket ServerSocket::Accept() { - SharedFD client = SharedFD::Accept(*fd_); - if (!client->IsOpen()) { - LOG(FATAL) << "Error attemping to accept: " << strerror(errno); - } - return ClientSocket{client}; -} - -void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint8_t b) { - msg->push_back(b); -} - -void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint16_t s) { - const std::uint16_t n = htons(s); - auto p = reinterpret_cast<const std::uint8_t*>(&n); - msg->insert(msg->end(), p, p + sizeof n); -} - -void cvd::AppendInNetworkByteOrder(Message* msg, const std::uint32_t w) { - const std::uint32_t n = htonl(w); - auto p = reinterpret_cast<const std::uint8_t*>(&n); - msg->insert(msg->end(), p, p + sizeof n); -} - -void cvd::AppendInNetworkByteOrder(Message* msg, const std::int32_t w) { - std::uint32_t u{}; - std::memcpy(&u, &w, sizeof u); - AppendInNetworkByteOrder(msg, u); -} - -void cvd::AppendInNetworkByteOrder(Message* msg, const std::string& str) { - msg->insert(msg->end(), str.begin(), str.end()); -} diff --git a/common/libs/tcp_socket/tcp_socket.h b/common/libs/tcp_socket/tcp_socket.h deleted file mode 100644 index e484f48a..00000000 --- a/common/libs/tcp_socket/tcp_socket.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/fs/shared_fd.h" - -#include <unistd.h> - -#include <cstddef> -#include <cstdint> -#include <mutex> -#include <vector> - -namespace cvd { -using Message = std::vector<std::uint8_t>; - -class ServerSocket; - -// Recv and Send wait until all data has been received or sent. -// Send is thread safe in this regard, Recv is not. -class ClientSocket { - public: - ClientSocket(ClientSocket&& other) : fd_{other.fd_} {} - - ClientSocket& operator=(ClientSocket&& other) { - fd_ = other.fd_; - return *this; - } - - ClientSocket(int port); - - ClientSocket(const ClientSocket&) = delete; - ClientSocket& operator=(const ClientSocket&) = delete; - - Message Recv(std::size_t length); - // RecvAny will receive whatever is available. - // An empty message returned indicates error or close. - Message RecvAny(std::size_t length); - // Sends are called with MSG_NOSIGNAL to suppress SIGPIPE - ssize_t SendNoSignal(const std::uint8_t* data, std::size_t size); - ssize_t SendNoSignal(const Message& message); - - template <std::size_t N> - ssize_t SendNoSignal(const std::uint8_t (&data)[N]) { - return SendNoSignal(data, N); - } - - bool closed() const; - - private: - friend ServerSocket; - explicit ClientSocket(cvd::SharedFD fd) : fd_(fd) {} - - cvd::SharedFD fd_; - bool other_side_closed_{}; - mutable std::mutex closed_lock_; - std::mutex send_lock_; -}; - -class ServerSocket { - public: - explicit ServerSocket(int port); - - ServerSocket(const ServerSocket&) = delete; - ServerSocket& operator=(const ServerSocket&) = delete; - - ClientSocket Accept(); - - private: - cvd::SharedFD fd_; -}; - -void AppendInNetworkByteOrder(Message* msg, const std::uint8_t b); -void AppendInNetworkByteOrder(Message* msg, const std::uint16_t s); -void AppendInNetworkByteOrder(Message* msg, const std::uint32_t w); -void AppendInNetworkByteOrder(Message* msg, const std::int32_t w); -void AppendInNetworkByteOrder(Message* msg, const std::string& str); - -inline void AppendToMessage(Message*) {} - -template <typename T, typename... Ts> -void AppendToMessage(Message* msg, T v, Ts... vals) { - AppendInNetworkByteOrder(msg, v); - AppendToMessage(msg, vals...); -} - -template <typename... Ts> -Message CreateMessage(Ts... vals) { - Message m; - AppendToMessage(&m, vals...); - return m; -} - -} // namespace cvd diff --git a/common/libs/thread_safe_queue/thread_safe_queue.h b/common/libs/thread_safe_queue/thread_safe_queue.h deleted file mode 100644 index 86629284..00000000 --- a/common/libs/thread_safe_queue/thread_safe_queue.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <mutex> -#include <condition_variable> -#include <deque> -#include <utility> -#include <iterator> - -namespace cvd { -// Simple queue with Push and Pop capabilities. -// If the max_elements argument is passed to the constructor, and Push is called -// when the queue holds max_elements items, the max_elements_handler is called -// with a pointer to the internal QueueImpl. The call is made while holding -// the guarding mutex; operations on the QueueImpl will not interleave with -// other threads calling Push() or Pop(). -// The QueueImpl type will be a SequenceContainer. -template <typename T> -class ThreadSafeQueue { - public: - using QueueImpl = std::deque<T>; - ThreadSafeQueue() = default; - explicit ThreadSafeQueue(std::size_t max_elements, - std::function<void(QueueImpl*)> max_elements_handler) - : max_elements_{max_elements}, - max_elements_handler_{std::move(max_elements_handler)} {} - - T Pop() { - std::unique_lock<std::mutex> guard(m_); - while (items_.empty()) { - new_item_.wait(guard); - } - auto t = std::move(items_.front()); - items_.pop_front(); - return t; - } - - void Push(T&& t) { - std::lock_guard<std::mutex> guard(m_); - DropItemsIfAtCapacity(); - items_.push_back(std::move(t)); - new_item_.notify_one(); - } - - void Push(const T& t) { - std::lock_guard<std::mutex> guard(m_); - DropItemsIfAtCapacity(); - items_.push_back(t); - new_item_.notify_one(); - } - - private: - void DropItemsIfAtCapacity() { - if (max_elements_ && max_elements_ == items_.size()) { - max_elements_handler_(&items_); - } - } - - std::mutex m_; - std::size_t max_elements_{}; - std::function<void(QueueImpl*)> max_elements_handler_{}; - std::condition_variable new_item_; - QueueImpl items_; -}; -} // namespace cvd diff --git a/common/libs/threads/Android.bp b/common/libs/threads/Android.bp deleted file mode 100644 index 97b4be82..00000000 --- a/common/libs/threads/Android.bp +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_test_host { - name: "cuttlefish_thread_test", - srcs: [ - "cuttlefish_thread_test.cpp", - ], - shared_libs: [ - "cuttlefish_time", - "libbase", - ], - static_libs: [ - "libgtest_host", - ], - cpp_std: "c++17", - defaults: ["cuttlefish_host_only"], - test_suites: ["general-tests"], -} diff --git a/common/libs/threads/TEST_MAPPING b/common/libs/threads/TEST_MAPPING deleted file mode 100644 index 87f78847..00000000 --- a/common/libs/threads/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presubmit": [ - { - "name": "cuttlefish_thread_test", - "host": true - } - ] -} diff --git a/common/libs/threads/cuttlefish_thread.h b/common/libs/threads/cuttlefish_thread.h deleted file mode 100644 index 54e5ceb8..00000000 --- a/common/libs/threads/cuttlefish_thread.h +++ /dev/null @@ -1,169 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 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. - */ - -// Concurreny classess for cuttlefish. -// -// These more or less mimic the interface of the C++ classes: -// Mutex is similar to std::mutex -// ConditionVariable is similar to std::condition_variable -// LockGuard is similar to std::lock_guard -// -// There are some extensions: -// ScopedThread creates a Thread and joins it when the class is destroyed -// This comes in handy during unit tests. It should be used cautiously, if -// at all, in production code because thread creation isn't free. - -#include <stdint.h> -#include <pthread.h> -#include "common/libs/time/monotonic_time.h" - -namespace cvd { - -class Mutex { - friend class ConditionVariable; - - public: - Mutex() { - pthread_mutex_init(&mutex_, NULL); - } - - ~Mutex() { - pthread_mutex_destroy(&mutex_); - } - - void Lock() { - pthread_mutex_lock(&mutex_); - } - - void Unlock() { - pthread_mutex_unlock(&mutex_); - } - - // TODO(ghartman): Add TryLock if and only if there's a good use case. - - protected: - - pthread_mutex_t* GetMutex() { - return &mutex_; - } - - pthread_mutex_t mutex_; - - private: - Mutex(const Mutex&); - Mutex& operator= (const Mutex&); -}; - -class ConditionVariable { - public: - explicit ConditionVariable(Mutex* mutex) : mutex_(mutex) { - pthread_condattr_t attr; - pthread_condattr_init(&attr); - pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - pthread_cond_init(&cond_, &attr); - pthread_condattr_destroy(&attr); - } - - ~ConditionVariable() { - pthread_cond_destroy(&cond_); - } - - int NotifyOne() { - return pthread_cond_signal(&cond_); - } - - int NotifyAll() { - return pthread_cond_broadcast(&cond_); - } - - int Wait() { - return pthread_cond_wait(&cond_, mutex_->GetMutex()); - } - - int WaitUntil(const cvd::time::MonotonicTimePoint& tp) { - struct timespec ts; - tp.ToTimespec(&ts); - return pthread_cond_timedwait(&cond_, mutex_->GetMutex(), &ts); - } - - protected: - Mutex* mutex_; - pthread_cond_t cond_; - - private: - ConditionVariable(const ConditionVariable&); - ConditionVariable& operator= (const ConditionVariable&); -}; - -template <typename M> class LockGuard { - public: - explicit LockGuard(M& mutex) : mutex_(mutex) { - mutex_.Lock(); - } - - ~LockGuard() { - mutex_.Unlock(); - } - - private: - M& mutex_; - - LockGuard(const LockGuard&); - LockGuard& operator= (const LockGuard&); -}; - -// Use only in cases where the mutex can't be upgraded to a Mutex. -template<> class LockGuard<pthread_mutex_t> { - public: - explicit LockGuard(pthread_mutex_t& mutex) : mutex_(mutex), unlock_(false) { - unlock_ = (pthread_mutex_lock(&mutex_) == 0); - } - - ~LockGuard() { - if (unlock_) { - pthread_mutex_unlock(&mutex_); - } - } - - private: - pthread_mutex_t& mutex_; - bool unlock_; - - LockGuard(const LockGuard&); - LockGuard& operator= (const LockGuard&); -}; - -class ScopedThread { - public: - ScopedThread(void* (*start)(void*), void* arg) { - pthread_create(&thread_, NULL, start, arg); - } - - ~ScopedThread() { - void* value; - pthread_join(thread_, &value); - } - - protected: - pthread_t thread_; - - private: - ScopedThread(const ScopedThread&); - ScopedThread& operator= (const ScopedThread&); -}; - -} // namespace cvd diff --git a/common/libs/threads/cuttlefish_thread_test.cpp b/common/libs/threads/cuttlefish_thread_test.cpp deleted file mode 100644 index 5989e9b7..00000000 --- a/common/libs/threads/cuttlefish_thread_test.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/threads/cuttlefish_thread.h" - -#include <gtest/gtest.h> - -#include <android-base/logging.h> -#include "common/libs/threads/thunkers.h" -#include "common/libs/time/monotonic_time.h" - -using cvd::ConditionVariable; -using cvd::Mutex; -using cvd::ScopedThread; -using cvd::time::MonotonicTimePoint; -using cvd::time::Milliseconds; - -static const int FINISHED = 100; - -static void SleepUntil(const MonotonicTimePoint& in) { - struct timespec ts; - in.ToTimespec(&ts); -#ifdef CLOCK_MONOTONIC_RAW - // WARNING: - // While we do have CLOCK_MONOTONIC_RAW, we can't depend on it until: - // - ALL places relying on MonotonicTimePoint are fixed, - // - pthread supports pthread_timewait_monotonic. - // - CLOCK_MONOTONIC_RAW is re-enabled in monotonic_time.h. - // - // This is currently observable as a LEGITIMATE problem while running - // this test. DO NOT revert this to CLOCK_MONOTONIC_RAW until this is - // fixed everywhere AND this test passes. - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL); -#else - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL); -#endif -} - -class MutexTest { - public: - MutexTest() : busy_(NULL), stage_(0) {} - - void Run() { - { - ScopedThread thread_a(cvd::thunk<void, &MutexTest::FastThread>, this); - ScopedThread thread_b(cvd::thunk<void, &MutexTest::SlowThread>, this); - } - LOG(INFO) << "MutexTest: completed at stage " - << stage_ - << ", result: " - << ((stage_ == FINISHED) ? "PASSED" : "FAILED"); - } - -protected: - void* FastThread() { - mutex_.Lock(); - CHECK(busy_ == NULL); - busy_ = "FastThread"; - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - stage_ = 1; - busy_ = NULL; - mutex_.Unlock(); - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(10)); - mutex_.Lock(); - CHECK(busy_ == NULL); - busy_ = "FastThread"; - CHECK(stage_ == 2); - stage_ = FINISHED; - busy_ = NULL; - mutex_.Unlock(); - return NULL; - } - - void* SlowThread() { - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(50)); - mutex_.Lock(); - CHECK(busy_== NULL); - busy_ = "SlowThread"; - CHECK(stage_ == 1); - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - stage_ = 2; - busy_ = NULL; - mutex_.Unlock(); - return NULL; - } - - Mutex mutex_; - const char* busy_; - int stage_; -}; - -class NotifyOneTest { - public: - NotifyOneTest() : cond_(&mutex_), signalled_(0) {} - - void Run() { - { - ScopedThread thread_s( - cvd::thunk<void, &NotifyOneTest::SignalThread>, this); - ScopedThread thread_w1( - cvd::thunk<void, &NotifyOneTest::WaitThread>, this); - ScopedThread thread_w2( - cvd::thunk<void, &NotifyOneTest::WaitThread>, this); - } - LOG(INFO) << "NotifyOneTest: completed, signalled " - << signalled_ - << ", result: " - << ((signalled_ == 2) ? "PASSED" : "FAILED"); - } - -protected: - void* SignalThread() { - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - mutex_.Lock(); - cond_.NotifyOne(); - mutex_.Unlock(); - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - mutex_.Lock(); - CHECK(signalled_== 1); - cond_.NotifyOne(); - mutex_.Unlock(); - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - mutex_.Lock(); - CHECK(signalled_ == 2); - mutex_.Unlock(); - return NULL; - } - - void* WaitThread() { - mutex_.Lock(); - cond_.Wait(); - signalled_++; - mutex_.Unlock(); - return NULL; - } - - Mutex mutex_; - ConditionVariable cond_; - int signalled_; -}; - -class NotifyAllTest { - public: - NotifyAllTest() : cond_(&mutex_), signalled_(0) {} - - void Run() { - { - ScopedThread thread_s( - cvd::thunk<void, &NotifyAllTest::SignalThread>, this); - ScopedThread thread_w1( - cvd::thunk<void, &NotifyAllTest::WaitThread>, this); - ScopedThread thread_w2( - cvd::thunk<void, &NotifyAllTest::WaitThread>, this); - } - printf("NotifyAllTest: completed, signalled %d (%s)\n", - signalled_, (signalled_ == 2) ? "PASSED" : "FAILED"); - } - -protected: - void* SignalThread() { - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - mutex_.Lock(); - cond_.NotifyAll(); - mutex_.Unlock(); - SleepUntil(MonotonicTimePoint::Now() + Milliseconds(100)); - mutex_.Lock(); - CHECK(signalled_ == 2); - mutex_.Unlock(); - return NULL; - } - - void* WaitThread() { - mutex_.Lock(); - cond_.Wait(); - signalled_++; - mutex_.Unlock(); - return NULL; - } - - Mutex mutex_; - ConditionVariable cond_; - int signalled_; -}; - -class WaitUntilTest { - public: - WaitUntilTest() : cond_(&mutex_), stage_(0) {} - - bool Run() { - start_ = MonotonicTimePoint::Now(); - { - ScopedThread thread_s( - cvd::thunk<void, &WaitUntilTest::SignalThread>, this); - ScopedThread thread_w2( - cvd::thunk<void, &WaitUntilTest::WaitThread>, this); - } - printf("WaitUntilTest: completed, stage %d (%s)\n", - stage_, (stage_ == FINISHED) ? "PASSED" : "FAILED"); - return stage_ == FINISHED; - } - -protected: - void* SignalThread() { - SleepUntil(start_ + Milliseconds(200)); - mutex_.Lock(); - CHECK(stage_ == 2); - cond_.NotifyOne(); - stage_ = 3; - mutex_.Unlock(); - return NULL; - } - - void* WaitThread() { - mutex_.Lock(); - CHECK(stage_ == 0); - stage_ = 1; - cond_.WaitUntil(start_ + Milliseconds(50)); - MonotonicTimePoint current(MonotonicTimePoint::Now()); - CHECK(Milliseconds(current - start_).count() >= 50); - CHECK(Milliseconds(current - start_).count() <= 100); - stage_ = 2; - cond_.WaitUntil(start_ + Milliseconds(1000)); - current = MonotonicTimePoint::Now(); - CHECK(Milliseconds(current - start_).count() <= 500); - CHECK(stage_ == 3); - stage_ = FINISHED; - mutex_.Unlock(); - return NULL; - } - - Mutex mutex_; - ConditionVariable cond_; - int stage_; - MonotonicTimePoint start_; -}; - -TEST(ThreadTest, Mutex) { - MutexTest mt; - mt.Run(); - NotifyOneTest nt1; - nt1.Run(); - NotifyAllTest nta; - nta.Run(); - WaitUntilTest wu; - bool success = wu.Run(); - EXPECT_TRUE(success); -} diff --git a/common/libs/threads/thread_annotations.h b/common/libs/threads/thread_annotations.h deleted file mode 100644 index 3ba67e7f..00000000 --- a/common/libs/threads/thread_annotations.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 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. - */ - -#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__) -#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) -#else -#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op -#endif - -#define CAPABILITY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) - -#define SCOPED_CAPABILITY \ - THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) - -#define GUARDED_BY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) - -#define PT_GUARDED_BY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) - -#define ACQUIRED_BEFORE(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) - -#define ACQUIRED_AFTER(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) - -#define REQUIRES(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) - -#define REQUIRES_SHARED(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) - -#define ACQUIRE(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) - -#define ACQUIRE_SHARED(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) - -#define RELEASE(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) - -#define RELEASE_SHARED(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) - -#define TRY_ACQUIRE(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) - -#define TRY_ACQUIRE_SHARED(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) - -#define EXCLUDES(...) \ - THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) - -#define ASSERT_CAPABILITY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) - -#define ASSERT_SHARED_CAPABILITY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) - -#define RETURN_CAPABILITY(x) \ - THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) - -#define NO_THREAD_SAFETY_ANALYSIS \ - THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) diff --git a/common/libs/threads/thunkers.h b/common/libs/threads/thunkers.h deleted file mode 100644 index bb971749..00000000 --- a/common/libs/threads/thunkers.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ -#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_ -#define CUTTLEFISH_COMMON_COMMON_LIBS_THREADS_THUNKERS_H_ - -namespace cvd { -namespace internal { - -template <typename HalType, typename F> -struct ThunkerImpl; - -template <typename HalType, typename Impl, typename R, typename... Args> -struct ThunkerImpl<HalType, R (Impl::*)(Args...)> { - template <R (Impl::*MemFn)(Args...)> - static R call(HalType* in, Args... args) { - return (reinterpret_cast<Impl*>(in)->*MemFn)(args...); - } -}; - -template <typename HalType, typename Impl, typename R, typename... Args> -struct ThunkerImpl<HalType, R (Impl::*)(Args...) const> { - template <R (Impl::*MemFn)(Args...) const> - static R call(const HalType* in, Args... args) { - return (reinterpret_cast<const Impl*>(in)->*MemFn)(args...); - } -}; - -template <typename HalType, auto MemFunc> -struct Thunker { - static constexpr auto call = - ThunkerImpl<HalType, decltype(MemFunc)>::template call<MemFunc>; -}; - -} // namespace internal - -template <typename HalType, auto MemFunc> -constexpr auto thunk = internal::Thunker<HalType, MemFunc>::call; - -} // namespace cvd - -#endif diff --git a/common/libs/time/Android.bp b/common/libs/time/Android.bp deleted file mode 100644 index 972958f2..00000000 --- a/common/libs/time/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_library_shared { - name: "cuttlefish_time", - srcs: [ - "monotonic_time.cpp", - ], - defaults: ["cuttlefish_host_and_guest"], -} - -cc_test_host { - name: "monotonic_time_test", - srcs: [ - "monotonic_time_test.cpp", - ], - shared_libs: [ - "cuttlefish_time", - ], - defaults: ["cuttlefish_host_only"], - test_suites: ["general-tests"], -} diff --git a/common/libs/time/TEST_MAPPING b/common/libs/time/TEST_MAPPING deleted file mode 100644 index 4c95014f..00000000 --- a/common/libs/time/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presubmit": [ - { - "name": "monotonic_time_test", - "host": true - } - ] -} diff --git a/common/libs/time/monotonic_time.cpp b/common/libs/time/monotonic_time.cpp deleted file mode 100644 index 1d7bbd86..00000000 --- a/common/libs/time/monotonic_time.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/time/monotonic_time.h" - -namespace cvd { -namespace time { -MonotonicTimePointFactory* MonotonicTimePointFactory::GetInstance() { - static MonotonicTimePointFactory factory; - - return &factory; -} -} // namespace time -} // namespace cvd diff --git a/common/libs/time/monotonic_time.h b/common/libs/time/monotonic_time.h deleted file mode 100644 index 8f5de132..00000000 --- a/common/libs/time/monotonic_time.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> -#include <time.h> - -namespace cvd { -namespace time { - -static const int64_t kNanosecondsPerSecond = 1000000000; - -class TimeDifference { - public: - TimeDifference(time_t seconds, long nanoseconds, int64_t scale) : - scale_(scale), truncated_(false) { - ts_.tv_sec = seconds; - ts_.tv_nsec = nanoseconds; - if (scale_ == kNanosecondsPerSecond) { - truncated_ = true; - truncated_ns_ = 0; - } - } - - TimeDifference(const TimeDifference& in, int64_t scale) : - scale_(scale), truncated_(false) { - ts_ = in.GetTS(); - if (scale_ == kNanosecondsPerSecond) { - truncated_ = true; - truncated_ns_ = 0; - } else if ((in.scale_ % scale_) == 0) { - truncated_ = true; - truncated_ns_ = ts_.tv_nsec; - } - } - - TimeDifference(const struct timespec& in, int64_t scale) : - ts_(in), scale_(scale), truncated_(false) { } - - TimeDifference operator*(const uint32_t factor) { - TimeDifference rval = *this; - rval.ts_.tv_sec = ts_.tv_sec * factor; - // Create temporary variable to hold the multiplied - // nanoseconds so that no overflow is possible. - // Nanoseconds must be in [0, 10^9) and so all are less - // then 2^30. Even multiplied by the largest uint32 - // this will fit in a 64-bit int without overflow. - int64_t tv_nsec = static_cast<int64_t>(ts_.tv_nsec) * factor; - rval.ts_.tv_sec += (tv_nsec / kNanosecondsPerSecond); - rval.ts_.tv_nsec = tv_nsec % kNanosecondsPerSecond; - return rval; - } - - TimeDifference operator+(const TimeDifference& other) const { - struct timespec ret = ts_; - ret.tv_nsec = (ts_.tv_nsec + other.ts_.tv_nsec) % 1000000000; - ret.tv_sec = (ts_.tv_sec + other.ts_.tv_sec) + - (ts_.tv_nsec + other.ts_.tv_nsec) / 1000000000; - return TimeDifference(ret, scale_ < other.scale_ ? scale_: other.scale_); - } - - TimeDifference operator-(const TimeDifference& other) const { - struct timespec ret = ts_; - // Keeps nanoseconds positive and allow negative numbers only on - // seconds. - ret.tv_nsec = (1000000000 + ts_.tv_nsec - other.ts_.tv_nsec) % 1000000000; - ret.tv_sec = (ts_.tv_sec - other.ts_.tv_sec) - - (ts_.tv_nsec < other.ts_.tv_nsec ? 1 : 0); - return TimeDifference(ret, scale_ < other.scale_ ? scale_: other.scale_); - } - - bool operator<(const TimeDifference& other) const { - return ts_.tv_sec < other.ts_.tv_sec || - (ts_.tv_sec == other.ts_.tv_sec && ts_.tv_nsec < other.ts_.tv_nsec); - } - - int64_t count() const { - return ts_.tv_sec * (kNanosecondsPerSecond / scale_) + ts_.tv_nsec / scale_; - } - - time_t seconds() const { - return ts_.tv_sec; - } - - long subseconds_in_ns() const { - if (!truncated_) { - truncated_ns_ = (ts_.tv_nsec / scale_) * scale_; - truncated_ = true; - } - return truncated_ns_; - } - - struct timespec GetTS() const { - // We can't assume C++11, so avoid extended initializer lists. - struct timespec rval = { ts_.tv_sec, subseconds_in_ns()}; - return rval; - } - - protected: - struct timespec ts_; - int64_t scale_; - mutable bool truncated_; - mutable long truncated_ns_; -}; - -class MonotonicTimePoint { - public: - static MonotonicTimePoint Now() { - struct timespec ts; -#ifdef CLOCK_MONOTONIC_RAW - // WARNING: - // While we do have CLOCK_MONOTONIC_RAW, we can't depend on it until: - // - ALL places relying on MonotonicTimePoint are fixed, - // - pthread supports pthread_timewait_monotonic. - // - // This is currently observable as a LEGITIMATE problem while running - // pthread_test. DO NOT revert this to CLOCK_MONOTONIC_RAW until test - // passes. - clock_gettime(CLOCK_MONOTONIC, &ts); -#else - clock_gettime(CLOCK_MONOTONIC, &ts); -#endif - return MonotonicTimePoint(ts); - } - - MonotonicTimePoint() { - ts_.tv_sec = 0; - ts_.tv_nsec = 0; - } - - explicit MonotonicTimePoint(const struct timespec& ts) { - ts_ = ts; - } - - TimeDifference SinceEpoch() const { - return TimeDifference(ts_, 1); - } - - TimeDifference operator-(const MonotonicTimePoint& other) const { - struct timespec rval; - rval.tv_sec = ts_.tv_sec - other.ts_.tv_sec; - rval.tv_nsec = ts_.tv_nsec - other.ts_.tv_nsec; - if (rval.tv_nsec < 0) { - --rval.tv_sec; - rval.tv_nsec += kNanosecondsPerSecond; - } - return TimeDifference(rval, 1); - } - - MonotonicTimePoint operator+(const TimeDifference& other) const { - MonotonicTimePoint rval = *this; - rval.ts_.tv_sec += other.seconds(); - rval.ts_.tv_nsec += other.subseconds_in_ns(); - if (rval.ts_.tv_nsec >= kNanosecondsPerSecond) { - ++rval.ts_.tv_sec; - rval.ts_.tv_nsec -= kNanosecondsPerSecond; - } - return rval; - } - - bool operator==(const MonotonicTimePoint& other) const { - return (ts_.tv_sec == other.ts_.tv_sec) && - (ts_.tv_nsec == other.ts_.tv_nsec); - } - - bool operator!=(const MonotonicTimePoint& other) const { - return !(*this == other); - } - - bool operator<(const MonotonicTimePoint& other) const { - return ((ts_.tv_sec - other.ts_.tv_sec) < 0) || - ((ts_.tv_sec == other.ts_.tv_sec) && - (ts_.tv_nsec < other.ts_.tv_nsec)); - } - - bool operator>(const MonotonicTimePoint& other) const { - return other < *this; - } - - bool operator<=(const MonotonicTimePoint& other) const { - return !(*this > other); - } - - bool operator>=(const MonotonicTimePoint& other) const { - return !(*this < other); - } - - MonotonicTimePoint& operator+=(const TimeDifference& other) { - ts_.tv_sec += other.seconds(); - ts_.tv_nsec += other.subseconds_in_ns(); - if (ts_.tv_nsec >= kNanosecondsPerSecond) { - ++ts_.tv_sec; - ts_.tv_nsec -= kNanosecondsPerSecond; - } - return *this; - } - - MonotonicTimePoint& operator-=(const TimeDifference& other) { - ts_.tv_sec -= other.seconds(); - ts_.tv_nsec -= other.subseconds_in_ns(); - if (ts_.tv_nsec < 0) { - --ts_.tv_sec; - ts_.tv_nsec += kNanosecondsPerSecond; - } - return *this; - } - - void ToTimespec(struct timespec* dest) const { - *dest = ts_; - } - - protected: - struct timespec ts_; -}; - -class MonotonicTimePointFactory { - public: - static MonotonicTimePointFactory* GetInstance(); - - virtual ~MonotonicTimePointFactory() { } - - virtual void FetchCurrentTime(MonotonicTimePoint* dest) const { - *dest = MonotonicTimePoint::Now(); - } -}; - -class Seconds : public TimeDifference { - public: - explicit Seconds(const TimeDifference& difference) : - TimeDifference(difference, kNanosecondsPerSecond) { } - - Seconds(int64_t seconds) : - TimeDifference(seconds, 0, kNanosecondsPerSecond) { } -}; - -class Milliseconds : public TimeDifference { - public: - explicit Milliseconds(const TimeDifference& difference) : - TimeDifference(difference, kScale) { } - - Milliseconds(int64_t ms) : TimeDifference( - ms / 1000, (ms % 1000) * kScale, kScale) { } - - protected: - static const int kScale = kNanosecondsPerSecond / 1000; -}; - -class Microseconds : public TimeDifference { - public: - explicit Microseconds(const TimeDifference& difference) : - TimeDifference(difference, kScale) { } - - Microseconds(int64_t micros) : TimeDifference( - micros / 1000000, (micros % 1000000) * kScale, kScale) { } - - protected: - static const int kScale = kNanosecondsPerSecond / 1000000; -}; - -class Nanoseconds : public TimeDifference { - public: - explicit Nanoseconds(const TimeDifference& difference) : - TimeDifference(difference, 1) { } - Nanoseconds(int64_t ns) : TimeDifference(ns / kNanosecondsPerSecond, - ns % kNanosecondsPerSecond, 1) { } -}; - -} // namespace time -} // namespace cvd - -/** - * Legacy support for microseconds. Use MonotonicTimePoint in new code. - */ -static const int64_t kSecsToUsecs = static_cast<int64_t>(1000) * 1000; - -static inline int64_t get_monotonic_usecs() { - return cvd::time::Microseconds( - cvd::time::MonotonicTimePoint::Now().SinceEpoch()).count(); -} diff --git a/common/libs/time/monotonic_time_test.cpp b/common/libs/time/monotonic_time_test.cpp deleted file mode 100644 index b1c07c92..00000000 --- a/common/libs/time/monotonic_time_test.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/time/monotonic_time.h" - -#include <gtest/gtest.h> -#include <algorithm> - -using cvd::time::TimeDifference; - -class MonotonicTimeTest : public ::testing::Test { - public: - MonotonicTimeTest() {} -}; - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd1) { - TimeDifference td1(1, 10, 1); - TimeDifference td2(0, 100, 1); - EXPECT_EQ((td1+td2).count(), (1)*1000000000 + 110); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd2) { - TimeDifference td1(10, 1000, 1); - TimeDifference td2(100, 10000, 1); - EXPECT_EQ((td1+td2).count(), (110L)*1000000000L + 11000L); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd3) { - int64_t scale = 1000; - TimeDifference td1(10, 1000, scale); - TimeDifference td2(100, 10000, scale); - EXPECT_EQ((td1+td2).count(), ((110L)*1000000000L + 11000L)/scale); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd4) { - int64_t scale = 1; - TimeDifference td1(-10, 1000, scale); - TimeDifference td2(100, 10000, scale); - EXPECT_EQ((td1+td2).count(), ((90L)*1000000000L + 11000L)/scale); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd5) { - int64_t scale1 = 1, scale2 = 1000; - TimeDifference td1(-10, 1000, scale1); - TimeDifference td2(100, 10000, scale2); - EXPECT_EQ((td1+td2).count(), ((90L)*1000000000L + 11000L)/std::min(scale1, scale2)); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceAdd6) { - int64_t scale1 = 1000, scale2 = 1000; - TimeDifference td1(0, 995, scale1); - TimeDifference td2(0, 10, scale2); - EXPECT_EQ((td1+td2).count(), (1005L)/std::min(scale1, scale2)); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceSub1) { - int64_t scale = 1; - TimeDifference td1(10, 1000, scale); - TimeDifference td2(100, 10000, scale); - EXPECT_EQ((td2-td1).count(), ((90L)*1000000000L + 9000L)/scale); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceSub2) { - int64_t scale = 1; - TimeDifference td1(10, 1000, scale); - TimeDifference td2(100, 10000, scale); - EXPECT_EQ((td1-td2).count(), ((-91L)*1000000000L + 1000000000L - 9000L)/scale); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceSub3) { - int64_t scale1 = 1, scale2 = 1000; - TimeDifference td1(-10, 1000, scale1); - TimeDifference td2(100, 10000, scale2); - EXPECT_EQ((td1-td2).count(), ((-111L)*1000000000L + 1000000000L - 9000L)/std::min(scale1, scale2)); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceSub4) { - int64_t scale1 = 1000, scale2 = 1000; - TimeDifference td1(0, 995, scale1); - TimeDifference td2(0, 10, scale2); - EXPECT_EQ((td1-td2).count(), (985L)/std::min(scale1, scale2)); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceComp1) { - int64_t scale = 1; - TimeDifference td1(10, 10000, scale); - TimeDifference td2(100, 10, scale); - EXPECT_TRUE((td1 < td2)); - EXPECT_FALSE(td2 < td1); -} - -TEST_F(MonotonicTimeTest, TimeDifferenceComp2) { - int64_t scale = 1; - TimeDifference td1(100, 10000, scale); - TimeDifference td2(100, 10, scale); - EXPECT_TRUE((td2 < td1)); - EXPECT_FALSE(td1 < td2); -} diff --git a/common/libs/usbforward/protocol.h b/common/libs/usbforward/protocol.h deleted file mode 100644 index c55c3b6f..00000000 --- a/common/libs/usbforward/protocol.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> - -namespace usb_forward { - -// Commands that can be executed over serial port. -// Use magic value to avoid accidental interpretation of commonly seen numbers. -enum Command : uint32_t { - // Get device list. - // Request format: - // - RequestHeader{} - // Response format: - // - ResponseHeader{} - // - int32_t(num_devices) - // - num_devices times: - // - DeviceInfo{} - // - DeviceInfo.num_interfaces times: - // - InterfaceInfo{} - CmdDeviceList = 0xcfad0001, - - // Attach specified device. - // Request format: - // - RequestHeader{} - // - AttachRequestHeader{} - // Response format: - // - ResponseHeader{} - CmdAttach, - - // Execute command on attached USB device. - // Request format: - // - RequestHeader{} - // - ControlTransfer{} - // - if transfer direction is host -> device - // - uint8_t[ControlTransfer.length] data - // Response format: - // - ResponseHeader{} - // - if transfer direction is device -> host - // - int32_t(actual length) - // - uint8_t[actual length] bytes - CmdControlTransfer, - - // Execute transfer on attached USB device. - // Request format: - // - RequestHeader{} - // - DataTransfer{} - // - if transfer direction is host -> device - // - uint8_t[DataTransfer.length] data - // Response format: - // - ResponseHeader{} - // - if transfer direction is host -> device - // - int32_t(actual length) - // - int32_t[actual length] bytes - CmdDataTransfer, - - // Heartbeat is used to detect whether device is alive. - // This is a trivial request/response mechanism. - // Response status indicates whether server is ready. - // Request format: - // - RequestHeader{} - // Response format: - // - ResponseHeader{} - CmdHeartbeat, -}; - -// Status represents command execution result, using USB/IP compatible values. -enum Status : uint32_t { - // StatusSuccess indicates successful command execution. - StatusSuccess = 0, - - // StatusFailure indicates error during command execution. - StatusFailure = 1 -}; - -struct RequestHeader { - Command command; - uint32_t tag; -}; - -struct ResponseHeader { - Status status; - uint32_t tag; -}; - -// DeviceInfo describes individual USB device that was found attached to the -// bus. -struct DeviceInfo { - uint16_t vendor_id; - uint16_t product_id; - uint16_t dev_version; - uint8_t dev_class; - uint8_t dev_subclass; - uint8_t dev_protocol; - uint8_t bus_id; - uint8_t dev_id; - uint8_t speed; - uint8_t num_configurations; - uint8_t num_interfaces; - uint8_t cur_configuration; -} __attribute__((packed)); - -// InterfaceInfo describes individual interface attached to a USB device. -struct InterfaceInfo { - uint8_t if_class; - uint8_t if_subclass; - uint8_t if_protocol; - uint8_t if_reserved; -} __attribute__((packed)); - -// AttachRequest specifies which device on which bus needs to be attached. -struct AttachRequest { - uint8_t bus_id; - uint8_t dev_id; -} __attribute__((packed)); - -// ControlTransfer specifies target bus and device along with USB request. -struct ControlTransfer { - uint8_t bus_id; - uint8_t dev_id; - uint8_t type; - uint8_t cmd; - uint16_t value; - uint16_t index; - uint16_t length; - uint32_t timeout; -} __attribute__((packed)); - -// DataTransfer is used to exchange data between host and device. -struct DataTransfer { - uint8_t bus_id; - uint8_t dev_id; - uint8_t endpoint_id; - uint8_t is_host_to_device; - int32_t length; - uint32_t timeout; -} __attribute__((packed)); - -} // namespace usb_forward diff --git a/common/libs/utils/Android.bp b/common/libs/utils/Android.bp deleted file mode 100644 index 7330315d..00000000 --- a/common/libs/utils/Android.bp +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_library { - name: "libcuttlefish_utils", - srcs: [ - "archive.cpp", - "subprocess.cpp", - "environment.cpp", - "size_utils.cpp", - "files.cpp", - "users.cpp", - "network.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared: { - shared_libs: [ - "libbase", - "libcuttlefish_fs", - ], - }, - static: { - static_libs: [ - "libbase", - "libcuttlefish_fs", - ], - }, - defaults: ["cuttlefish_host_and_guest"], -} - -cc_test { - name: "cuttlefish_simulated_buffer_test", - srcs: ["simulated_buffer_test.cpp"], - shared_libs: ["libcuttlefish_utils"], - gtest: true, - defaults: ["cuttlefish_host_only"], - test_suites: ["general-tests"], -} diff --git a/common/libs/utils/TEST_MAPPING b/common/libs/utils/TEST_MAPPING deleted file mode 100644 index 61de4584..00000000 --- a/common/libs/utils/TEST_MAPPING +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presubmit": [ - { - "name": "cuttlefish_simulated_buffer_test", - "host": true - } - ] -} diff --git a/common/libs/utils/archive.cpp b/common/libs/utils/archive.cpp deleted file mode 100644 index c1c496d0..00000000 --- a/common/libs/utils/archive.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/archive.h" - -#include <string> -#include <vector> - -#include <android-base/strings.h> -#include <glog/logging.h> - -#include "common/libs/utils/subprocess.h" - -namespace cvd { - -Archive::Archive(const std::string& file) : file(file) { -} - -Archive::~Archive() { -} - -std::vector<std::string> Archive::Contents() { - cvd::Command bsdtar_cmd("/usr/bin/bsdtar"); - bsdtar_cmd.AddParameter("-tf"); - bsdtar_cmd.AddParameter(file); - std::string bsdtar_input, bsdtar_output; - auto bsdtar_ret = cvd::RunWithManagedStdio(std::move(bsdtar_cmd), &bsdtar_input, - &bsdtar_output, nullptr); - if (bsdtar_ret != 0) { - LOG(ERROR) << "`bsdtar -tf \"" << file << "\"` returned " << bsdtar_ret; - } - return bsdtar_ret == 0 - ? android::base::Split(bsdtar_output, "\n") - : std::vector<std::string>(); -} - -bool Archive::ExtractAll(const std::string& target_directory) { - return ExtractFiles({}, target_directory); -} - -bool Archive::ExtractFiles(const std::vector<std::string>& to_extract, - const std::string& target_directory) { - cvd::Command bsdtar_cmd("/usr/bin/bsdtar"); - bsdtar_cmd.AddParameter("-x"); - bsdtar_cmd.AddParameter("-v"); - bsdtar_cmd.AddParameter("-C"); - bsdtar_cmd.AddParameter(target_directory); - bsdtar_cmd.AddParameter("-f"); - bsdtar_cmd.AddParameter(file); - bsdtar_cmd.AddParameter("-S"); - for (const auto& extract : to_extract) { - bsdtar_cmd.AddParameter(extract); - } - bsdtar_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, - cvd::Subprocess::StdIOChannel::kStdErr); - auto bsdtar_ret = bsdtar_cmd.Start().Wait(); - if (bsdtar_ret != 0) { - LOG(ERROR) << "bsdtar extraction on \"" << file << "\" returned " << bsdtar_ret; - } - return bsdtar_ret == 0; -} - -} // namespace cvd diff --git a/common/libs/utils/archive.h b/common/libs/utils/archive.h deleted file mode 100644 index fae9288f..00000000 --- a/common/libs/utils/archive.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> -#include <vector> - -namespace cvd { - -// Operations on archive files -class Archive { - std::string file; -public: - Archive(const std::string& file); - ~Archive(); - - std::vector<std::string> Contents(); - bool ExtractAll(const std::string& target_directory = "."); - bool ExtractFiles(const std::vector<std::string>& files, - const std::string& target_directory = "."); -}; - -} // namespace cvd diff --git a/common/libs/utils/environment.cpp b/common/libs/utils/environment.cpp deleted file mode 100644 index 11a0b8c1..00000000 --- a/common/libs/utils/environment.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/environment.h" - -#include <stdlib.h> - -namespace cvd { - -std::string StringFromEnv(const std::string& varname, - const std::string& defval) { - const char* const valstr = getenv(varname.c_str()); - if (!valstr) { - return defval; - } - return valstr; -} - -} // namespace cvd diff --git a/common/libs/utils/environment.h b/common/libs/utils/environment.h deleted file mode 100644 index 1aab8de7..00000000 --- a/common/libs/utils/environment.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> - -namespace cvd { - -std::string StringFromEnv(const std::string& varname, - const std::string& defval); - -} // namespace cvd diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp deleted file mode 100644 index 3d0ba067..00000000 --- a/common/libs/utils/files.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/files.h" - -#include <glog/logging.h> - -#include <array> -#include <climits> -#include <cstdio> -#include <cstdlib> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -namespace cvd { - -bool FileExists(const std::string& path) { - struct stat st; - return stat(path.c_str(), &st) == 0; -} - -bool FileHasContent(const std::string& path) { - return FileSize(path) > 0; -} - -bool DirectoryExists(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) == -1) { - return false; - } - if ((st.st_mode & S_IFMT) != S_IFDIR) { - return false; - } - return true; -} - -std::string AbsolutePath(const std::string& path) { - if (path.empty()) { - return {}; - } - if (path[0] == '/') { - return path; - } - - std::array<char, PATH_MAX> buffer{}; - if (!realpath(".", buffer.data())) { - LOG(WARNING) << "Could not get real path for current directory \".\"" - << ": " << strerror(errno); - return {}; - } - return std::string{buffer.data()} + "/" + path; -} - -off_t FileSize(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) == -1) { - return 0; - } - return st.st_size; -} - -// TODO(schuffelen): Use std::filesystem::last_write_time when on C++17 -std::chrono::system_clock::time_point FileModificationTime(const std::string& path) { - struct stat st; - if (stat(path.c_str(), &st) == -1) { - return std::chrono::system_clock::time_point(); - } - std::chrono::seconds seconds(st.st_mtim.tv_sec); - return std::chrono::system_clock::time_point(seconds); -} - -bool RemoveFile(const std::string& file) { - LOG(INFO) << "Removing " << file; - return remove(file.c_str()) == 0; -} - -std::string CurrentDirectory() { - char* path = getcwd(nullptr, 0); - std::string ret(path); - free(path); - return ret; -} - -} // namespace cvd diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h deleted file mode 100644 index d42edc5e..00000000 --- a/common/libs/utils/files.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <sys/types.h> - -#include <chrono> -#include <string> - -namespace cvd { -bool FileExists(const std::string& path); -bool FileHasContent(const std::string& path); -bool DirectoryExists(const std::string& path); -off_t FileSize(const std::string& path); -bool RemoveFile(const std::string& file); -std::chrono::system_clock::time_point FileModificationTime(const std::string& path); - -// The returned value may contain .. or . if these are present in the path -// argument. -// path must not contain ~ -std::string AbsolutePath(const std::string& path); - -std::string CurrentDirectory(); -} // namespace cvd diff --git a/common/libs/utils/network.cpp b/common/libs/utils/network.cpp deleted file mode 100644 index f4943ed9..00000000 --- a/common/libs/utils/network.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/network.h" - -#include <linux/if.h> -#include <linux/if_tun.h> -#include <string.h> - -#include "common/libs/glog/logging.h" - -namespace cvd { -namespace { -// This should be the size of virtio_net_hdr_v1, from linux/virtio_net.h, but -// the version of that header that ships with android in Pie does not include -// that struct (it was added in Q). -// This is what that struct looks like: -// struct virtio_net_hdr_v1 { -// u8 flags; -// u8 gso_type; -// u16 hdr_len; -// u16 gso_size; -// u16 csum_start; -// u16 csum_offset; -// u16 num_buffers; -// }; -static constexpr int SIZE_OF_VIRTIO_NET_HDR_V1 = 12; -} // namespace - -SharedFD OpenTapInterface(const std::string& interface_name) { - constexpr auto TUNTAP_DEV = "/dev/net/tun"; - - auto tap_fd = SharedFD::Open(TUNTAP_DEV, O_RDWR | O_NONBLOCK); - if (!tap_fd->IsOpen()) { - LOG(ERROR) << "Unable to open tun device: " << tap_fd->StrError(); - return tap_fd; - } - - struct ifreq ifr; - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; - strncpy(ifr.ifr_name, interface_name.c_str(), IFNAMSIZ); - - int err = tap_fd->Ioctl(TUNSETIFF, &ifr); - if (err < 0) { - LOG(ERROR) << "Unable to connect to " << interface_name - << " tap interface: " << tap_fd->StrError(); - tap_fd->Close(); - return cvd::SharedFD(); - } - - // The interface's configuration may have been modified or just not set - // correctly on creation. While qemu checks this and enforces the right - // configuration, crosvm does not, so it needs to be set before it's passed to - // it. - tap_fd->Ioctl(TUNSETOFFLOAD, - reinterpret_cast<void*>(TUN_F_CSUM | TUN_F_UFO | TUN_F_TSO4 | - TUN_F_TSO6)); - int len = SIZE_OF_VIRTIO_NET_HDR_V1; - tap_fd->Ioctl(TUNSETVNETHDRSZ, &len); - - return tap_fd; -} -} // namespace cvd diff --git a/common/libs/utils/network.h b/common/libs/utils/network.h deleted file mode 100644 index 7b856e4d..00000000 --- a/common/libs/utils/network.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> - -#include "common/libs/fs/shared_fd.h" - -namespace cvd { -// Creates, or connects to if it already exists, a tap network interface. The -// user needs CAP_NET_ADMIN to create such interfaces or be the owner to connect -// to one. -SharedFD OpenTapInterface(const std::string& interface_name); -}
\ No newline at end of file diff --git a/common/libs/utils/simulated_buffer.h b/common/libs/utils/simulated_buffer.h deleted file mode 100644 index a61108d4..00000000 --- a/common/libs/utils/simulated_buffer.h +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> -#include <unistd.h> -#include <time.h> - -#include "common/libs/time/monotonic_time.h" - -/** - * This abstract class simulates a buffer that either fills or empties at - * a specified rate. - * - * The simulated buffer automatically fills or empties at a specific rate. - * - * An item is the thing contained in the simulated buffer. Items are moved - * in and out of the buffer without subdivision. - * - * An integral number of items must arrive / depart in each second. - * This number is stored in items_per_second_ - * - * items_per_second * 2000000000 must fit within an int64_t. This - * works if items_per_second is represented by an int32. - * - * The base class does have the concept of capacity, but doesn't use it. - * It is included here to simplify unit testing. - * - * For actual use, see SimulatedInputBuffer and SimulatedOutputBuffer below. - */ -class SimulatedBufferBase { - public: - static inline int64_t divide_and_round_up(int64_t q, int64_t d) { - return q / d + ((q % d) != 0); - } - - SimulatedBufferBase( - int32_t items_per_second, - int64_t simulated_item_capacity, - cvd::time::MonotonicTimePointFactory* clock = - cvd::time::MonotonicTimePointFactory::GetInstance()) : - clock_(clock), - current_item_num_(0), - base_item_num_(0), - simulated_item_capacity_(simulated_item_capacity), - items_per_second_(items_per_second), - initialize_(true), - paused_(false) { } - - virtual ~SimulatedBufferBase() { } - - int64_t GetCurrentItemNum() { - Update(); - return current_item_num_; - } - - const cvd::time::MonotonicTimePoint GetLastUpdatedTime() const { - return current_time_; - } - - // Sleep for the given amount of time. Subclasses may override this to use - // different sleep calls. - // Sleep is best-effort. The code assumes that the acutal sleep time may be - // greater or less than the time requested. - virtual void SleepUntilTime(const cvd::time::MonotonicTimePoint& in) { - struct timespec ts; - in.ToTimespec(&ts); - clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL); - } - - // The time counter may not start at 0. Concrete classes should call this - // to allow the buffer simulation to read the current time number and - // initialize its internal state. - virtual void Init() { - if (initialize_) { - clock_->FetchCurrentTime(&base_time_); - current_time_ = base_time_; - initialize_ = false; - } - } - - virtual void Update() { - if (initialize_) { - Init(); - } - cvd::time::MonotonicTimePoint now; - clock_->FetchCurrentTime(&now); - // We can't call FetchCurrentTime() in the constuctor because a subclass may - // want to override it, so we initialze the times to 0. If we detect this - // case go ahead and initialize to a current timestamp. - if (paused_) { - base_time_ += now - current_time_; - current_time_ = now; - return; - } - // Avoid potential overflow by limiting the scaling to one time second. - // There is no round-off error here because the bases are adjusted for full - // seconds. - // There is no issue with int64 overflow because 2's compliment subtraction - // is immune to overflow. - // However, this does assume that kNanosecondsPerSecond * items_per_second_ - // fits in an int64. - cvd::time::Seconds seconds(now - base_time_); - base_time_ += seconds; - base_item_num_ += seconds.count() * items_per_second_; - current_time_ = now; - current_item_num_ = - cvd::time::Nanoseconds(now - base_time_).count() * - items_per_second_ / cvd::time::kNanosecondsPerSecond + - base_item_num_; - } - - // If set to true new items will not be created. - bool SetPaused(bool new_state) { - bool rval = paused_; - Update(); - paused_ = new_state; - return rval; - } - - // Calculate the TimePoint that corresponds to an item. - // Caution: This may not return a correct time for items in the past. - cvd::time::MonotonicTimePoint CalculateItemTime(int64_t item) { - int64_t seconds = (item - base_item_num_) / items_per_second_; - int64_t new_base_item_num = base_item_num_ + seconds * items_per_second_; - return base_time_ + cvd::time::Seconds(seconds) + - cvd::time::Nanoseconds(divide_and_round_up( - (item - new_base_item_num) * - cvd::time::kNanosecondsPerSecond, - items_per_second_)); - } - - // Sleep until the given item number is generated. If the generator is - // paused unpause it to make the sleep finite. - void SleepUntilItem(int64_t item) { - if (paused_) { - SetPaused(false); - } - cvd::time::MonotonicTimePoint desired_time = - CalculateItemTime(item); - while (1) { - Update(); - if (current_item_num_ - item >= 0) { - return; - } - SleepUntilTime(desired_time); - } - } - - protected: - // Source of the timepoints. - cvd::time::MonotonicTimePointFactory* clock_; - // Time when the other values in the structure were updated. - cvd::time::MonotonicTimePoint current_time_; - // Most recent time when there was no round-off error between the clock and - // items. - cvd::time::MonotonicTimePoint base_time_; - // Number of the current item. - int64_t current_item_num_; - // Most recent item number where there was no round-off error between the - // clock and items. - int64_t base_item_num_; - // Simulated_Item_Capacity of the buffer in items. - int64_t simulated_item_capacity_; - // Number of items that are created in 1s. A typical number would be 48000. - int32_t items_per_second_; - bool initialize_; - // If true then don't generate new items. - bool paused_; -}; - -/** - * This is a simulation of an output buffer that drains at a constant rate. - */ -class SimulatedOutputBuffer : public SimulatedBufferBase { - public: - SimulatedOutputBuffer( - int64_t item_rate, - int64_t simulated_item_capacity, - cvd::time::MonotonicTimePointFactory* clock = - cvd::time::MonotonicTimePointFactory::GetInstance()) : - SimulatedBufferBase(item_rate, simulated_item_capacity, clock) { - output_buffer_item_num_ = current_item_num_; - } - - void Update() override { - SimulatedBufferBase::Update(); - if ((output_buffer_item_num_ - current_item_num_) < 0) { - // We ran out of items at some point in the past. However, the - // output capactiy can't be negative. - output_buffer_item_num_ = current_item_num_; - } - } - - int64_t AddToOutputBuffer(int64_t num_new_items, bool block) { - Update(); - // The easy case: num_new_items fit in the bucket. - if ((output_buffer_item_num_ + num_new_items - current_item_num_) <= - simulated_item_capacity_) { - output_buffer_item_num_ += num_new_items; - return num_new_items; - } - // If we're non-blocking accept enough items to fill the output. - if (!block) { - int64_t used = current_item_num_ + simulated_item_capacity_ - - output_buffer_item_num_; - output_buffer_item_num_ = current_item_num_ + simulated_item_capacity_; - return used; - } - int64_t new_output_buffer_item_num = output_buffer_item_num_ + num_new_items; - SleepUntilItem(new_output_buffer_item_num - simulated_item_capacity_); - output_buffer_item_num_ = new_output_buffer_item_num; - return num_new_items; - } - - int64_t GetNextOutputBufferItemNum() { - Update(); - return output_buffer_item_num_; - } - - cvd::time::MonotonicTimePoint GetNextOutputBufferItemTime() { - Update(); - return CalculateItemTime(output_buffer_item_num_); - } - - int64_t GetOutputBufferSize() { - Update(); - return output_buffer_item_num_ - current_item_num_; - } - - void Drain() { - SleepUntilItem(output_buffer_item_num_); - } - - protected: - int64_t output_buffer_item_num_; -}; - -/** - * Simulates an input buffer that fills at a constant rate. - */ -class SimulatedInputBuffer : public SimulatedBufferBase { - public: - SimulatedInputBuffer( - int64_t item_rate, - int64_t simulated_item_capacity, - cvd::time::MonotonicTimePointFactory* clock = - cvd::time::MonotonicTimePointFactory::GetInstance()) : - SimulatedBufferBase(item_rate, simulated_item_capacity, clock) { - input_buffer_item_num_ = current_item_num_; - lost_input_items_ = 0; - } - - void Update() override { - SimulatedBufferBase::Update(); - if ((current_item_num_ - input_buffer_item_num_) > - simulated_item_capacity_) { - // The buffer overflowed at some point in the past. Account for the lost - // times. - int64_t new_input_buffer_item_num = - current_item_num_ - simulated_item_capacity_; - lost_input_items_ += - new_input_buffer_item_num - input_buffer_item_num_; - input_buffer_item_num_ = new_input_buffer_item_num; - } - } - - int64_t RemoveFromInputBuffer(int64_t num_items_wanted, bool block) { - Update(); - if (!block) { - int64_t num_items_available = current_item_num_ - input_buffer_item_num_; - if (num_items_available < num_items_wanted) { - input_buffer_item_num_ += num_items_available; - return num_items_available; - } else { - input_buffer_item_num_ += num_items_wanted; - return num_items_wanted; - } - } - // Calculate the item number that is being claimed. Sleep until it appears. - // Advancing input_buffer_item_num_ causes a negative value to be compared - // to the capacity, effectively disabling the overflow detection code - // in Update(). - input_buffer_item_num_ += num_items_wanted; - while (input_buffer_item_num_ - current_item_num_ > 0) { - SleepUntilItem(input_buffer_item_num_); - } - return num_items_wanted; - } - - int64_t GetLostInputItems() { - Update(); - int64_t rval = lost_input_items_; - lost_input_items_ = 0; - return rval; - } - - protected: - int64_t input_buffer_item_num_; - int64_t lost_input_items_; -}; diff --git a/common/libs/utils/simulated_buffer_test.cpp b/common/libs/utils/simulated_buffer_test.cpp deleted file mode 100644 index c3fbe494..00000000 --- a/common/libs/utils/simulated_buffer_test.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "common/libs/utils/simulated_buffer.h" -#include <gtest/gtest.h> - -using cvd::time::MonotonicTimePoint; -using cvd::time::MonotonicTimePointFactory; -using cvd::time::Seconds; -using cvd::time::Milliseconds; -using cvd::time::Nanoseconds; -using cvd::time::kNanosecondsPerSecond; - -class MockTimepointFactory : public MonotonicTimePointFactory { - public: - virtual void FetchCurrentTime(MonotonicTimePoint* dest) const override { - *dest = system_time_; - } - - void SetTime(const MonotonicTimePoint& in) { - system_time_ = in; - } - - protected: - MonotonicTimePoint system_time_; -}; - -template <typename T> class MockSimulatedBuffer : public T { - public: - MockSimulatedBuffer( - int64_t sample_rate, - int64_t capacity, - MockTimepointFactory* factory) : - T(sample_rate, capacity, factory), - factory_(factory) { } - - void FetchCurrentTime(MonotonicTimePoint* dest) const { - return factory_->FetchCurrentTime(dest); - } - - void SleepUntilTime(const MonotonicTimePoint& tick) { - factory_->SetTime(tick); - } - - protected: - // Save a redundant pointer to avoid downcasting - MockTimepointFactory* factory_; -}; - -static const int64_t kItemRate = 48000; -static const int64_t kBufferCapacity = 4800; - -class SimulatedBufferTest : public ::testing::Test { - public: - MockTimepointFactory clock; - MockSimulatedBuffer<SimulatedBufferBase> buffer; - - SimulatedBufferTest() : buffer(kItemRate, kBufferCapacity, &clock) { } -}; - -TEST_F(SimulatedBufferTest, TimeMocking) { - // Ensure that the mocked clock starts at the epoch. - MonotonicTimePoint epoch_time; - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(epoch_time, actual_time); - - // Ensure that sleeping works - MonotonicTimePoint test_time = actual_time + Seconds(10); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - - // Try one more sleep to make sure that time moves forward - test_time += Seconds(5); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); -} - -TEST_F(SimulatedBufferTest, ItemScaling) { - // Make certain that we start at item 0 - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - - // Make certain that the expected number of items appear in 1 second - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - MonotonicTimePoint test_time = actual_time + Seconds(1); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(kItemRate, buffer.GetCurrentItemNum()); - - // Sleep an additional 10 seconds to make certain that the item numbers - // increment - test_time += Seconds(10); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(11 * kItemRate, buffer.GetCurrentItemNum()); - - // Make certain that partial seconds work - test_time += Milliseconds(1500); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(12.5 * kItemRate, buffer.GetCurrentItemNum()); - - // Make certain that we don't get new items when paused - buffer.SetPaused(true); - test_time += Seconds(10); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(12.5 * kItemRate, buffer.GetCurrentItemNum()); - - // Make certain that we start getting items when pausing stops - buffer.SetPaused(false); - test_time += Milliseconds(500); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(13 * kItemRate, buffer.GetCurrentItemNum()); -} - -TEST_F(SimulatedBufferTest, ItemSleeping) { - // See if sleeping on an time causes the right amount of time to pass - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - MonotonicTimePoint base_time; - buffer.FetchCurrentTime(&base_time); - - // Wait for 1500ms worth of samples - buffer.SleepUntilItem(kItemRate * 1500 / 1000); - EXPECT_EQ(kItemRate * 1500 / 1000, buffer.GetCurrentItemNum()); - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(1500, Milliseconds(actual_time - base_time).count()); - - // Now wait again for more samples - buffer.SleepUntilItem(kItemRate * 2500 / 1000); - EXPECT_EQ(kItemRate * 2500 / 1000, buffer.GetCurrentItemNum()); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(2500, Milliseconds(actual_time - base_time).count()); -} - -class OutputBufferTest : public ::testing::Test { - public: - MockTimepointFactory clock; - MockSimulatedBuffer<SimulatedOutputBuffer> buffer; - - OutputBufferTest() : buffer(kItemRate, kBufferCapacity, &clock) { } -}; - -TEST_F(OutputBufferTest, NonBlockingQueueing) { - int64_t half_buffer = kBufferCapacity / 2; - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - - // Filling half of the buffer should not block - MonotonicTimePoint test_time; - buffer.FetchCurrentTime(&test_time); - EXPECT_EQ(half_buffer, buffer.AddToOutputBuffer(half_buffer, false)); - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(half_buffer, buffer.GetOutputBufferSize()); - - // Filling all but one entry of the buffer should not block - EXPECT_EQ(half_buffer - 1, - buffer.AddToOutputBuffer(half_buffer - 1, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity - 1, buffer.GetOutputBufferSize()); - - // Filling the entire buffer should not block - EXPECT_EQ(1, buffer.AddToOutputBuffer(half_buffer, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(actual_time, test_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // The buffer should reject additional data but not block - EXPECT_EQ(0, buffer.AddToOutputBuffer(half_buffer, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // One quarter of the buffer should drain in the expected time - Nanoseconds quarter_drain_time( - kBufferCapacity / 4 * kNanosecondsPerSecond / kItemRate); - test_time += quarter_drain_time; - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(actual_time, test_time); - EXPECT_EQ(kBufferCapacity * 3 / 4, buffer.GetOutputBufferSize()); - - // The buffer should now accept new data without blocking - EXPECT_EQ(kBufferCapacity / 4, - buffer.AddToOutputBuffer(half_buffer, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // Now that the buffer is full it should reject additional data but - // not block - EXPECT_EQ(0, buffer.AddToOutputBuffer(half_buffer, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // Wait for 3/4 of the buffer to drain - test_time += Nanoseconds(3 * quarter_drain_time.count()); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity / 4, buffer.GetOutputBufferSize()); - - // The entire buffer should drain on schedule - test_time += Nanoseconds(quarter_drain_time.count() - 1); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(1, buffer.GetOutputBufferSize()); - test_time += Nanoseconds(1); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetOutputBufferSize()); - - // It should be possible to fill the buffer in a single shot - EXPECT_EQ(kBufferCapacity, - buffer.AddToOutputBuffer(kBufferCapacity, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // The buffer shouldn't accept additional data but shouldn't block - EXPECT_EQ(0, buffer.AddToOutputBuffer(1, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // The buffer should underflow sanely - test_time += Nanoseconds(6 * quarter_drain_time.count()); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetOutputBufferSize()); - - // The underflow shouldn't increase the buffer's capacity - EXPECT_EQ(kBufferCapacity, - buffer.AddToOutputBuffer(kBufferCapacity + 1, false)); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); -} - -TEST_F(OutputBufferTest, BlockingQueueing) { - int64_t half_buffer = kBufferCapacity / 2; - - // Check the initial setup - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - MonotonicTimePoint test_time; - buffer.FetchCurrentTime(&test_time); - - // Filling half the buffer works without blocking - EXPECT_EQ(half_buffer, buffer.AddToOutputBuffer(half_buffer, true)); - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(half_buffer, buffer.GetOutputBufferSize()); - - // Filling all but one entry of the buffer also works without blocking - EXPECT_EQ(half_buffer - 1, - buffer.AddToOutputBuffer(half_buffer - 1, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity - 1, buffer.GetOutputBufferSize()); - - // Putting the last sample into the buffer doesn't block - EXPECT_EQ(1, buffer.AddToOutputBuffer(1, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // Putting more data into the buffer causes blocking - EXPECT_EQ(half_buffer, buffer.AddToOutputBuffer(half_buffer, true)); - Nanoseconds half_drain_time( - ((kBufferCapacity / 2) * kNanosecondsPerSecond + kItemRate - 1) / - kItemRate); - Nanoseconds quarter_drain_time(half_drain_time.count() / 2); - test_time += half_drain_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // The buffer drains as expected - test_time += quarter_drain_time; - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity * 3 / 4, buffer.GetOutputBufferSize()); - - // Overfilling the drained buffer also causes blocking - EXPECT_EQ(half_buffer, buffer.AddToOutputBuffer(half_buffer, true)); - test_time += quarter_drain_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // The buffer drains on schedule - test_time += Nanoseconds(half_drain_time.count() * 2 - 1); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(1, buffer.GetOutputBufferSize()); - test_time += Nanoseconds(1); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetOutputBufferSize()); - - // It's possible to fill the entire output buffer in 1 shot without blocking - EXPECT_EQ(kBufferCapacity, - buffer.AddToOutputBuffer(kBufferCapacity, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); - - // Adding a single extra sample causes some blocking - EXPECT_EQ(1, buffer.AddToOutputBuffer(1, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_LT(test_time, actual_time); - EXPECT_EQ(kBufferCapacity, buffer.GetOutputBufferSize()); -} - -class InputBufferTest : public ::testing::Test { - public: - MockTimepointFactory clock; - MockSimulatedBuffer<SimulatedInputBuffer> buffer; - - InputBufferTest() : buffer(kItemRate, kBufferCapacity, &clock) { } -}; - -TEST_F(InputBufferTest, NonBlockingInput) { - Nanoseconds quarter_fill_time(kBufferCapacity / 4 * kNanosecondsPerSecond / - kItemRate); - // Verify that the buffer starts empty - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(0, buffer.RemoveFromInputBuffer(kBufferCapacity, false)); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Wait for 1/4 of the buffer to fill - MonotonicTimePoint test_time = actual_time + quarter_fill_time; - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Verify that we can read the samples in two groups - EXPECT_EQ(kBufferCapacity / 8, - buffer.RemoveFromInputBuffer(kBufferCapacity / 8, false)); - EXPECT_EQ(kBufferCapacity / 8, - buffer.RemoveFromInputBuffer(kBufferCapacity, false)); - - // Verify that there are no samples left and that we did not block - EXPECT_EQ(0, buffer.RemoveFromInputBuffer(kBufferCapacity, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - - // Verify that the buffer fills on schedule - test_time += Nanoseconds(4 * quarter_fill_time.count() - 1); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(kBufferCapacity - 1, - buffer.RemoveFromInputBuffer(kBufferCapacity, false)); - test_time += Nanoseconds(1); - buffer.SleepUntilTime(test_time); - EXPECT_EQ(1, buffer.RemoveFromInputBuffer(kBufferCapacity, false)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Verify that the buffer overflows as expected - test_time += Nanoseconds(5 * quarter_fill_time.count()); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity / 4, buffer.GetLostInputItems()); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - EXPECT_EQ(kBufferCapacity, - buffer.RemoveFromInputBuffer(2 * kBufferCapacity, false)); - EXPECT_EQ(0, buffer.RemoveFromInputBuffer(kBufferCapacity, false)); -} - -TEST_F(InputBufferTest, BlockingInput) { - Nanoseconds quarter_fill_time(kBufferCapacity / 4 * kNanosecondsPerSecond / - kItemRate); - // Verify that the buffer starts empty - EXPECT_EQ(0, buffer.GetCurrentItemNum()); - MonotonicTimePoint actual_time; - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Wait for 1/4 of the buffer to fill - MonotonicTimePoint test_time = actual_time + quarter_fill_time; - EXPECT_EQ(kBufferCapacity / 4, - buffer.RemoveFromInputBuffer(kBufferCapacity / 4, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Verify that the buffer fills on schedule - test_time += Nanoseconds(4 * quarter_fill_time.count()); - EXPECT_EQ(kBufferCapacity, - buffer.RemoveFromInputBuffer(kBufferCapacity, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(0, buffer.GetLostInputItems()); - - // Verify that the buffer overflows as expected - test_time += Nanoseconds(5 * quarter_fill_time.count()); - buffer.SleepUntilTime(test_time); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - EXPECT_EQ(kBufferCapacity / 4, buffer.GetLostInputItems()); - EXPECT_EQ(0, buffer.GetLostInputItems()); - EXPECT_EQ(kBufferCapacity, - buffer.RemoveFromInputBuffer(kBufferCapacity, true)); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); - - // Verify that reads bigger than the buffer work as expected - test_time += Nanoseconds(8 * quarter_fill_time.count()); - EXPECT_EQ(kBufferCapacity * 2, - buffer.RemoveFromInputBuffer(kBufferCapacity * 2, true)); - EXPECT_EQ(0, buffer.GetLostInputItems()); - buffer.FetchCurrentTime(&actual_time); - EXPECT_EQ(test_time, actual_time); -} diff --git a/common/libs/utils/size_utils.cpp b/common/libs/utils/size_utils.cpp deleted file mode 100644 index c43bf960..00000000 --- a/common/libs/utils/size_utils.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/size_utils.h" - -#include <unistd.h> - -namespace cvd { - -uint32_t AlignToPageSize(uint32_t val) { - static uint32_t page_size = sysconf(_SC_PAGESIZE); - return ((val + (page_size - 1)) / page_size) * page_size; -} - -uint32_t RoundUpToNextPowerOf2(uint32_t val) { - uint32_t power_of_2 = 1; - while (power_of_2 < val) { - power_of_2 *= 2; - } - return power_of_2; -} - -uint32_t AlignToPowerOf2(uint32_t val, uint8_t align_log) { - uint32_t align = 1 << align_log; - return ((val + (align - 1)) / align) * align; -} - -} // namespace cvd diff --git a/common/libs/utils/size_utils.h b/common/libs/utils/size_utils.h deleted file mode 100644 index 1d344930..00000000 --- a/common/libs/utils/size_utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> - -namespace cvd { - -// Returns the smallest multiple of PAGE_SIZE greater than or equal to val. -uint32_t AlignToPageSize(uint32_t val); - -// Returns the smallest power of two greater than or equal to val. -uint32_t RoundUpToNextPowerOf2(uint32_t val); - -// Returns the smallest multiple of 2^align_log greater than or equal to val. -uint32_t AlignToPowerOf2(uint32_t val, uint8_t align_log); - -} // namespace cvd diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp deleted file mode 100644 index e83b4870..00000000 --- a/common/libs/utils/subprocess.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/subprocess.h" - -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <map> -#include <set> -#include <thread> - -#include <glog/logging.h> - -#include "common/libs/fs/shared_buf.h" - -namespace { - -// If a redirected-to file descriptor was already closed, it's possible that -// some inherited file descriptor duped to this file descriptor and the redirect -// would override that. This function makes sure that doesn't happen. -bool validate_redirects( - const std::map<cvd::Subprocess::StdIOChannel, int>& redirects, - const std::map<cvd::SharedFD, int>& inherited_fds) { - // Add the redirected IO channels to a set as integers. This allows converting - // the enum values into integers instead of the other way around. - std::set<int> int_redirects; - for (const auto& entry : redirects) { - int_redirects.insert(static_cast<int>(entry.first)); - } - for (const auto& entry : inherited_fds) { - auto dupped_fd = entry.second; - if (int_redirects.count(dupped_fd)) { - LOG(ERROR) << "Requested redirect of fd(" << dupped_fd - << ") conflicts with inherited FD."; - return false; - } - } - return true; -} - -void do_redirects( - const std::map<cvd::Subprocess::StdIOChannel, int>& redirects) { - for (const auto& entry : redirects) { - auto std_channel = static_cast<int>(entry.first); - auto fd = entry.second; - TEMP_FAILURE_RETRY(dup2(fd, std_channel)); - } -} - -cvd::Subprocess subprocess_impl( - const char* const* command, const char* const* envp, - const std::map<cvd::Subprocess::StdIOChannel, int>& redirects, - const std::map<cvd::SharedFD, int>& inherited_fds, bool with_control_socket, - cvd::SubprocessStopper stopper, bool in_group = false, bool verbose = false) { - // The parent socket will get closed on the child on the call to exec, the - // child socket will be closed on the parent when this function returns and no - // references to the fd are left - cvd::SharedFD parent_socket, child_socket; - if (with_control_socket) { - if (!cvd::SharedFD::SocketPair(AF_LOCAL, SOCK_STREAM, 0, &parent_socket, - &child_socket)) { - LOG(ERROR) << "Unable to create control socket pair: " << strerror(errno); - return cvd::Subprocess(-1, {}); - } - // Remove FD_CLOEXEC from the child socket, ensure the parent has it - child_socket->Fcntl(F_SETFD, 0); - parent_socket->Fcntl(F_SETFD, FD_CLOEXEC); - } - - if (!validate_redirects(redirects, inherited_fds)) { - return cvd::Subprocess(-1, {}); - } - - pid_t pid = fork(); - if (!pid) { - do_redirects(redirects); - if (in_group) { - // This call should never fail (see SETPGID(2)) - if (setpgid(0, 0) != 0) { - auto error = errno; - LOG(ERROR) << "setpgid failed (" << strerror(error) << ")"; - } - } - for (const auto& entry : inherited_fds) { - if (fcntl(entry.second, F_SETFD, 0)) { - int error_num = errno; - LOG(ERROR) << "fcntl failed: " << strerror(error_num); - } - } - int rval; - // If envp is NULL, the current process's environment is used as the - // environment of the child process. To force an empty emvironment for - // the child process pass the address of a pointer to NULL - if (envp == NULL) { - rval = execv(command[0], const_cast<char* const*>(command)); - } else { - rval = execve(command[0], const_cast<char* const*>(command), - const_cast<char* const*>(envp)); - } - // No need for an if: if exec worked it wouldn't have returned - LOG(ERROR) << "exec of " << command[0] << " failed (" << strerror(errno) - << ")"; - exit(rval); - } - if (pid == -1) { - LOG(ERROR) << "fork failed (" << strerror(errno) << ")"; - } - if (verbose) { - LOG(INFO) << "Started (pid: " << pid << "): " << command[0]; - int i = 1; - while (command[i]) { - LOG(INFO) << command[i++]; - } - } - return cvd::Subprocess(pid, parent_socket, stopper); -} - -std::vector<const char*> ToCharPointers(const std::vector<std::string>& vect) { - std::vector<const char*> ret = {}; - for (const auto& str : vect) { - ret.push_back(str.c_str()); - } - ret.push_back(NULL); - return ret; -} -} // namespace -namespace cvd { - -Subprocess::Subprocess(Subprocess&& subprocess) - : pid_(subprocess.pid_), - started_(subprocess.started_), - control_socket_(subprocess.control_socket_), - stopper_(subprocess.stopper_) { - // Make sure the moved object no longer controls this subprocess - subprocess.pid_ = -1; - subprocess.started_ = false; - subprocess.control_socket_ = SharedFD(); -} - -Subprocess& Subprocess::operator=(Subprocess&& other) { - pid_ = other.pid_; - started_ = other.started_; - control_socket_ = other.control_socket_; - stopper_ = other.stopper_; - - other.pid_ = -1; - other.started_ = false; - other.control_socket_ = SharedFD(); - return *this; -} - -int Subprocess::Wait() { - if (pid_ < 0) { - LOG(ERROR) - << "Attempt to wait on invalid pid(has it been waited on already?): " - << pid_; - return -1; - } - int wstatus = 0; - auto pid = pid_; // Wait will set pid_ to -1 after waiting - auto wait_ret = Wait(&wstatus, 0); - if (wait_ret < 0) { - auto error = errno; - LOG(ERROR) << "Error on call to waitpid: " << strerror(error); - return wait_ret; - } - int retval = 0; - if (WIFEXITED(wstatus)) { - retval = WEXITSTATUS(wstatus); - if (retval) { - LOG(ERROR) << "Subprocess " << pid - << " exited with error code: " << retval; - } - } else if (WIFSIGNALED(wstatus)) { - LOG(ERROR) << "Subprocess " << pid - << " was interrupted by a signal: " << WTERMSIG(wstatus); - retval = -1; - } - return retval; -} -pid_t Subprocess::Wait(int* wstatus, int options) { - if (pid_ < 0) { - LOG(ERROR) - << "Attempt to wait on invalid pid(has it been waited on already?): " - << pid_; - return -1; - } - auto retval = waitpid(pid_, wstatus, options); - // We don't want to wait twice for the same process - pid_ = -1; - return retval; -} - -bool KillSubprocess(Subprocess* subprocess) { - auto pid = subprocess->pid(); - if (pid > 0) { - auto pgid = getpgid(pid); - if (pgid < 0) { - auto error = errno; - LOG(WARNING) << "Error obtaining process group id of process with pid=" - << pid << ": " << strerror(error); - // Send the kill signal anyways, because pgid will be -1 it will be sent - // to the process and not a (non-existent) group - } - bool is_group_head = pid == pgid; - if (is_group_head) { - return killpg(pid, SIGKILL) == 0; - } else { - return kill(pid, SIGKILL) == 0; - } - } - 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 - for (const auto& entry : inherited_fds_) { - close(entry.second); - } - // Close all redirected file descriptors - for (const auto& entry : redirects_) { - close(entry.second); - } -} - -bool Command::BuildParameter(std::stringstream* stream, SharedFD shared_fd) { - int fd; - if (inherited_fds_.count(shared_fd)) { - fd = inherited_fds_[shared_fd]; - } else { - fd = shared_fd->Fcntl(F_DUPFD_CLOEXEC, 3); - if (fd < 0) { - LOG(ERROR) << "Could not acquire a new file descriptor: " << shared_fd->StrError(); - return false; - } - inherited_fds_[shared_fd] = fd; - } - *stream << fd; - return true; -} - -bool Command::RedirectStdIO(cvd::Subprocess::StdIOChannel channel, - cvd::SharedFD shared_fd) { - if (!shared_fd->IsOpen()) { - return false; - } - if (redirects_.count(channel)) { - LOG(ERROR) << "Attempted multiple redirections of fd: " - << static_cast<int>(channel); - return false; - } - auto dup_fd = shared_fd->Fcntl(F_DUPFD_CLOEXEC, 3); - if (dup_fd < 0) { - LOG(ERROR) << "Could not acquire a new file descriptor: " << shared_fd->StrError(); - return false; - } - redirects_[channel] = dup_fd; - return true; -} -bool Command::RedirectStdIO(Subprocess::StdIOChannel subprocess_channel, - Subprocess::StdIOChannel parent_channel) { - return RedirectStdIO(subprocess_channel, - cvd::SharedFD::Dup(static_cast<int>(parent_channel))); -} - -void Command::SetVerbose(bool verbose) { - verbose_ = verbose; -} - -Subprocess Command::StartHelper(bool with_control_socket, bool in_group) const { - auto cmd = ToCharPointers(command_); - if (use_parent_env_) { - return subprocess_impl(cmd.data(), nullptr, redirects_, inherited_fds_, - with_control_socket, subprocess_stopper_, in_group, - verbose_); - } else { - auto envp = ToCharPointers(env_); - return subprocess_impl(cmd.data(), envp.data(), redirects_, inherited_fds_, - with_control_socket, subprocess_stopper_, in_group, - verbose_); - } -} - -Subprocess Command::Start(bool with_control_socket) const { - return StartHelper(with_control_socket, false); -} - -Subprocess Command::StartInGroup(bool with_control_socket) const { - return StartHelper(with_control_socket, true); -} - -// A class that waits for threads to exit in its destructor. -class ThreadJoiner { -std::vector<std::thread*> threads_; -public: - ThreadJoiner(const std::vector<std::thread*> threads) : threads_(threads) {} - ~ThreadJoiner() { - for (auto& thread : threads_) { - if (thread->joinable()) { - thread->join(); - } - } - } -}; - -int RunWithManagedStdio(cvd::Command&& cmd_tmp, const std::string* stdin, - std::string* stdout, std::string* stderr) { - /* - * The order of these declarations is necessary for safety. If the function - * returns at any point, the cvd::Command will be destroyed first, closing all - * of its references to SharedFDs. This will cause the thread internals to fail - * their reads or writes. The ThreadJoiner then waits for the threads to - * complete, as running the destructor of an active std::thread crashes the - * program. - * - * C++ scoping rules dictate that objects are descoped in reverse order to - * construction, so this behavior is predictable. - */ - std::thread stdin_thread, stdout_thread, stderr_thread; - ThreadJoiner thread_joiner({&stdin_thread, &stdout_thread, &stderr_thread}); - cvd::Command cmd = std::move(cmd_tmp); - bool io_error = false; - if (stdin != nullptr) { - cvd::SharedFD pipe_read, pipe_write; - if (!cvd::SharedFD::Pipe(&pipe_read, &pipe_write)) { - LOG(ERROR) << "Could not create a pipe to write the stdin of \"" - << cmd.GetShortName() << "\""; - return -1; - } - if (!cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, pipe_read)) { - LOG(ERROR) << "Could not set stdout of \"" << cmd.GetShortName() - << "\", was already set."; - return -1; - } - stdin_thread = std::thread([pipe_write, stdin, &io_error]() { - int written = cvd::WriteAll(pipe_write, *stdin); - if (written < 0) { - io_error = true; - LOG(ERROR) << "Error in writing stdin to process"; - } - }); - } - if (stdout != nullptr) { - cvd::SharedFD pipe_read, pipe_write; - if (!cvd::SharedFD::Pipe(&pipe_read, &pipe_write)) { - LOG(ERROR) << "Could not create a pipe to read the stdout of \"" - << cmd.GetShortName() << "\""; - return -1; - } - if (!cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, pipe_write)) { - LOG(ERROR) << "Could not set stdout of \"" << cmd.GetShortName() - << "\", was already set."; - return -1; - } - stdout_thread = std::thread([pipe_read, stdout, &io_error]() { - int read = cvd::ReadAll(pipe_read, stdout); - if (read < 0) { - io_error = true; - LOG(ERROR) << "Error in reading stdout from process"; - } - }); - } - if (stderr != nullptr) { - cvd::SharedFD pipe_read, pipe_write; - if (!cvd::SharedFD::Pipe(&pipe_read, &pipe_write)) { - LOG(ERROR) << "Could not create a pipe to read the stderr of \"" - << cmd.GetShortName() << "\""; - return -1; - } - if (!cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdErr, pipe_write)) { - LOG(ERROR) << "Could not set stderr of \"" << cmd.GetShortName() - << "\", was already set."; - return -1; - } - stderr_thread = std::thread([pipe_read, stderr, &io_error]() { - int read = cvd::ReadAll(pipe_read, stderr); - if (read < 0) { - io_error = true; - LOG(ERROR) << "Error in reading stderr from process"; - } - }); - } - - auto subprocess = cmd.Start(); - if (!subprocess.Started()) { - return -1; - } - { - // Force the destructor to run by moving it into a smaller scope. - // This is necessary to close the write end of the pipe. - cvd::Command forceDelete = std::move(cmd); - } - int wstatus; - subprocess.Wait(&wstatus, 0); - if (WIFSIGNALED(wstatus)) { - LOG(ERROR) << "Command was interrupted by a signal: " << WTERMSIG(wstatus); - return -1; - } - { - auto join_threads = std::move(thread_joiner); - } - if (io_error) { - LOG(ERROR) << "IO error communicating with " << cmd.GetShortName(); - return -1; - } - return WEXITSTATUS(wstatus); -} - -int execute(const std::vector<std::string>& command, - const std::vector<std::string>& env) { - Command cmd(command[0]); - for (size_t i = 1; i < command.size(); ++i) { - cmd.AddParameter(command[i]); - } - cmd.SetEnvironment(env); - auto subprocess = cmd.Start(); - if (!subprocess.Started()) { - return -1; - } - return subprocess.Wait(); -} -int execute(const std::vector<std::string>& command) { - Command cmd(command[0]); - for (size_t i = 1; i < command.size(); ++i) { - cmd.AddParameter(command[i]); - } - auto subprocess = cmd.Start(); - if (!subprocess.Started()) { - return -1; - } - return subprocess.Wait(); -} - -} // namespace cvd diff --git a/common/libs/utils/subprocess.h b/common/libs/utils/subprocess.h deleted file mode 100644 index 44976f90..00000000 --- a/common/libs/utils/subprocess.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <sys/types.h> - -#include <functional> -#include <map> -#include <sstream> -#include <string> -#include <vector> - -#include <common/libs/fs/shared_fd.h> - -namespace cvd { -class Subprocess; -using SubprocessStopper = std::function<bool(Subprocess*)>; -// Kills a process by sending it the SIGKILL signal. -bool KillSubprocess(Subprocess* subprocess); - -// Keeps track of a running (sub)process. Allows to wait for its completion. -// It's an error to wait twice for the same subprocess. -class Subprocess { - public: - enum class StdIOChannel { - kStdIn = 0, - kStdOut = 1, - kStdErr = 2, - }; - - Subprocess(pid_t pid, SharedFD control, SubprocessStopper stopper = KillSubprocess) - : pid_(pid), - started_(pid > 0), - control_socket_(control), - stopper_(stopper) {} - // The default implementation won't do because we need to reset the pid of the - // moved object. - Subprocess(Subprocess&&); - ~Subprocess() = default; - Subprocess& operator=(Subprocess&&); - // Waits for the subprocess to complete. Returns zero if completed - // successfully, non-zero otherwise. - int Wait(); - // Same as waitpid(2) - pid_t Wait(int* wstatus, int options); - // Whether the command started successfully. It only says whether the call to - // fork() succeeded or not, it says nothing about exec or successful - // completion of the command, that's what Wait is for. - bool Started() const { return started_; } - SharedFD control_socket() { return control_socket_; } - pid_t pid() const { return pid_; } - bool Stop() { return stopper_(this); } - - private: - // Copy is disabled to avoid waiting twice for the same pid (the first wait - // frees the pid, which allows the kernel to reuse it so we may end up waiting - // for the wrong process) - Subprocess(const Subprocess&) = delete; - Subprocess& operator=(const Subprocess&) = delete; - pid_t pid_ = -1; - bool started_ = false; - SharedFD control_socket_; - SubprocessStopper stopper_; -}; - -// An executable command. Multiple subprocesses can be started from the same -// command object. This class owns any file descriptors that the subprocess -// should inherit. -class Command { - private: - template <typename T> - // For every type other than SharedFD (for which there is a specialisation) - bool BuildParameter(std::stringstream* stream, T t) { - *stream << t; - return true; - } - // Special treatment for SharedFD - bool BuildParameter(std::stringstream* stream, SharedFD shared_fd); - template <typename T, typename... Args> - bool BuildParameter(std::stringstream* stream, T t, Args... args) { - return BuildParameter(stream, t) && BuildParameter(stream, args...); - } - - 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: - cvd::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. - Command(const std::string& executable, - SubprocessStopper stopper = KillSubprocess) - : subprocess_stopper_(stopper), verbose_(true) { - command_.push_back(executable); - } - Command(Command&&) = default; - // The default copy constructor is unsafe because it would mean multiple - // closing of the inherited file descriptors. If needed it can be implemented - // using dup(2) - Command(const Command&) = delete; - Command& operator=(const Command&) = delete; - ~Command(); - - // Specify the environment for the subprocesses to be started. By default - // subprocesses inherit the parent's environment. - void SetEnvironment(const std::vector<std::string>& env) { - use_parent_env_ = false; - env_ = env; - } - // Adds a single parameter to the command. All arguments are concatenated into - // a single string to form a parameter. If one of those arguments is a - // SharedFD a duplicate of it will be used and won't be closed until the - // object is destroyed. To add multiple parameters to the command the function - // must be called multiple times, one per parameter. - template <typename... Args> - bool AddParameter(Args... args) { - std::stringstream ss; - if (BuildParameter(&ss, args...)) { - command_.push_back(ss.str()); - return true; - } - return false; - } - - ParameterBuilder GetParameterBuilder() { return ParameterBuilder(this); } - - // Redirects the standard IO of the command. - bool RedirectStdIO(Subprocess::StdIOChannel channel, cvd::SharedFD shared_fd); - bool RedirectStdIO(Subprocess::StdIOChannel subprocess_channel, - Subprocess::StdIOChannel parent_channel); - - void SetVerbose(bool verbose); - - // Starts execution of the command. This method can be called multiple times, - // effectively staring multiple (possibly concurrent) instances. If - // with_control_socket is true the returned Subprocess instance will have a - // sharedFD that enables communication with the child process. - Subprocess Start(bool with_control_socket = false) const; - // Same as Start(bool), but the subprocess runs as head of its own process - // group. - Subprocess StartInGroup(bool with_control_socket = false) const; - - std::string GetShortName() const { - // This is safe because the constructor guarantees the name of the binary to - // be at index 0 on the vector - return command_[0]; - } - - private: - Subprocess StartHelper(bool with_control_socket, bool in_group) const; - - std::vector<std::string> command_; - std::map<cvd::SharedFD, int> inherited_fds_{}; - std::map<Subprocess::StdIOChannel, int> redirects_{}; - bool use_parent_env_ = true; - std::vector<std::string> env_{}; - SubprocessStopper subprocess_stopper_; - bool verbose_; -}; - -/* - * Consumes a cvd::Command and runs it, optionally managing the stdio channels. - * - * If `stdin` is set, the subprocess stdin will be pipe providing its contents. - * If `stdout` is set, the subprocess stdout will be captured and saved to it. - * If `stderr` is set, the subprocess stderr will be captured and saved to it. - * - * If `command` exits normally, the lower 8 bits of the return code will be - * returned in a value between 0 and 255. - * If some setup fails, `command` fails to start, or `command` exits due to a - * signal, the return value will be negative. - */ -int RunWithManagedStdio(cvd::Command&& command, const std::string* stdin, - std::string* stdout, std::string* stderr); - -// Convenience wrapper around Command and Subprocess class, allows to easily -// execute a command and wait for it to complete. The version without the env -// parameter starts the command with the same environment as the parent. Returns -// zero if the command completed successfully, non zero otherwise. -int execute(const std::vector<std::string>& command, - const std::vector<std::string>& env); -int execute(const std::vector<std::string>& command); - -} // namespace cvd diff --git a/common/libs/utils/users.cpp b/common/libs/utils/users.cpp deleted file mode 100644 index 0ec92c23..00000000 --- a/common/libs/utils/users.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/utils/users.h" - -#include <cerrno> -#include <cstring> -#include <sys/types.h> -#include <unistd.h> -#include <grp.h> - -#include <algorithm> -#include <vector> - -#include <glog/logging.h> - -namespace { -gid_t GroupIdFromName(const std::string& group_name) { - struct group grp{}; - struct group* grp_p{}; - std::vector<char> buffer(100); - int result = 0; - while(true) { - result = getgrnam_r(group_name.c_str(), &grp, buffer.data(), buffer.size(), - &grp_p); - if (result != ERANGE) { - break; - } - buffer.resize(2*buffer.size()); - } - if (result == 0) { - if (grp_p != nullptr) { - return grp.gr_gid; - } else { - LOG(ERROR) << "Group " << group_name << " does not exist"; - return -1; - } - } else { - LOG(ERROR) << "Unable to get group id for group " << group_name << ": " - << std::strerror(result); - return -1; - } -} - -std::vector<gid_t> GetSuplementaryGroups() { - int num_groups = getgroups(0, nullptr); - if (num_groups < 0) { - LOG(ERROR) << "Unable to get number of suplementary groups: " - << std::strerror(errno); - return {}; - } - std::vector<gid_t> groups(num_groups + 1); - int retval = getgroups(groups.size(), groups.data()); - if (retval < 0) { - LOG(ERROR) << "Error obtaining list of suplementary groups (list size: " - << groups.size() << "): " << std::strerror(errno); - return {}; - } - return groups; -} -} // namespace - -bool cvd::InGroup(const std::string& group) { - auto gid = GroupIdFromName(group); - if (gid == static_cast<gid_t>(-1)) { - return false; - } - - if (gid == getegid()) { - return true; - } - - auto groups = GetSuplementaryGroups(); - - if (std::find(groups.cbegin(), groups.cend(), gid) != groups.cend()) { - return true; - } - return false; -}
\ No newline at end of file diff --git a/common/libs/utils/users.h b/common/libs/utils/users.h deleted file mode 100644 index 2fbbdd4a..00000000 --- a/common/libs/utils/users.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> - -namespace cvd { - -bool InGroup(const std::string& group); - -} // namespace cvd diff --git a/guest/Android.bp b/guest/Android.bp deleted file mode 100644 index 95584bcb..00000000 --- a/guest/Android.bp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = ["*"] diff --git a/guest/commands/Android.bp b/guest/commands/Android.bp deleted file mode 100644 index df150678..00000000 --- a/guest/commands/Android.bp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "vsock_logcat", - "ip_link_add", - "usbforward", - "vport_trigger", - "vsoc_input_service", -] diff --git a/guest/commands/ip_link_add/Android.bp b/guest/commands/ip_link_add/Android.bp deleted file mode 100644 index 6c155f0b..00000000 --- a/guest/commands/ip_link_add/Android.bp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "ip_link_add", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "cuttlefish_net", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/ip_link_add/main.cpp b/guest/commands/ip_link_add/main.cpp deleted file mode 100644 index 5b077980..00000000 --- a/guest/commands/ip_link_add/main.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/net/netlink_client.h" -#include "common/libs/net/netlink_request.h" -#include "common/libs/net/network_interface.h" -#include "common/libs/net/network_interface_manager.h" - -#include <linux/rtnetlink.h> -#include <net/if.h> -#include <iostream> -#include <string> - -int main(int argc, char *argv[]) { - if (!((argc == 5 && std::string(argv[1]) == "vlan") || - (argc == 4 && std::string(argv[1]) == "virt_wifi"))) { - std::cerr << "usages:\n"; - std::cerr << " " << argv[0] << " vlan [ethA] [ethB] [index]\n"; - std::cerr << " " << argv[0] << " virt_wifi [ethA] [ethB]\n"; - return -1; - } - const char *const name = argv[2]; - int32_t index = if_nametoindex(name); - if (index == 0) { - fprintf(stderr, "%s: invalid interface name '%s'\n", argv[2], name); - return -2; - } - const char *const new_name = argv[3]; - auto factory = cvd::NetlinkClientFactory::Default(); - std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE)); - - // http://maz-programmersdiary.blogspot.com/2011/09/netlink-sockets.html - cvd::NetlinkRequest link_add_request(RTM_NEWLINK, NLM_F_REQUEST|NLM_F_ACK|0x600); - link_add_request.Append(ifinfomsg { - .ifi_change = 0xFFFFFFFF, - }); - link_add_request.AddString(IFLA_IFNAME, std::string(new_name)); - link_add_request.AddInt(IFLA_LINK, index); - - link_add_request.PushList(IFLA_LINKINFO); - link_add_request.AddString(IFLA_INFO_KIND, argv[1]); - link_add_request.PushList(IFLA_INFO_DATA); - if (std::string(argv[1]) == "vlan") { - uint16_t vlan_index = atoi(argv[4]); - link_add_request.AddInt(IFLA_VLAN_ID, vlan_index); - } - link_add_request.PopList(); - link_add_request.PopList(); - - nl->Send(link_add_request); - - cvd::NetlinkRequest bring_up_backing_request(RTM_SETLINK, NLM_F_REQUEST|NLM_F_ACK|0x600); - bring_up_backing_request.Append(ifinfomsg { - .ifi_index = index, - .ifi_flags = IFF_UP, - .ifi_change = 0xFFFFFFFF, - }); - - nl->Send(bring_up_backing_request); - - return 0; -} diff --git a/guest/commands/rename_netiface/Android.bp b/guest/commands/rename_netiface/Android.bp deleted file mode 100644 index b93a4658..00000000 --- a/guest/commands/rename_netiface/Android.bp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "rename_netiface", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "cuttlefish_net", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/rename_netiface/main.cpp b/guest/commands/rename_netiface/main.cpp deleted file mode 100644 index 37031076..00000000 --- a/guest/commands/rename_netiface/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/net/netlink_client.h" -#include "common/libs/net/network_interface.h" -#include "common/libs/net/network_interface_manager.h" - -#include <net/if.h> -#include <cstdio> - -// This command can only rename network interfaces that are *DOWN* - -int main(int argc, char *argv[]) { - if (argc != 3) { - fprintf(stderr, "usage: %s [ethA] [ethB]\n", argv[0]); - return -1; - } - const char *const name = argv[1]; - int32_t index = if_nametoindex(name); - if (index == 0) { - fprintf(stderr, "%s: invalid interface name '%s'\n", argv[0], name); - return -2; - } - const char *const new_name = argv[2]; - auto factory = cvd::NetlinkClientFactory::Default(); - std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE)); - std::unique_ptr<cvd::NetworkInterfaceManager> nm( - cvd::NetworkInterfaceManager::New(factory)); - std::unique_ptr<cvd::NetworkInterface> ni(nm->Open(new_name, name)); - bool res = false; - if (ni) { - ni->SetName(new_name); - res = nm->ApplyChanges(*ni); - } - if (!res) { - fprintf(stderr, "%s: renaming interface '%s' failed\n", argv[0], name); - return -3; - } - return 0; -} diff --git a/guest/commands/setup_wifi/Android.bp b/guest/commands/setup_wifi/Android.bp deleted file mode 100644 index 182d885c..00000000 --- a/guest/commands/setup_wifi/Android.bp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "setup_wifi", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "cuttlefish_net", - "libbase", - "liblog", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/setup_wifi/main.cpp b/guest/commands/setup_wifi/main.cpp deleted file mode 100644 index e3840ff6..00000000 --- a/guest/commands/setup_wifi/main.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <linux/rtnetlink.h> -#include <net/if.h> - -#include <cstdlib> -#include <iostream> -#include <string> - -#include "common/libs/net/netlink_client.h" -#include "common/libs/net/netlink_request.h" -#include "common/libs/net/network_interface.h" -#include "common/libs/net/network_interface_manager.h" -#include "common/libs/glog/logging.h" - -// TODO(schuffelen): Merge this with the ip_link_add binary. -int CreateWifiWrapper(const std::string& source, - const std::string& destination) { - auto factory = cvd::NetlinkClientFactory::Default(); - std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE)); - - // http://maz-programmersdiary.blogspot.com/2011/09/netlink-sockets.html - cvd::NetlinkRequest link_add_request(RTM_NEWLINK, - NLM_F_REQUEST|NLM_F_ACK|0x600); - link_add_request.Append(ifinfomsg { - .ifi_change = 0xFFFFFFFF, - }); - int32_t index = if_nametoindex(source.c_str()); - if (index == 0) { - LOG(ERROR) << "setup_network: invalid interface name '" << source << "'\n"; - return -2; - } - link_add_request.AddString(IFLA_IFNAME, destination); - link_add_request.AddInt(IFLA_LINK, index); - - link_add_request.PushList(IFLA_LINKINFO); - link_add_request.AddString(IFLA_INFO_KIND, "virt_wifi"); - link_add_request.PushList(IFLA_INFO_DATA); - link_add_request.PopList(); - link_add_request.PopList(); - - bool link_add_success = nl->Send(link_add_request); - if (!link_add_success) { - LOG(ERROR) << "setup_network: could not add link " << destination; - return -3; - } - - cvd::NetlinkRequest bring_up_backing_request(RTM_SETLINK, - NLM_F_REQUEST|NLM_F_ACK|0x600); - bring_up_backing_request.Append(ifinfomsg { - .ifi_index = index, - .ifi_flags = IFF_UP, - .ifi_change = 0xFFFFFFFF, - }); - - bool link_backing_up = nl->Send(bring_up_backing_request); - if (!link_backing_up) { - LOG(ERROR) << "setup_network: could not bring up backing " << source; - return -4; - } - - return 0; -} - -int RenameNetwork(const std::string& name, const std::string& new_name) { - static auto net_manager = - cvd::NetworkInterfaceManager::New(cvd::NetlinkClientFactory::Default()); - auto connection = net_manager->Open(name, "ignore"); - if (!connection) { - LOG(ERROR) << "setup_network: could not open " << name << " on device."; - return -1; - } - connection->SetName(new_name); - bool changes_applied = net_manager->ApplyChanges(*connection); - if (!changes_applied) { - LOG(ERROR) << "setup_network: can't rename " << name << " to " << new_name; - return -1; - } - return 0; -} - -int main() { - int renamed_eth0 = RenameNetwork("eth0", "buried_eth0"); - if (renamed_eth0 != 0) { - return renamed_eth0; - } - return CreateWifiWrapper("buried_eth0", "wlan0"); -} diff --git a/guest/commands/usbforward/Android.bp b/guest/commands/usbforward/Android.bp deleted file mode 100644 index fe390e67..00000000 --- a/guest/commands/usbforward/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "usbforward", - srcs: [ - "main.cpp", - "usb_server.cpp", - "transport_request.cpp", - ], - shared_libs: [ - "libcuttlefish_fs", - "libusb", - "libbase", - "liblog", - ], - cflags: [ - "-DLOG_TAG=\"UsbForward\"", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/usbforward/main.cpp b/guest/commands/usbforward/main.cpp deleted file mode 100644 index 3edd78f4..00000000 --- a/guest/commands/usbforward/main.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <log/log.h> -#include <stdio.h> -#include <libusb/libusb.h> - -#include "common/libs/fs/shared_fd.h" -#include "guest/commands/usbforward/usb_server.h" - -int main(int argc, char* argv[]) { - if (argc == 1) { - printf("Usage: %s <virtio_channel>\n", argv[0]); - return 1; - } - - cvd::SharedFD fd = cvd::SharedFD::Open(argv[1], O_RDWR | O_NOCTTY); - if (!fd->IsOpen()) { - ALOGE("Could not open %s: %s", argv[1], fd->StrError()); - return 1; - } - - usb_forward::USBServer server(fd); - server.Serve(); - ALOGE("Terminated."); - - libusb_exit(nullptr); - return 1; -} diff --git a/guest/commands/usbforward/transport_request.cpp b/guest/commands/usbforward/transport_request.cpp deleted file mode 100644 index fa68acec..00000000 --- a/guest/commands/usbforward/transport_request.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/commands/usbforward/transport_request.h" - -#include <log/log.h> - -namespace usb_forward { - -TransportRequest::TransportRequest(std::shared_ptr<libusb_device_handle> handle, - CallbackType callback, - const ControlTransfer& transfer) - : handle_{std::move(handle)}, - callback_{std::move(callback)}, - is_control_{true}, - transfer_{libusb_alloc_transfer(0), libusb_free_transfer} { - // NOTE: libusb places setup structure as part of user data! - buffer_.reset(new uint8_t[transfer.length + LIBUSB_CONTROL_SETUP_SIZE]); - - // NOTE: libusb places a structure of size LIBUSB_CONTROL_SETUP_SIZE directly - // in the data buffer. - libusb_fill_control_setup(buffer_.get(), transfer.type, transfer.cmd, - transfer.value, transfer.index, transfer.length); - - // NOTE: despite libusb requires user to allocate buffer large enough to - // accommodate SETUP structure and actual data, it requires user to provide - // only data length here, while setup length is added internally. - libusb_fill_control_transfer(transfer_.get(), handle_.get(), buffer_.get(), - OnTransferComplete, this, transfer.timeout); -} - -TransportRequest::TransportRequest(std::shared_ptr<libusb_device_handle> handle, - CallbackType callback, - const DataTransfer& transfer) - : handle_{std::move(handle)}, - callback_{std::move(callback)}, - is_control_{false}, - transfer_{libusb_alloc_transfer(0), libusb_free_transfer} { - buffer_.reset(new uint8_t[transfer.length]); - libusb_fill_bulk_transfer( - transfer_.get(), handle_.get(), - transfer.endpoint_id | (transfer.is_host_to_device ? LIBUSB_ENDPOINT_OUT - : LIBUSB_ENDPOINT_IN), - buffer_.get(), transfer.length, OnTransferComplete, this, - transfer.timeout); -} - -uint8_t* TransportRequest::Buffer() { - if (is_control_) { - return &buffer_[LIBUSB_CONTROL_SETUP_SIZE]; - } else { - return buffer_.get(); - } -} - -bool TransportRequest::Submit() { - if (handle_) { - auto err = libusb_submit_transfer(transfer_.get()); - if (err != 0) { - ALOGE("libusb transfer failed: %d", err); - } - return err == 0; - } else { - ALOGE("Initiated transfer, but device not opened."); - return false; - } -} - -void TransportRequest::OnTransferComplete(libusb_transfer* req) { - auto treq = static_cast<TransportRequest*>(req->user_data); - treq->callback_(req->status == 0, treq->Buffer(), req->actual_length); -} - -} // namespace usb_forward diff --git a/guest/commands/usbforward/transport_request.h b/guest/commands/usbforward/transport_request.h deleted file mode 100644 index 1f76bbe9..00000000 --- a/guest/commands/usbforward/transport_request.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <functional> -#include <memory> - -#include <stdint.h> -#include <libusb/libusb.h> -#include "common/libs/usbforward/protocol.h" - -namespace usb_forward { - -// TransportRequest represents a libusb asynchronous transport request. -// This class encapsulates everything that is necessary to complete -// transfer. -class TransportRequest final { - public: - // CallbackType describes what kind of function can receive call when this - // asynchronous call is complete. - // Parameters passed to callback, in order: - // - success indicator (true = success), - // - buffer with data (in or out), - // - actual length transferred. - using CallbackType = std::function<void(bool, const uint8_t*, int32_t)>; - - TransportRequest(std::shared_ptr<libusb_device_handle> device, - CallbackType callback, const ControlTransfer& transfer); - TransportRequest(std::shared_ptr<libusb_device_handle> device, - CallbackType callback, const DataTransfer& transfer); - ~TransportRequest() = default; - - uint8_t* Buffer(); - - // Submit sends an asynchronous data exchange requests. - // Returns true only if operation was successful. At this point - // ownership of this structure is passed to libusb and user - // must not release the underlying structure. - bool Submit(); - - // Executes corresponding callback with execution results. - // This is a static call to ensure that the callback being invoked - // can dispose of this instance. - static void OnTransferComplete(libusb_transfer* req); - - private: - std::shared_ptr<libusb_device_handle> handle_; - CallbackType callback_; - bool is_control_; - std::unique_ptr<libusb_transfer, void (*)(libusb_transfer*)> transfer_; - std::unique_ptr<uint8_t[]> buffer_; - - TransportRequest(const TransportRequest& other) = delete; - TransportRequest& operator=(const TransportRequest& other) = delete; -}; - -} // namespace usb_forward diff --git a/guest/commands/usbforward/usb_server.cpp b/guest/commands/usbforward/usb_server.cpp deleted file mode 100644 index e8f55257..00000000 --- a/guest/commands/usbforward/usb_server.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -// #undef NDEBUG - -#include "guest/commands/usbforward/usb_server.h" - -#include <string> -#include <vector> -#include <strings.h> -#include <log/log.h> -#include <libusb/libusb.h> -#include "common/libs/fs/shared_select.h" -#include "common/libs/usbforward/protocol.h" -#include "guest/commands/usbforward/transport_request.h" - -namespace usb_forward { -namespace { -// USBServer exports device kExportedVendorID:kExportedProductID to the server. -// We will not support exporting multiple USB devices as there's no practical -// need for this. -constexpr uint16_t kExportedVendorID = 0x18d1; -constexpr uint16_t kExportedProductID = 0x4ee7; - -// Use default BUS and DEVICE IDs so that it's easier to attach over USB/IP. -constexpr uint8_t kDefaultBusID = 1; -constexpr uint8_t kDefaultDevID = 1; - -std::shared_ptr<libusb_device_handle> GetDevice() { - std::shared_ptr<libusb_device_handle> res( - libusb_open_device_with_vid_pid(nullptr, kExportedVendorID, - kExportedProductID), - [](libusb_device_handle* h) { - // Apparently, deleter is called even on an uninitialized shared_ptr. - if (h != nullptr) { - libusb_release_interface(h, 0); - libusb_close(h); - } - }); - - if (res) libusb_claim_interface(res.get(), 0); - - return res; -} - -} // anonymous namespace - -bool USBServer::GetDeviceInfo( - DeviceInfo* info, std::vector<InterfaceInfo>* ifaces) { - if (!handle_) return false; - - // This function does not modify the reference count of the returned device, - // so do not feel compelled to unreference it when you are done. - libusb_device* dev = libusb_get_device(handle_.get()); - - libusb_device_descriptor desc; - libusb_config_descriptor* conf; - memset(info, 0, sizeof(*info)); - - int res = libusb_get_device_descriptor(dev, &desc); - if (res < 0) { - // This shouldn't really happen. - ALOGE("libusb_get_device_descriptor failed %d", res); - return false; - } - - res = libusb_get_active_config_descriptor(dev, &conf); - if (res < 0) { - // This shouldn't really happen. - ALOGE("libusb_get_active_config_descriptor failed %d", res); - libusb_free_config_descriptor(conf); - return false; - } - - info->vendor_id = desc.idVendor; - info->product_id = desc.idProduct; - info->dev_version = desc.bcdDevice; - info->dev_class = desc.bDeviceClass; - info->dev_subclass = desc.bDeviceSubClass; - info->dev_protocol = desc.bDeviceProtocol; - info->speed = libusb_get_device_speed(dev); - info->num_configurations = desc.bNumConfigurations; - info->num_interfaces = conf->bNumInterfaces; - info->cur_configuration = conf->bConfigurationValue; - info->bus_id = kDefaultBusID; - info->dev_id = kDefaultDevID; - - if (ifaces != nullptr) { - for (int ifidx = 0; ifidx < conf->bNumInterfaces; ++ifidx) { - const libusb_interface& iface = conf->interface[ifidx]; - for (int altidx = 0; altidx < iface.num_altsetting; ++altidx) { - const libusb_interface_descriptor& alt = iface.altsetting[altidx]; - ifaces->push_back(InterfaceInfo{alt.bInterfaceClass, - alt.bInterfaceSubClass, - alt.bInterfaceProtocol, 0}); - } - } - } - libusb_free_config_descriptor(conf); - return true; -} - -USBServer::USBServer(const cvd::SharedFD& fd) - : fd_{fd}, - device_event_fd_{cvd::SharedFD::Event(0, 0)}, - thread_event_fd_{cvd::SharedFD::Event(0, 0)} {} - -void USBServer::HandleDeviceList(uint32_t tag) { - // Iterate all devices and send structure for every found device. - // Write header: number of devices. - DeviceInfo info; - std::vector<InterfaceInfo> ifaces; - bool found = GetDeviceInfo(&info, &ifaces); - - cvd::LockGuard<cvd::Mutex> lock(write_mutex_); - ResponseHeader rsp{StatusSuccess, tag}; - fd_->Write(&rsp, sizeof(rsp)); - if (found) { - uint32_t cnt = 1; - fd_->Write(&cnt, sizeof(cnt)); - fd_->Write(&info, sizeof(info)); - fd_->Write(ifaces.data(), ifaces.size() * sizeof(InterfaceInfo)); - } else { - // No devices. - uint32_t cnt = 0; - fd_->Write(&cnt, sizeof(cnt)); - } -} - -void USBServer::HandleAttach(uint32_t tag) { - // We read the request, but it no longer plays any significant role here. - AttachRequest req; - if (fd_->Read(&req, sizeof(req)) != sizeof(req)) return; - - cvd::LockGuard<cvd::Mutex> lock(write_mutex_); - ResponseHeader rsp{handle_ ? StatusSuccess : StatusFailure, tag}; - fd_->Write(&rsp, sizeof(rsp)); -} - -void USBServer::HandleHeartbeat(uint32_t tag) { - cvd::LockGuard<cvd::Mutex> lock(write_mutex_); - ResponseHeader rsp{handle_ ? StatusSuccess : StatusFailure, tag}; - fd_->Write(&rsp, sizeof(rsp)); -} - -void USBServer::HandleControlTransfer(uint32_t tag) { - ControlTransfer req; - // If disconnected prematurely, don't send response. - if (fd_->Read(&req, sizeof(req)) != sizeof(req)) return; - - // Technically speaking this isn't endpoint, but names, masks, values and - // meaning here is exactly same. - bool is_data_in = - ((req.type & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN); - - std::unique_ptr<TransportRequest> treq(new TransportRequest( - handle_, - [this, is_data_in, tag](bool is_success, const uint8_t* data, - int32_t length) { - OnTransferComplete(tag, is_data_in, is_success, data, length); - }, - req)); - - if (!is_data_in && req.length) { - // If disconnected prematurely, don't send response. - int32_t got = 0; - while (got < req.length) { - auto read = fd_->Read(&treq->Buffer()[got], req.length - got); - if (fd_->GetErrno() != 0) { - ALOGE("Failed to read from client: %s", fd_->StrError()); - return; - } else if (read == 0) { - ALOGE("Failed to read from client: short read"); - return; - } - got += read; - } - } - - // At this point we store transport request internally until it completes. - TransportRequest* treq_ptr = treq.get(); - { - cvd::LockGuard<cvd::Mutex> lock(requests_mutex_); - requests_in_flight_[tag] = std::move(treq); - } - - if (!treq_ptr->Submit()) { - OnTransferComplete(tag, is_data_in, false, nullptr, 0); - } -} - -void USBServer::HandleDataTransfer(uint32_t tag) { - DataTransfer req; - // If disconnected prematurely, don't send response. - if (fd_->Read(&req, sizeof(req)) != sizeof(req)) return; - - bool is_data_in = !req.is_host_to_device; - - std::unique_ptr<TransportRequest> treq(new TransportRequest( - handle_, - [this, is_data_in, tag](bool is_success, const uint8_t* data, - int32_t length) { - OnTransferComplete(tag, is_data_in, is_success, data, length); - }, - req)); - - if (!is_data_in && req.length) { - // If disconnected prematurely, don't send response. - int32_t got = 0; - while (got < req.length) { - auto read = fd_->Read(&treq->Buffer()[got], req.length - got); - if (fd_->GetErrno() != 0) { - ALOGE("Failed to read from client: %s", fd_->StrError()); - return; - } else if (read == 0) { - ALOGE("Failed to read from client: short read"); - return; - } - got += read; - } - } - - // At this point we store transport request internally until it completes. - TransportRequest* treq_ptr = treq.get(); - { - cvd::LockGuard<cvd::Mutex> lock(requests_mutex_); - requests_in_flight_[tag] = std::move(treq); - } - - if (!treq_ptr->Submit()) { - OnTransferComplete(tag, is_data_in, false, nullptr, 0); - } -} - -void USBServer::OnTransferComplete(uint32_t tag, bool is_data_in, - bool is_success, const uint8_t* buffer, - int32_t actual_length) { - ResponseHeader rsp{is_success ? StatusSuccess : StatusFailure, tag}; - - cvd::LockGuard<cvd::Mutex> lock(write_mutex_); - fd_->Write(&rsp, sizeof(rsp)); - if (is_success && is_data_in) { - fd_->Write(&actual_length, sizeof(actual_length)); - if (actual_length > 0) { - // NOTE: don't use buffer_ here directly, as libusb uses first few bytes - // to store control data there. - int32_t sent = 0; - while (sent < actual_length) { - int packet_size = fd_->Write(&buffer[sent], actual_length - sent); - sent += packet_size; - ALOGV("Sending response, %d / %d bytes sent", sent, actual_length); - if (fd_->GetErrno() != 0) { - ALOGE("Send failed: %s", fd_->StrError()); - return; - } - } - } - } - - { - cvd::LockGuard<cvd::Mutex> lock(requests_mutex_); - requests_in_flight_.erase(tag); - } -} - -int USBServer::HandleDeviceEvent(libusb_context*, libusb_device*, - libusb_hotplug_event, void* self_raw) { - auto self = reinterpret_cast<USBServer*>(self_raw); - int64_t dummy = 1; - self->device_event_fd_->Write(&dummy, sizeof(dummy)); - return 0; -} - -void* USBServer::ProcessLibUSBRequests(void* self_raw) { - USBServer* self = reinterpret_cast<USBServer*>(self_raw); - ALOGI("Starting hotplug thread."); - - cvd::SharedFDSet rset; - while (true) { - // Do not wait if there's no event. - timeval select_timeout{0, 0}; - rset.Zero(); - rset.Set(self->thread_event_fd_); - int ret = cvd::Select(&rset, nullptr, nullptr, &select_timeout); - if (ret > 0) break; - - timeval libusb_timeout{1, 0}; - libusb_handle_events_timeout_completed(nullptr, &libusb_timeout, nullptr); - } - - int64_t dummy; - self->thread_event_fd_->Read(&dummy, sizeof(dummy)); - ALOGI("Shutting down hotplug thread."); - return nullptr; -} - -void USBServer::InitLibUSB() { - if (libusb_init(nullptr) != 0) return; - libusb_hotplug_register_callback( - nullptr, - libusb_hotplug_event(LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT), - libusb_hotplug_flag(0), kExportedVendorID, kExportedProductID, - LIBUSB_HOTPLUG_MATCH_ANY, &USBServer::HandleDeviceEvent, this, - &hotplug_handle_); - handle_ = GetDevice(); - libusb_thread_.reset(new cvd::ScopedThread(&ProcessLibUSBRequests, this)); -} - -void USBServer::ExitLibUSB() { - if (!libusb_thread_) return; - libusb_hotplug_deregister_callback(nullptr, hotplug_handle_); - int64_t dummy = 1; - thread_event_fd_->Write(&dummy, sizeof(dummy)); - libusb_thread_.reset(); - handle_.reset(); - libusb_exit(nullptr); -} - -void USBServer::Serve() { - cvd::SharedFDSet rset; - while (true) { - timeval retry_timeout{1, 0}; - timeval* select_timeout = nullptr; - if (!handle_) { - select_timeout = &retry_timeout; - } - - rset.Zero(); - rset.Set(fd_); - rset.Set(device_event_fd_); - int ret = cvd::Select(&rset, nullptr, nullptr, select_timeout); - - // device_event_fd_ is reset each time libusb notices device has re-appeared - // or is gone. In both cases, the existing handle is no longer valid. - if (rset.IsSet(device_event_fd_)) { - int64_t dummy; - device_event_fd_->Read(&dummy, sizeof(dummy)); - handle_.reset(); - } - - if (!handle_) { - ExitLibUSB(); - InitLibUSB(); - if (handle_) { - ALOGI("Device present."); - } - } - - if (ret < 0) continue; - - if (rset.IsSet(fd_)) { - RequestHeader req; - if (fd_->Read(&req, sizeof(req)) != sizeof(req)) { - // There's nobody on the other side. - sleep(3); - continue; - } - - switch (req.command) { - case CmdDeviceList: - ALOGV("Processing DeviceList command, tag=%d", req.tag); - HandleDeviceList(req.tag); - break; - - case CmdAttach: - ALOGV("Processing Attach command, tag=%d", req.tag); - HandleAttach(req.tag); - break; - - case CmdControlTransfer: - ALOGV("Processing ControlTransfer command, tag=%d", req.tag); - HandleControlTransfer(req.tag); - break; - - case CmdDataTransfer: - ALOGV("Processing DataTransfer command, tag=%d", req.tag); - HandleDataTransfer(req.tag); - break; - - case CmdHeartbeat: - ALOGV("Processing Heartbeat command, tag=%d", req.tag); - HandleHeartbeat(req.tag); - break; - - default: - ALOGE("Discarding unknown command %08x, tag=%d", req.command, - req.tag); - } - } - } -} - -} // namespace usb_forward diff --git a/guest/commands/usbforward/usb_server.h b/guest/commands/usbforward/usb_server.h deleted file mode 100644 index 77449b99..00000000 --- a/guest/commands/usbforward/usb_server.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <map> -#include <memory> -#include <string> -#include <libusb/libusb.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/threads/cuttlefish_thread.h" -#include "guest/commands/usbforward/transport_request.h" - -namespace usb_forward { - -// USBServer exposes access to USB devices over pipe (virtio channel etc). -// Usage: -// -// cvd::SharedFD pipe = cvd::SharedFD::Open(pipe_path, O_RDWR); -// USBServer server(pipe); -// CHECK(server.Init()); -// server.Serve(); -class USBServer final { - public: - USBServer(const cvd::SharedFD& fd); - ~USBServer() = default; - - // Serve incoming USB requests. - void Serve(); - - private: - // HandleDeviceEvent opens and closes Android Gadget device, whenever it - // appears / disappears. - static int HandleDeviceEvent(libusb_context*, libusb_device*, - libusb_hotplug_event event, void* self_raw); - - // Handle CmdDeviceList request. - void HandleDeviceList(uint32_t tag); - - // Handle CmdAttach request. - void HandleAttach(uint32_t tag); - - // Handle CmdControlTransfer request. - void HandleControlTransfer(uint32_t tag); - - // Handle CmdDataTransfer request. - void HandleDataTransfer(uint32_t tag); - - // Handle CmdHeartbeat request. - void HandleHeartbeat(uint32_t tag); - - // OnAsyncDataTransferComplete handles end of asynchronous data transfer cycle - // and sends response back to caller. - void OnTransferComplete(uint32_t tag, bool is_data_in, bool is_success, - const uint8_t* buffer, int32_t actual_length); - - // Initialize, Configure and start libusb. - void InitLibUSB(); - - // Stop, Deconfigure and Clean up libusb. - void ExitLibUSB(); - - // Extract device info, if device is available. - bool GetDeviceInfo(DeviceInfo* info, std::vector<InterfaceInfo>* ifaces); - - // Handle asynchronous libusb events. - static void* ProcessLibUSBRequests(void* self_ptr); - - std::shared_ptr<libusb_device_handle> handle_; - libusb_hotplug_callback_handle hotplug_handle_; - - std::unique_ptr<cvd::ScopedThread> libusb_thread_; - cvd::Mutex write_mutex_; - cvd::SharedFD fd_; - cvd::SharedFD device_event_fd_; - cvd::SharedFD thread_event_fd_; - - cvd::Mutex requests_mutex_; - std::map<uint32_t, std::unique_ptr<TransportRequest>> requests_in_flight_; - - USBServer(const USBServer& other) = delete; - USBServer& operator=(const USBServer& other) = delete; -}; - -} // namespace usb_forward diff --git a/guest/commands/vport_trigger/Android.bp b/guest/commands/vport_trigger/Android.bp deleted file mode 100644 index 621b9c5d..00000000 --- a/guest/commands/vport_trigger/Android.bp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "vport_trigger", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "libcutils", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/vport_trigger/main.cpp b/guest/commands/vport_trigger/main.cpp deleted file mode 100644 index b8d88671..00000000 --- a/guest/commands/vport_trigger/main.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/properties.h> - -#include <sys/cdefs.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <unistd.h> -#include <fcntl.h> - -#include <climits> -#include <cerrno> -#include <string> - -// Taken from android::base, which wasn't available on platform versions -// earlier than nougat. - -static bool ReadFdToString(int fd, std::string* content) { - content->clear(); - char buf[BUFSIZ]; - ssize_t n; - while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) { - content->append(buf, n); - } - return (n == 0) ? true : false; -} - -static bool ReadFileToString(const std::string& path, std::string* content, - bool follow_symlinks) { - int flags = O_RDONLY | O_CLOEXEC | (follow_symlinks ? 0 : O_NOFOLLOW); - int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags)); - if (fd == -1) { - return false; - } - bool result = ReadFdToString(fd, content); - close(fd); - return result; -} - -int main(int argc __unused, char *argv[] __unused) { - const char sysfs_base[] = "/sys/class/virtio-ports/"; - DIR *dir = opendir(sysfs_base); - if (dir) { - dirent *dp; - while ((dp = readdir(dir)) != nullptr) { - std::string dirname = dp->d_name; - std::string sysfs(sysfs_base + dirname + "/name"); - struct stat st; - if (stat(sysfs.c_str(), &st)) { - continue; - } - std::string content; - if (!ReadFileToString(sysfs, &content, true)) { - continue; - } - if (content.empty()) { - continue; - } - content.erase(content.end() - 1); - // Leaves 32-11=22 characters for the port name from QEMU. - std::string dev("/dev/" + dirname); - std::string propname("vendor.ser." + content); - property_set(propname.c_str(), dev.c_str()); - // Property was renamed; this is for compatibility - std::string legacy_propname("sys.cf.ser." + content); - property_set(legacy_propname.c_str(), dev.c_str()); - } - } - return 0; -} diff --git a/guest/commands/vsoc_input_service/Android.bp b/guest/commands/vsoc_input_service/Android.bp deleted file mode 100644 index 6c99127d..00000000 --- a/guest/commands/vsoc_input_service/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "vsoc_input_service", - srcs: [ - "main.cpp", - "virtual_device_base.cpp", - "virtual_power_button.cpp", - "virtual_keyboard.cpp", - "virtual_touchscreen.cpp", - "vsoc_input_service.cpp", - ], - static_libs: [ - "libgflags", - ], - shared_libs: [ - "libcuttlefish_device_config", - "libcuttlefish_fs", - "libbase", - "liblog", - ], - header_libs: [ - "cuttlefish_glog", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/vsoc_input_service/main.cpp b/guest/commands/vsoc_input_service/main.cpp deleted file mode 100644 index c9e93ede..00000000 --- a/guest/commands/vsoc_input_service/main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "log/log.h" -#include <gflags/gflags.h> - -#include "vsoc_input_service.h" - -int main(int argc, char* argv[]) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - vsoc_input_service::VSoCInputService service; - if (!service.SetUpDevices()) { - return -1; - } - - if (!service.ProcessEvents()) { - return -2; - } - return 0; -} diff --git a/guest/commands/vsoc_input_service/virtual_device_base.cpp b/guest/commands/vsoc_input_service/virtual_device_base.cpp deleted file mode 100644 index 0abb0cd9..00000000 --- a/guest/commands/vsoc_input_service/virtual_device_base.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_device_base.h" - -#include <glog/logging.h> -#include <errno.h> -#include <inttypes.h> -#include <string.h> -#include <unistd.h> - -#include "log/log.h" - -using vsoc_input_service::VirtualDeviceBase; - -namespace { - -bool DoIoctl(int fd, int request, const uint32_t value) { - int rc = ioctl(fd, request, value); - if (rc < 0) { - SLOGE("ioctl failed (%s)", strerror(errno)); - return false; - } - return true; -} - -} // namespace - -VirtualDeviceBase::VirtualDeviceBase(const char* device_name, - uint16_t product_id) - : device_name_(device_name), - bus_type_(BUS_USB), - vendor_id_(0x6006), - product_id_(product_id), - version_(1) {} - -VirtualDeviceBase::~VirtualDeviceBase() { - if (fd_ >= 0) { - close(fd_); - fd_ = -1; - } -} - -bool VirtualDeviceBase::SetUp() { - fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK); - if (fd_ < 0) { - SLOGE("Failed to open /dev/uinput (%s)", strerror(errno)); - return false; - } - - strncpy(dev_.name, device_name_, sizeof(dev_.name)); - dev_.id.bustype = bus_type_; - dev_.id.vendor = vendor_id_; - dev_.id.product = product_id_; - dev_.id.version = version_; - - for (uint32_t evt_type : GetEventTypes()) { - if (!DoIoctl(fd_, UI_SET_EVBIT, evt_type)) { - SLOGE("Error setting event type: %" PRIu32, evt_type); - return false; - } - } - - for (uint32_t key : GetKeys()) { - if (!DoIoctl(fd_, UI_SET_KEYBIT, key)) { - SLOGE("Error setting key: %" PRIu32, key); - return false; - } - } - - for (uint32_t property : GetProperties()) { - if (!DoIoctl(fd_, UI_SET_PROPBIT, property)) { - SLOGE("Error setting property: %" PRIu32, property); - return false; - } - } - - for (uint32_t abs : GetAbs()) { - if (!DoIoctl(fd_, UI_SET_ABSBIT, abs)) { - SLOGE("Error setting abs: %" PRIu32, abs); - return false; - } - } - - if (write(fd_, &dev_, sizeof(dev_)) < 0) { - SLOGE("Unable to set input device info (%s)", strerror(errno)); - return false; - } - if (ioctl(fd_, UI_DEV_CREATE) < 0) { - SLOGE("Unable to create input device (%s)", strerror(errno)); - return false; - } - - LOG(INFO) << "set up virtual device"; - - return true; -} - -bool VirtualDeviceBase::EmitEvent(uint16_t type, - uint16_t code, - uint32_t value) { - struct input_event event {}; - event.type = type; - event.code = code; - event.value = value; - - if (write(fd_, &event, sizeof(event)) < static_cast<ssize_t>(sizeof(event))) { - SLOGE("Event write failed (%s): aborting", strerror(errno)); - return false; - } - return true; -} - -// By default devices have no event types, keys, properties or absolutes, -// subclasses can override this behavior if necessary. -const std::vector<const uint32_t>& VirtualDeviceBase::GetEventTypes() const { - static const std::vector<const uint32_t> evt_types{}; - return evt_types; -} -const std::vector<const uint32_t>& VirtualDeviceBase::GetKeys() const { - static const std::vector<const uint32_t> keys{}; - return keys; -} -const std::vector<const uint32_t>& VirtualDeviceBase::GetProperties() const { - static const std::vector<const uint32_t> properties{}; - return properties; -} -const std::vector<const uint32_t>& VirtualDeviceBase::GetAbs() const { - static const std::vector<const uint32_t> abs{}; - return abs; -} diff --git a/guest/commands/vsoc_input_service/virtual_device_base.h b/guest/commands/vsoc_input_service/virtual_device_base.h deleted file mode 100644 index d25e0e4d..00000000 --- a/guest/commands/vsoc_input_service/virtual_device_base.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <linux/input.h> -#include <linux/uinput.h> -#include <stdint.h> - -#include <functional> -#include <vector> - -namespace vsoc_input_service { - -class VirtualDeviceBase { - public: - VirtualDeviceBase(const char* device_name, uint16_t product_id); - virtual ~VirtualDeviceBase(); - - bool SetUp(); - bool EmitEvent(uint16_t type, uint16_t code, uint32_t value); - - protected: - virtual const std::vector<const uint32_t>& GetEventTypes() const; - virtual const std::vector<const uint32_t>& GetKeys() const; - virtual const std::vector<const uint32_t>& GetProperties() const; - virtual const std::vector<const uint32_t>& GetAbs() const; - - const char* const device_name_; - const uint16_t bus_type_; - const uint16_t vendor_id_; - const uint16_t product_id_; - const uint16_t version_; - - struct uinput_user_dev dev_ {}; - int fd_ = -1; -}; - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_keyboard.cpp b/guest/commands/vsoc_input_service/virtual_keyboard.cpp deleted file mode 100644 index 80cf0e07..00000000 --- a/guest/commands/vsoc_input_service/virtual_keyboard.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_keyboard.h" - -namespace vsoc_input_service { - -VirtualKeyboard::VirtualKeyboard() - : VirtualDeviceBase("VSoC keyboard", 0x6008) {} - -const std::vector<const uint32_t>& VirtualKeyboard::GetEventTypes() const { - static const std::vector<const uint32_t> evt_types{EV_KEY}; - return evt_types; -} -const std::vector<const uint32_t>& VirtualKeyboard::GetKeys() const { - static const std::vector<const uint32_t> keys{ - KEY_0, KEY_1, KEY_2, KEY_3, - KEY_4, KEY_5, KEY_6, KEY_7, - KEY_8, KEY_9, KEY_A, KEY_AGAIN, - KEY_APOSTROPHE, KEY_B, KEY_BACKSLASH, KEY_BACKSPACE, - KEY_C, KEY_CAPSLOCK, KEY_COMMA, KEY_COMPOSE, - KEY_D, KEY_DELETE, KEY_DOT, KEY_DOWN, - KEY_E, KEY_END, KEY_ENTER, KEY_EQUAL, - KEY_ESC, KEY_F, KEY_F1, KEY_F10, - KEY_F11, KEY_F12, KEY_F13, KEY_F14, - KEY_F15, KEY_F16, KEY_F17, KEY_F18, - KEY_F19, KEY_F2, KEY_F20, KEY_F21, - KEY_F22, KEY_F23, KEY_F24, KEY_F3, - KEY_F4, KEY_F5, KEY_F6, KEY_F7, - KEY_F8, KEY_F9, KEY_FIND, KEY_G, - KEY_GRAVE, KEY_H, KEY_HOME, KEY_I, - KEY_INSERT, KEY_J, KEY_K, KEY_KP0, - KEY_KP1, KEY_KP2, KEY_KP3, KEY_KP4, - KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8, - KEY_KP9, KEY_KPASTERISK, KEY_KPCOMMA, KEY_KPDOT, - KEY_KPENTER, KEY_KPEQUAL, KEY_KPMINUS, KEY_KPPLUS, - KEY_KPPLUSMINUS, KEY_KPSLASH, KEY_L, KEY_LEFT, - KEY_LEFTALT, KEY_LEFTBRACE, KEY_LEFTCTRL, KEY_LEFTMETA, - KEY_LEFTSHIFT, KEY_LINEFEED, KEY_M, KEY_MENU, - KEY_MINUS, KEY_MUTE, KEY_N, KEY_NUMLOCK, - KEY_O, KEY_P, KEY_PAGEDOWN, KEY_PAGEUP, - KEY_PAUSE, KEY_PRINT, KEY_Q, KEY_R, - KEY_RIGHT, KEY_RIGHTALT, KEY_RIGHTBRACE, KEY_RIGHTCTRL, - KEY_RIGHTMETA, KEY_RIGHTSHIFT, KEY_S, KEY_SCROLLLOCK, - KEY_SEMICOLON, KEY_SLASH, KEY_SPACE, KEY_STOP, - KEY_SYSRQ, KEY_T, KEY_TAB, KEY_U, - KEY_UNDO, KEY_UP, KEY_V, KEY_VOLUMEDOWN, - KEY_VOLUMEUP, KEY_W, KEY_X, KEY_Y, - KEY_YEN, KEY_Z}; - return keys; -} - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_keyboard.h b/guest/commands/vsoc_input_service/virtual_keyboard.h deleted file mode 100644 index b3436990..00000000 --- a/guest/commands/vsoc_input_service/virtual_keyboard.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_device_base.h" - -namespace vsoc_input_service { - -class VirtualKeyboard : public VirtualDeviceBase { - public: - VirtualKeyboard(); - - protected: - const std::vector<const uint32_t>& GetEventTypes() const override; - const std::vector<const uint32_t>& GetKeys() const override; -}; - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_power_button.cpp b/guest/commands/vsoc_input_service/virtual_power_button.cpp deleted file mode 100644 index d1758e04..00000000 --- a/guest/commands/vsoc_input_service/virtual_power_button.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_power_button.h" - -namespace vsoc_input_service { - -VirtualPowerButton::VirtualPowerButton() - : VirtualDeviceBase("VSoC power button", 0x6007) {} - -const std::vector<const uint32_t>& VirtualPowerButton::GetEventTypes() const { - static const std::vector<const uint32_t> evt_types{EV_KEY}; - return evt_types; -} -const std::vector<const uint32_t>& VirtualPowerButton::GetKeys() const { - static const std::vector<const uint32_t> keys{KEY_POWER}; - return keys; -} - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_power_button.h b/guest/commands/vsoc_input_service/virtual_power_button.h deleted file mode 100644 index 220bfdce..00000000 --- a/guest/commands/vsoc_input_service/virtual_power_button.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_device_base.h" - -namespace vsoc_input_service { - -class VirtualPowerButton : public VirtualDeviceBase { - public: - VirtualPowerButton(); - - protected: - const std::vector<const uint32_t>& GetEventTypes() const override; - const std::vector<const uint32_t>& GetKeys() const override; -}; - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_touchscreen.cpp b/guest/commands/vsoc_input_service/virtual_touchscreen.cpp deleted file mode 100644 index 72a0d3fd..00000000 --- a/guest/commands/vsoc_input_service/virtual_touchscreen.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_touchscreen.h" - -namespace vsoc_input_service { - -const std::vector<const uint32_t>& VirtualTouchScreen::GetEventTypes() const { - static const std::vector<const uint32_t> evt_types{EV_ABS, EV_KEY}; - return evt_types; -} -const std::vector<const uint32_t>& VirtualTouchScreen::GetKeys() const { - static const std::vector<const uint32_t> keys{BTN_TOUCH}; - return keys; -} -const std::vector<const uint32_t>& VirtualTouchScreen::GetProperties() const { - static const std::vector<const uint32_t> properties{INPUT_PROP_DIRECT}; - return properties; -} -const std::vector<const uint32_t>& VirtualTouchScreen::GetAbs() const { - static const std::vector<const uint32_t> abs{ABS_X, ABS_Y}; - return abs; -} - -VirtualTouchScreen::VirtualTouchScreen(uint32_t width, uint32_t height) - : VirtualDeviceBase("VSoC touchscreen", 0x6006) { - dev_.absmin[ABS_X] = 0; - dev_.absmax[ABS_X] = width; - dev_.absmin[ABS_Y] = 0; - dev_.absmax[ABS_Y] = height; -} - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/virtual_touchscreen.h b/guest/commands/vsoc_input_service/virtual_touchscreen.h deleted file mode 100644 index 9ac806eb..00000000 --- a/guest/commands/vsoc_input_service/virtual_touchscreen.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "virtual_device_base.h" - -namespace vsoc_input_service { - -class VirtualTouchScreen : public VirtualDeviceBase { - public: - VirtualTouchScreen(uint32_t width, uint32_t lenght); - - protected: - virtual const std::vector<const uint32_t>& GetEventTypes() const; - virtual const std::vector<const uint32_t>& GetKeys() const; - virtual const std::vector<const uint32_t>& GetProperties() const; - virtual const std::vector<const uint32_t>& GetAbs() const; -}; - -} // namespace vsoc_input_service diff --git a/guest/commands/vsoc_input_service/vsoc_input_service.cpp b/guest/commands/vsoc_input_service/vsoc_input_service.cpp deleted file mode 100644 index 8b75b451..00000000 --- a/guest/commands/vsoc_input_service/vsoc_input_service.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "vsoc_input_service.h" - -#include <linux/input.h> -#include <linux/uinput.h> -#include <linux/virtio_input.h> - -#include <thread> - -#include <gflags/gflags.h> -#include "log/log.h" -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/device_config/device_config.h" - -using vsoc::input_events::InputEvent; -using vsoc_input_service::VirtualDeviceBase; -using vsoc_input_service::VirtualKeyboard; -using vsoc_input_service::VirtualPowerButton; -using vsoc_input_service::VirtualTouchScreen; -using vsoc_input_service::VSoCInputService; - -DEFINE_uint32(keyboard_port, 0, "keyboard vsock port"); -DEFINE_uint32(touch_port, 0, "keyboard vsock port"); - -namespace { - -void EventLoop(std::shared_ptr<VirtualDeviceBase> device, - std::function<InputEvent()> next_event) { - while (1) { - InputEvent event = next_event(); - device->EmitEvent(event.type, event.code, event.value); - } -} - -} // namespace - -bool VSoCInputService::SetUpDevices() { - virtual_power_button_.reset(new VirtualPowerButton()); - if (!virtual_power_button_->SetUp()) { - return false; - } - virtual_keyboard_.reset(new VirtualKeyboard()); - if (!virtual_keyboard_->SetUp()) { - return false; - } - - auto config = cvd::DeviceConfig::Get(); - if (!config) { - LOG(ERROR) << "Failed to open device config"; - return false; - } - - virtual_touchscreen_.reset( - new VirtualTouchScreen(config->screen_x_res(), config->screen_y_res())); - if (!virtual_touchscreen_->SetUp()) { - return false; - } - - return true; -} - -bool VSoCInputService::ProcessEvents() { - cvd::SharedFD keyboard_fd; - cvd::SharedFD touch_fd; - - LOG(INFO) << "Connecting to the keyboard at " << FLAGS_keyboard_port; - if (FLAGS_keyboard_port) { - keyboard_fd = cvd::SharedFD::VsockClient(2, FLAGS_keyboard_port, SOCK_STREAM); - if (!keyboard_fd->IsOpen()) { - LOG(ERROR) << "Could not connect to the keyboard at vsock:2:" << FLAGS_keyboard_port; - } - LOG(INFO) << "Connected to keyboard"; - } - LOG(INFO) << "Connecting to the touchscreen at " << FLAGS_keyboard_port; - if (FLAGS_touch_port) { - touch_fd = cvd::SharedFD::VsockClient(2, FLAGS_touch_port, SOCK_STREAM); - if (!touch_fd->IsOpen()) { - LOG(ERROR) << "Could not connect to the touch at vsock:2:" << FLAGS_touch_port; - } - LOG(INFO) << "Connected to touch"; - } - - // Start device threads - std::thread screen_thread([this, touch_fd]() { - EventLoop(virtual_touchscreen_, [touch_fd]() { - struct virtio_input_event event; - if (touch_fd->Read(&event, sizeof(event)) != sizeof(event)) { - LOG(FATAL) << "Could not read touch event: " << touch_fd->StrError(); - } - return InputEvent { - .type = event.type, - .code = event.code, - .value = event.value, - }; - }); - }); - std::thread keyboard_thread([this, keyboard_fd]() { - EventLoop(virtual_keyboard_, [keyboard_fd]() { - struct virtio_input_event event; - if (keyboard_fd->Read(&event, sizeof(event)) != sizeof(event)) { - LOG(FATAL) << "Could not read keyboard event: " << keyboard_fd->StrError(); - } - return InputEvent { - .type = event.type, - .code = event.code, - .value = event.value, - }; - }); - }); - - screen_thread.join(); - keyboard_thread.join(); - - // Should never return - return false; -} diff --git a/guest/commands/vsoc_input_service/vsoc_input_service.h b/guest/commands/vsoc_input_service/vsoc_input_service.h deleted file mode 100644 index edf196de..00000000 --- a/guest/commands/vsoc_input_service/vsoc_input_service.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <memory> - -#include "virtual_keyboard.h" -#include "virtual_power_button.h" -#include "virtual_touchscreen.h" - -namespace vsoc { -namespace input_events { - -struct InputEvent { - uint16_t type; - uint16_t code; - uint32_t value; -}; - -} // namespace input_events -} // namespace vsoc - -namespace vsoc_input_service { - -class VSoCInputService { - public: - bool SetUpDevices(); - bool ProcessEvents(); - - private: - std::shared_ptr<VirtualPowerButton> virtual_power_button_; - std::shared_ptr<VirtualKeyboard> virtual_keyboard_; - std::shared_ptr<VirtualTouchScreen> virtual_touchscreen_; -}; - -} // namespace vsoc_input_service diff --git a/guest/commands/vsock_logcat/Android.bp b/guest/commands/vsock_logcat/Android.bp deleted file mode 100644 index 52575d7e..00000000 --- a/guest/commands/vsock_logcat/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2019 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. - - -cc_binary { - name: "vsock_logcat", - srcs: [ - "main.cpp", - ], - shared_libs: [ - "libbase", - "libcutils", - "libcuttlefish_fs", - "libcuttlefish_utils", - "liblog", - ], - static_libs: [ - "libgflags", - ], - header_libs: [ - "cuttlefish_glog", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/commands/vsock_logcat/main.cpp b/guest/commands/vsock_logcat/main.cpp deleted file mode 100644 index 51d97e38..00000000 --- a/guest/commands/vsock_logcat/main.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -#define LOG_TAG "vsock_logcat" - -#include <string.h> - -#include <errno.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <fstream> -#include <sstream> -#include <string> - -#include <cutils/properties.h> -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" - -DEFINE_uint32(port, property_get_int32("ro.boot.vsock_logcat_port", 0), - "VSOCK port to send logcat output to"); -DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to"); -DEFINE_string(pipe_name, "/dev/cf_logcat_pipe", - "The path for the named pipe logcat will write to"); - -namespace { - -constexpr char kLogcatExitMsg[] = "\nDetected exit of logcat process\n\n"; - -class ServiceStatus { - public: - static const char* kServiceStatusProperty; - static const char* kStatusStarted; - static const char* kStatusFailed; - - ServiceStatus() { - // This can fail if the property isn't set (the first time it runs), so - // ignore the result. - property_get(kServiceStatusProperty, status_, kStatusStarted); - } - - bool Set(const char* status) { - auto ret = property_set(kServiceStatusProperty, status); - - if (ret == 0) { - strcpy(status_, status); - return true; - } - return false; - } - - const char* Get() { return status_; } - - private: - char status_[PROP_VALUE_MAX]; -}; - -const char* ServiceStatus::kServiceStatusProperty = "vendor.vsock_logcat_status"; -const char* ServiceStatus::kStatusStarted = "started"; -const char* ServiceStatus::kStatusFailed = "failed"; - -void LogFailed(const std::string& msg, ServiceStatus* status) { - // Only log if status is not failed, ensuring it logs once per fail. - if (strcmp(status->Get(), ServiceStatus::kStatusFailed) != 0) { - LOG(ERROR) << msg; - std::ofstream kmsg; - kmsg.open("/dev/kmsg"); - kmsg << LOG_TAG << ": " << msg; - kmsg << ""; - kmsg.close(); - } - auto ret = status->Set(ServiceStatus::kStatusFailed); - if (!ret) { - LOG(ERROR) << "Unable to set value of property: " - << ServiceStatus::kServiceStatusProperty; - } -} -} // namespace - -int main(int argc, char** argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - - CHECK(FLAGS_port != 0) << "Port flag is required"; - - ServiceStatus status; - - auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port, SOCK_STREAM); - if (!log_fd->IsOpen()) { - std::ostringstream msg; - msg << "Unable to connect to vsock:" << FLAGS_cid << ":" << FLAGS_port - << ": " << log_fd->StrError(); - LogFailed(msg.str(), &status); - return 1; - } - auto ret = status.Set(ServiceStatus::kStatusStarted); - if (!ret) { - LOG(ERROR) << "Unable to set value of property: " - << ServiceStatus::kServiceStatusProperty; - } - - if (cvd::FileExists(FLAGS_pipe_name)) { - LOG(WARNING) << "The file " << FLAGS_pipe_name << " already exists. Deleting..."; - cvd::RemoveFile(FLAGS_pipe_name); - } - auto pipe = mkfifo(FLAGS_pipe_name.c_str(), 0600); - if (pipe != 0) { - LOG(FATAL) << "unable to create pipe: " << strerror(errno); - } - property_set("vendor.ser.cf-logcat", FLAGS_pipe_name.c_str()); - while (1) { - auto conn = cvd::SharedFD::Open(FLAGS_pipe_name.c_str(), O_RDONLY); - while (conn->IsOpen()) { - char buff[4096]; - auto read = conn->Read(buff, sizeof(buff)); - if (read) { - log_fd->Write(buff, read); - } else { - conn->Close(); - } - } - log_fd->Write(kLogcatExitMsg, sizeof(kLogcatExitMsg) - 1); - } -} diff --git a/guest/hals/Android.bp b/guest/hals/Android.bp deleted file mode 100644 index 003b3b82..00000000 --- a/guest/hals/Android.bp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "gps", - "health", - "hwcomposer", - "power", -] diff --git a/guest/hals/audio/Android.bp b/guest/hals/audio/Android.bp deleted file mode 100644 index 93a74558..00000000 --- a/guest/hals/audio/Android.bp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2019 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. - -cc_library_shared { - name: "audio.primary.cutf", - relative_install_path: "hw", - defaults: ["cuttlefish_guest_only"], - vendor: true, - srcs: ["audio_hw.c"], - cflags: ["-Wno-unused-parameter"], - shared_libs: ["libcutils", "libhardware", "liblog", "libtinyalsa"], -} diff --git a/guest/hals/audio/audio_hw.c b/guest/hals/audio/audio_hw.c deleted file mode 100644 index f0979a97..00000000 --- a/guest/hals/audio/audio_hw.c +++ /dev/null @@ -1,1620 +0,0 @@ -/* - * Copyright (C) 2012 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. - * - * This code was forked from device/generic/goldfish/audio/audio_hw.c - * - * At the time of forking, the code was identical except that a fallback - * to a legacy HAL which does not use ALSA was removed, and the dependency - * on libdl was also removed. - */ - -#define LOG_TAG "audio_hw_generic" - -#include <assert.h> -#include <errno.h> -#include <inttypes.h> -#include <pthread.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/time.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <unistd.h> - -#include <log/log.h> -#include <cutils/str_parms.h> - -#include <hardware/hardware.h> -#include <system/audio.h> -#include <hardware/audio.h> -#include <tinyalsa/asoundlib.h> - -#define PCM_CARD 0 -#define PCM_DEVICE 0 - - -#define OUT_PERIOD_MS 15 -#define OUT_PERIOD_COUNT 4 - -#define IN_PERIOD_MS 15 -#define IN_PERIOD_COUNT 4 - -struct generic_audio_device { - struct audio_hw_device device; // Constant after init - pthread_mutex_t lock; - bool mic_mute; // Proteced by this->lock - struct mixer* mixer; // Proteced by this->lock -}; - -/* If not NULL, this is a pointer to the fallback module. - * This really is the original goldfish audio device /dev/eac which we will use - * if no alsa devices are detected. - */ -static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state); -static int adev_get_microphones(const audio_hw_device_t *dev, - struct audio_microphone_characteristic_t *mic_array, - size_t *mic_count); - - -typedef struct audio_vbuffer { - pthread_mutex_t lock; - uint8_t * data; - size_t frame_size; - size_t frame_count; - size_t head; - size_t tail; - size_t live; -} audio_vbuffer_t; - -static int audio_vbuffer_init (audio_vbuffer_t * audio_vbuffer, size_t frame_count, - size_t frame_size) { - if (!audio_vbuffer) { - return -EINVAL; - } - audio_vbuffer->frame_size = frame_size; - audio_vbuffer->frame_count = frame_count; - size_t bytes = frame_count * frame_size; - audio_vbuffer->data = calloc(bytes, 1); - if (!audio_vbuffer->data) { - return -ENOMEM; - } - audio_vbuffer->head = 0; - audio_vbuffer->tail = 0; - audio_vbuffer->live = 0; - pthread_mutex_init (&audio_vbuffer->lock, (const pthread_mutexattr_t *) NULL); - return 0; -} - -static int audio_vbuffer_destroy (audio_vbuffer_t * audio_vbuffer) { - if (!audio_vbuffer) { - return -EINVAL; - } - free(audio_vbuffer->data); - pthread_mutex_destroy(&audio_vbuffer->lock); - return 0; -} - -static int audio_vbuffer_live (audio_vbuffer_t * audio_vbuffer) { - if (!audio_vbuffer) { - return -EINVAL; - } - pthread_mutex_lock (&audio_vbuffer->lock); - int live = audio_vbuffer->live; - pthread_mutex_unlock (&audio_vbuffer->lock); - return live; -} - -#define MIN(a,b) (((a)<(b))?(a):(b)) -static size_t audio_vbuffer_write (audio_vbuffer_t * audio_vbuffer, const void * buffer, size_t frame_count) { - size_t frames_written = 0; - pthread_mutex_lock (&audio_vbuffer->lock); - - while (frame_count != 0) { - int frames = 0; - if (audio_vbuffer->live == 0 || audio_vbuffer->head > audio_vbuffer->tail) { - frames = MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->head); - } else if (audio_vbuffer->head < audio_vbuffer->tail) { - frames = MIN(frame_count, audio_vbuffer->tail - (audio_vbuffer->head)); - } else { - // Full - break; - } - memcpy(&audio_vbuffer->data[audio_vbuffer->head*audio_vbuffer->frame_size], - &((uint8_t*)buffer)[frames_written*audio_vbuffer->frame_size], - frames*audio_vbuffer->frame_size); - audio_vbuffer->live += frames; - frames_written += frames; - frame_count -= frames; - audio_vbuffer->head = (audio_vbuffer->head + frames) % audio_vbuffer->frame_count; - } - - pthread_mutex_unlock (&audio_vbuffer->lock); - return frames_written; -} - -static size_t audio_vbuffer_read (audio_vbuffer_t * audio_vbuffer, void * buffer, size_t frame_count) { - size_t frames_read = 0; - pthread_mutex_lock (&audio_vbuffer->lock); - - while (frame_count != 0) { - int frames = 0; - if (audio_vbuffer->live == audio_vbuffer->frame_count || - audio_vbuffer->tail > audio_vbuffer->head) { - frames = MIN(frame_count, audio_vbuffer->frame_count - audio_vbuffer->tail); - } else if (audio_vbuffer->tail < audio_vbuffer->head) { - frames = MIN(frame_count, audio_vbuffer->head - audio_vbuffer->tail); - } else { - break; - } - memcpy(&((uint8_t*)buffer)[frames_read*audio_vbuffer->frame_size], - &audio_vbuffer->data[audio_vbuffer->tail*audio_vbuffer->frame_size], - frames*audio_vbuffer->frame_size); - audio_vbuffer->live -= frames; - frames_read += frames; - frame_count -= frames; - audio_vbuffer->tail = (audio_vbuffer->tail + frames) % audio_vbuffer->frame_count; - } - - pthread_mutex_unlock (&audio_vbuffer->lock); - return frames_read; -} - -struct generic_stream_out { - struct audio_stream_out stream; // Constant after init - pthread_mutex_t lock; - struct generic_audio_device *dev; // Constant after init - audio_devices_t device; // Protected by this->lock - struct audio_config req_config; // Constant after init - struct pcm_config pcm_config; // Constant after init - audio_vbuffer_t buffer; // Constant after init - - // Time & Position Keeping - bool standby; // Protected by this->lock - uint64_t underrun_position; // Protected by this->lock - struct timespec underrun_time; // Protected by this->lock - uint64_t last_write_time_us; // Protected by this->lock - uint64_t frames_total_buffered; // Protected by this->lock - uint64_t frames_written; // Protected by this->lock - uint64_t frames_rendered; // Protected by this->lock - - // Worker - pthread_t worker_thread; // Constant after init - pthread_cond_t worker_wake; // Protected by this->lock - bool worker_standby; // Protected by this->lock - bool worker_exit; // Protected by this->lock -}; - -struct generic_stream_in { - struct audio_stream_in stream; // Constant after init - pthread_mutex_t lock; - struct generic_audio_device *dev; // Constant after init - audio_devices_t device; // Protected by this->lock - struct audio_config req_config; // Constant after init - struct pcm *pcm; // Protected by this->lock - struct pcm_config pcm_config; // Constant after init - int16_t *stereo_to_mono_buf; // Protected by this->lock - size_t stereo_to_mono_buf_size; // Protected by this->lock - audio_vbuffer_t buffer; // Protected by this->lock - - // Time & Position Keeping - bool standby; // Protected by this->lock - int64_t standby_position; // Protected by this->lock - struct timespec standby_exit_time;// Protected by this->lock - int64_t standby_frames_read; // Protected by this->lock - - // Worker - pthread_t worker_thread; // Constant after init - pthread_cond_t worker_wake; // Protected by this->lock - bool worker_standby; // Protected by this->lock - bool worker_exit; // Protected by this->lock -}; - -static struct pcm_config pcm_config_out = { - .channels = 2, - .rate = 0, - .period_size = 0, - .period_count = OUT_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, - .start_threshold = 0, -}; - -static struct pcm_config pcm_config_in = { - .channels = 2, - .rate = 0, - .period_size = 0, - .period_count = IN_PERIOD_COUNT, - .format = PCM_FORMAT_S16_LE, - .start_threshold = 0, - .stop_threshold = INT_MAX, -}; - -static pthread_mutex_t adev_init_lock = PTHREAD_MUTEX_INITIALIZER; -static unsigned int audio_device_ref_count = 0; - -static uint32_t out_get_sample_rate(const struct audio_stream *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - return out->req_config.sample_rate; -} - -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - return -ENOSYS; -} - -static size_t out_get_buffer_size(const struct audio_stream *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - int size = out->pcm_config.period_size * - audio_stream_out_frame_size(&out->stream); - - return size; -} - -static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - return out->req_config.channel_mask; -} - -static audio_format_t out_get_format(const struct audio_stream *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - - return out->req_config.format; -} - -static int out_set_format(struct audio_stream *stream, audio_format_t format) -{ - return -ENOSYS; -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - pthread_mutex_lock(&out->lock); - dprintf(fd, "\tout_dump:\n" - "\t\tsample rate: %u\n" - "\t\tbuffer size: %zu\n" - "\t\tchannel mask: %08x\n" - "\t\tformat: %d\n" - "\t\tdevice: %08x\n" - "\t\taudio dev: %p\n\n", - out_get_sample_rate(stream), - out_get_buffer_size(stream), - out_get_channels(stream), - out_get_format(stream), - out->device, - out->dev); - pthread_mutex_unlock(&out->lock); - return 0; -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - struct str_parms *parms; - char value[32]; - int ret = -EINVAL; - int success; - long val; - char *end; - bool new_device_req = false; - int new_device; - - if (kvpairs == NULL || kvpairs[0] == 0) { - return 0; - } - parms = str_parms_create_str(kvpairs); - success = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, - value, sizeof(value)); - if (success >= 0) { - errno = 0; - val = strtol(value, &end, 10); - if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) { - new_device_req = true; - new_device = (int)val; - ret = 0; - } - } - str_parms_destroy(parms); - if (ret != 0) { - ALOGD("%s: Unsupported parameter %s", __FUNCTION__, kvpairs); - return ret; - } - - // Try applying change requests - pthread_mutex_lock(&out->lock); - if (new_device_req) { - out->device = new_device; - } - pthread_mutex_unlock(&out->lock); - return ret; -} - -static char * out_get_parameters(const struct audio_stream *stream, const char *keys) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - struct str_parms *query = str_parms_create_str(keys); - char *str = NULL; - char value[256]; - struct str_parms *reply = str_parms_create(); - int ret; - bool get = false; - - ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); - if (ret >= 0) { - pthread_mutex_lock(&out->lock); - str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, out->device); - pthread_mutex_unlock(&out->lock); - get = true; - } - - if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) { - value[0] = 0; - strcat(value, "AUDIO_FORMAT_PCM_16_BIT"); - str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value); - get = true; - } - - if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_FORMAT)) { - value[0] = 0; - strcat(value, "AUDIO_FORMAT_PCM_16_BIT"); - str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_FORMAT, value); - get = true; - } - - if (get) { - str = strdup(str_parms_to_str(reply)); - } - else { - ALOGD("%s Unsupported paramter: %s", __FUNCTION__, keys); - } - - str_parms_destroy(query); - str_parms_destroy(reply); - return str; -} - -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - return (out->pcm_config.period_size * 1000) / out->pcm_config.rate; -} - -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - return -ENOSYS; -} - -static void *out_write_worker(void * args) -{ - struct generic_stream_out *out = (struct generic_stream_out *)args; - struct pcm *pcm = NULL; - uint8_t *buffer = NULL; - int buffer_frames; - int buffer_size; - bool restart = false; - bool shutdown = false; - while (true) { - pthread_mutex_lock(&out->lock); - while (out->worker_standby || restart) { - restart = false; - if (pcm) { - pcm_close(pcm); // Frees pcm - pcm = NULL; - free(buffer); - buffer=NULL; - } - if (out->worker_exit) { - break; - } - pthread_cond_wait(&out->worker_wake, &out->lock); - } - - if (out->worker_exit) { - if (!out->worker_standby) { - ALOGE("Out worker not in standby before exiting"); - } - shutdown = true; - } - - while (!shutdown && audio_vbuffer_live(&out->buffer) == 0) { - pthread_cond_wait(&out->worker_wake, &out->lock); - } - - if (shutdown) { - pthread_mutex_unlock(&out->lock); - break; - } - - if (!pcm) { - pcm = pcm_open(PCM_CARD, PCM_DEVICE, - PCM_OUT | PCM_MONOTONIC, &out->pcm_config); - if (!pcm_is_ready(pcm)) { - ALOGE("pcm_open(out) failed: %s: channels %d format %d rate %d", - pcm_get_error(pcm), - out->pcm_config.channels, - out->pcm_config.format, - out->pcm_config.rate - ); - pthread_mutex_unlock(&out->lock); - break; - } - buffer_frames = out->pcm_config.period_size; - buffer_size = pcm_frames_to_bytes(pcm, buffer_frames); - buffer = malloc(buffer_size); - if (!buffer) { - ALOGE("could not allocate write buffer"); - pthread_mutex_unlock(&out->lock); - break; - } - } - int frames = audio_vbuffer_read(&out->buffer, buffer, buffer_frames); - pthread_mutex_unlock(&out->lock); - int ret = pcm_write(pcm, buffer, pcm_frames_to_bytes(pcm, frames)); - if (ret != 0) { - ALOGE("pcm_write failed %s", pcm_get_error(pcm)); - restart = true; - } - } - if (buffer) { - free(buffer); - } - - return NULL; -} - -// Call with in->lock held -static void get_current_output_position(struct generic_stream_out *out, - uint64_t * position, - struct timespec * timestamp) { - struct timespec curtime = { .tv_sec = 0, .tv_nsec = 0 }; - clock_gettime(CLOCK_MONOTONIC, &curtime); - const int64_t now_us = (curtime.tv_sec * 1000000000LL + curtime.tv_nsec) / 1000; - if (timestamp) { - *timestamp = curtime; - } - int64_t position_since_underrun; - if (out->standby) { - position_since_underrun = 0; - } else { - const int64_t first_us = (out->underrun_time.tv_sec * 1000000000LL + - out->underrun_time.tv_nsec) / 1000; - position_since_underrun = (now_us - first_us) * - out_get_sample_rate(&out->stream.common) / - 1000000; - if (position_since_underrun < 0) { - position_since_underrun = 0; - } - } - *position = out->underrun_position + position_since_underrun; - - // The device will reuse the same output stream leading to periods of - // underrun. - if (*position > out->frames_written) { - ALOGW("Not supplying enough data to HAL, expected position %" PRIu64 " , only wrote " - "%" PRIu64, - *position, out->frames_written); - - *position = out->frames_written; - out->underrun_position = *position; - out->underrun_time = curtime; - out->frames_total_buffered = 0; - } -} - - -static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, - size_t bytes) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - const size_t frames = bytes / audio_stream_out_frame_size(stream); - - pthread_mutex_lock(&out->lock); - - if (out->worker_standby) { - out->worker_standby = false; - } - - uint64_t current_position; - struct timespec current_time; - - get_current_output_position(out, ¤t_position, ¤t_time); - const uint64_t now_us = (current_time.tv_sec * 1000000000LL + - current_time.tv_nsec) / 1000; - if (out->standby) { - out->standby = false; - out->underrun_time = current_time; - out->frames_rendered = 0; - out->frames_total_buffered = 0; - } - - size_t frames_written = audio_vbuffer_write(&out->buffer, buffer, frames); - pthread_cond_signal(&out->worker_wake); - - /* Implementation just consumes bytes if we start getting backed up */ - out->frames_written += frames; - out->frames_rendered += frames; - out->frames_total_buffered += frames; - - // We simulate the audio device blocking when it's write buffers become - // full. - - // At the beginning or after an underrun, try to fill up the vbuffer. - // This will be throttled by the PlaybackThread - int frames_sleep = out->frames_total_buffered < out->buffer.frame_count ? 0 : frames; - - uint64_t sleep_time_us = frames_sleep * 1000000LL / - out_get_sample_rate(&stream->common); - - // If the write calls are delayed, subtract time off of the sleep to - // compensate - uint64_t time_since_last_write_us = now_us - out->last_write_time_us; - if (time_since_last_write_us < sleep_time_us) { - sleep_time_us -= time_since_last_write_us; - } else { - sleep_time_us = 0; - } - out->last_write_time_us = now_us + sleep_time_us; - - pthread_mutex_unlock(&out->lock); - - if (sleep_time_us > 0) { - usleep(sleep_time_us); - } - - if (frames_written < frames) { - ALOGW("Hardware backing HAL too slow, could only write %zu of %zu frames", frames_written, frames); - } - - /* Always consume all bytes */ - return bytes; -} - -static int out_get_presentation_position(const struct audio_stream_out *stream, - uint64_t *frames, struct timespec *timestamp) - -{ - if (stream == NULL || frames == NULL || timestamp == NULL) { - return -EINVAL; - } - struct generic_stream_out *out = (struct generic_stream_out *)stream; - - pthread_mutex_lock(&out->lock); - get_current_output_position(out, frames, timestamp); - pthread_mutex_unlock(&out->lock); - - return 0; -} - -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - if (stream == NULL || dsp_frames == NULL) { - return -EINVAL; - } - struct generic_stream_out *out = (struct generic_stream_out *)stream; - pthread_mutex_lock(&out->lock); - *dsp_frames = out->frames_rendered; - pthread_mutex_unlock(&out->lock); - return 0; -} - -// Must be called with out->lock held -static void do_out_standby(struct generic_stream_out *out) -{ - int frames_sleep = 0; - uint64_t sleep_time_us = 0; - if (out->standby) { - return; - } - while (true) { - get_current_output_position(out, &out->underrun_position, NULL); - frames_sleep = out->frames_written - out->underrun_position; - - if (frames_sleep == 0) { - break; - } - - sleep_time_us = frames_sleep * 1000000LL / - out_get_sample_rate(&out->stream.common); - - pthread_mutex_unlock(&out->lock); - usleep(sleep_time_us); - pthread_mutex_lock(&out->lock); - } - out->worker_standby = true; - out->standby = true; -} - -static int out_standby(struct audio_stream *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - pthread_mutex_lock(&out->lock); - do_out_standby(out); - pthread_mutex_unlock(&out->lock); - return 0; -} - -static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - // out_add_audio_effect is a no op - return 0; -} - -static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - // out_remove_audio_effect is a no op - return 0; -} - -static int out_get_next_write_timestamp(const struct audio_stream_out *stream, - int64_t *timestamp) -{ - return -ENOSYS; -} - -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - return in->req_config.sample_rate; -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - return -ENOSYS; -} - -static int refine_output_parameters(uint32_t *sample_rate, audio_format_t *format, audio_channel_mask_t *channel_mask) -{ - static const uint32_t sample_rates [] = {8000,11025,16000,22050,24000,32000, - 44100,48000}; - static const int sample_rates_count = sizeof(sample_rates)/sizeof(uint32_t); - bool inval = false; - if (*format != AUDIO_FORMAT_PCM_16_BIT) { - *format = AUDIO_FORMAT_PCM_16_BIT; - inval = true; - } - - int channel_count = popcount(*channel_mask); - if (channel_count != 1 && channel_count != 2) { - *channel_mask = AUDIO_CHANNEL_IN_STEREO; - inval = true; - } - - int i; - for (i = 0; i < sample_rates_count; i++) { - if (*sample_rate < sample_rates[i]) { - *sample_rate = sample_rates[i]; - inval=true; - break; - } - else if (*sample_rate == sample_rates[i]) { - break; - } - else if (i == sample_rates_count-1) { - // Cap it to the highest rate we support - *sample_rate = sample_rates[i]; - inval=true; - } - } - - if (inval) { - return -EINVAL; - } - return 0; -} - -static int refine_input_parameters(uint32_t *sample_rate, audio_format_t *format, audio_channel_mask_t *channel_mask) -{ - static const uint32_t sample_rates [] = {8000, 11025, 16000, 22050, 44100, 48000}; - static const int sample_rates_count = sizeof(sample_rates)/sizeof(uint32_t); - bool inval = false; - // Only PCM_16_bit is supported. If this is changed, stereo to mono drop - // must be fixed in in_read - if (*format != AUDIO_FORMAT_PCM_16_BIT) { - *format = AUDIO_FORMAT_PCM_16_BIT; - inval = true; - } - - int channel_count = popcount(*channel_mask); - if (channel_count != 1 && channel_count != 2) { - *channel_mask = AUDIO_CHANNEL_IN_STEREO; - inval = true; - } - - int i; - for (i = 0; i < sample_rates_count; i++) { - if (*sample_rate < sample_rates[i]) { - *sample_rate = sample_rates[i]; - inval=true; - break; - } - else if (*sample_rate == sample_rates[i]) { - break; - } - else if (i == sample_rates_count-1) { - // Cap it to the highest rate we support - *sample_rate = sample_rates[i]; - inval=true; - } - } - - if (inval) { - return -EINVAL; - } - return 0; -} - -static int check_input_parameters(uint32_t sample_rate, audio_format_t format, - audio_channel_mask_t channel_mask) -{ - return refine_input_parameters(&sample_rate, &format, &channel_mask); -} - -static size_t get_input_buffer_size(uint32_t sample_rate, audio_format_t format, - audio_channel_mask_t channel_mask) -{ - size_t size; - int channel_count = popcount(channel_mask); - if (check_input_parameters(sample_rate, format, channel_mask) != 0) - return 0; - - size = sample_rate*IN_PERIOD_MS/1000; - // Audioflinger expects audio buffers to be multiple of 16 frames - size = ((size + 15) / 16) * 16; - size *= sizeof(short) * channel_count; - - return size; -} - - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - int size = get_input_buffer_size(in->req_config.sample_rate, - in->req_config.format, - in->req_config.channel_mask); - - return size; -} - -static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - return in->req_config.channel_mask; -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - return in->req_config.format; -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - return -ENOSYS; -} - -static int in_dump(const struct audio_stream *stream, int fd) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - - pthread_mutex_lock(&in->lock); - dprintf(fd, "\tin_dump:\n" - "\t\tsample rate: %u\n" - "\t\tbuffer size: %zu\n" - "\t\tchannel mask: %08x\n" - "\t\tformat: %d\n" - "\t\tdevice: %08x\n" - "\t\taudio dev: %p\n\n", - in_get_sample_rate(stream), - in_get_buffer_size(stream), - in_get_channels(stream), - in_get_format(stream), - in->device, - in->dev); - pthread_mutex_unlock(&in->lock); - return 0; -} - -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - struct str_parms *parms; - char value[32]; - int ret = -EINVAL; - int success; - long val; - char *end; - bool new_device_req = false; - int new_device; - - if (kvpairs == NULL || kvpairs[0] == 0) { - return 0; - } - parms = str_parms_create_str(kvpairs); - success = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, - value, sizeof(value)); - if (success >= 0) { - errno = 0; - val = strtol(value, &end, 10); - if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) { - new_device_req = true; - new_device = (int)val; - ret = 0; - } - } - str_parms_destroy(parms); - if (ret != 0) { - ALOGD("%s: Unsupported parameter %s", __FUNCTION__, kvpairs); - return ret; - } - - // Try applying change requests - pthread_mutex_lock(&in->lock); - if (new_device_req) { - in->device = new_device; - } - pthread_mutex_unlock(&in->lock); - return ret; -} - -static char * in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - struct str_parms *query = str_parms_create_str(keys); - char *str = NULL; - char value[256]; - struct str_parms *reply = str_parms_create(); - int ret; - bool get = false; - - ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); - if (ret >= 0) { - str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, in->device); - get = true; - } - - if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) { - value[0] = 0; - strcat(value, "AUDIO_FORMAT_PCM_16_BIT"); - str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_FORMATS, value); - get = true; - } - - if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_FORMAT)) { - value[0] = 0; - strcat(value, "AUDIO_FORMAT_PCM_16_BIT"); - str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_FORMAT, value); - get = true; - } - - if (get) { - str = strdup(str_parms_to_str(reply)); - } - else { - ALOGD("%s Unsupported paramter: %s", __FUNCTION__, keys); - } - - str_parms_destroy(query); - str_parms_destroy(reply); - return str; -} - -static int in_set_gain(struct audio_stream_in *stream, float gain) -{ - // in_set_gain is a no op - return 0; -} - -// Call with in->lock held -static void get_current_input_position(struct generic_stream_in *in, - int64_t * position, - struct timespec * timestamp) { - struct timespec t = { .tv_sec = 0, .tv_nsec = 0 }; - clock_gettime(CLOCK_MONOTONIC, &t); - const int64_t now_us = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000; - if (timestamp) { - *timestamp = t; - } - int64_t position_since_standby; - if (in->standby) { - position_since_standby = 0; - } else { - const int64_t first_us = (in->standby_exit_time.tv_sec * 1000000000LL + - in->standby_exit_time.tv_nsec) / 1000; - position_since_standby = (now_us - first_us) * - in_get_sample_rate(&in->stream.common) / - 1000000; - if (position_since_standby < 0) { - position_since_standby = 0; - } - } - *position = in->standby_position + position_since_standby; -} - -// Must be called with in->lock held -static void do_in_standby(struct generic_stream_in *in) -{ - if (in->standby) { - return; - } - in->worker_standby = true; - get_current_input_position(in, &in->standby_position, NULL); - in->standby = true; -} - -static int in_standby(struct audio_stream *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - pthread_mutex_lock(&in->lock); - do_in_standby(in); - pthread_mutex_unlock(&in->lock); - return 0; -} - -static void *in_read_worker(void * args) -{ - struct generic_stream_in *in = (struct generic_stream_in *)args; - struct pcm *pcm = NULL; - uint8_t *buffer = NULL; - size_t buffer_frames; - int buffer_size; - - bool restart = false; - bool shutdown = false; - while (true) { - pthread_mutex_lock(&in->lock); - while (in->worker_standby || restart) { - restart = false; - if (pcm) { - pcm_close(pcm); // Frees pcm - pcm = NULL; - free(buffer); - buffer=NULL; - } - if (in->worker_exit) { - break; - } - pthread_cond_wait(&in->worker_wake, &in->lock); - } - - if (in->worker_exit) { - if (!in->worker_standby) { - ALOGE("In worker not in standby before exiting"); - } - shutdown = true; - } - if (shutdown) { - pthread_mutex_unlock(&in->lock); - break; - } - if (!pcm) { - pcm = pcm_open(PCM_CARD, PCM_DEVICE, - PCM_IN | PCM_MONOTONIC, &in->pcm_config); - if (!pcm_is_ready(pcm)) { - ALOGE("pcm_open(in) failed: %s: channels %d format %d rate %d", - pcm_get_error(pcm), - in->pcm_config.channels, - in->pcm_config.format, - in->pcm_config.rate - ); - pthread_mutex_unlock(&in->lock); - break; - } - buffer_frames = in->pcm_config.period_size; - buffer_size = pcm_frames_to_bytes(pcm, buffer_frames); - buffer = malloc(buffer_size); - if (!buffer) { - ALOGE("could not allocate worker read buffer"); - pthread_mutex_unlock(&in->lock); - break; - } - } - pthread_mutex_unlock(&in->lock); - int ret = pcm_read(pcm, buffer, pcm_frames_to_bytes(pcm, buffer_frames)); - if (ret != 0) { - ALOGW("pcm_read failed %s", pcm_get_error(pcm)); - restart = true; - continue; - } - - pthread_mutex_lock(&in->lock); - size_t frames_written = audio_vbuffer_write(&in->buffer, buffer, buffer_frames); - pthread_mutex_unlock(&in->lock); - - if (frames_written != buffer_frames) { - ALOGW("in_read_worker only could write %zu / %zu frames", frames_written, buffer_frames); - } - } - if (buffer) { - free(buffer); - } - return NULL; -} - -static ssize_t in_read(struct audio_stream_in *stream, void* buffer, - size_t bytes) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - struct generic_audio_device *adev = in->dev; - const size_t frames = bytes / audio_stream_in_frame_size(stream); - bool mic_mute = false; - size_t read_bytes = 0; - - adev_get_mic_mute(&adev->device, &mic_mute); - pthread_mutex_lock(&in->lock); - - if (in->worker_standby) { - in->worker_standby = false; - } - pthread_cond_signal(&in->worker_wake); - - int64_t current_position; - struct timespec current_time; - - get_current_input_position(in, ¤t_position, ¤t_time); - if (in->standby) { - in->standby = false; - in->standby_exit_time = current_time; - in->standby_frames_read = 0; - } - - const int64_t frames_available = current_position - in->standby_position - in->standby_frames_read; - assert(frames_available >= 0); - - const size_t frames_wait = ((uint64_t)frames_available > frames) ? 0 : frames - frames_available; - - int64_t sleep_time_us = frames_wait * 1000000LL / - in_get_sample_rate(&stream->common); - - pthread_mutex_unlock(&in->lock); - - if (sleep_time_us > 0) { - usleep(sleep_time_us); - } - - pthread_mutex_lock(&in->lock); - int read_frames = 0; - if (in->standby) { - ALOGW("Input put to sleep while read in progress"); - goto exit; - } - in->standby_frames_read += frames; - - if (popcount(in->req_config.channel_mask) == 1 && - in->pcm_config.channels == 2) { - // Need to resample to mono - if (in->stereo_to_mono_buf_size < bytes*2) { - in->stereo_to_mono_buf = realloc(in->stereo_to_mono_buf, - bytes*2); - if (!in->stereo_to_mono_buf) { - ALOGE("Failed to allocate stereo_to_mono_buff"); - goto exit; - } - } - - read_frames = audio_vbuffer_read(&in->buffer, in->stereo_to_mono_buf, frames); - - // Currently only pcm 16 is supported. - uint16_t *src = (uint16_t *)in->stereo_to_mono_buf; - uint16_t *dst = (uint16_t *)buffer; - size_t i; - // Resample stereo 16 to mono 16 by dropping one channel. - // The stereo stream is interleaved L-R-L-R - for (i = 0; i < frames; i++) { - *dst = *src; - src += 2; - dst += 1; - } - } else { - read_frames = audio_vbuffer_read(&in->buffer, buffer, frames); - } - -exit: - read_bytes = read_frames*audio_stream_in_frame_size(stream); - - if (mic_mute) { - read_bytes = 0; - } - - if (read_bytes < bytes) { - memset (&((uint8_t *)buffer)[read_bytes], 0, bytes-read_bytes); - } - - pthread_mutex_unlock(&in->lock); - - return bytes; -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) -{ - return 0; -} - -static int in_get_capture_position(const struct audio_stream_in *stream, - int64_t *frames, int64_t *time) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - pthread_mutex_lock(&in->lock); - struct timespec current_time; - get_current_input_position(in, frames, ¤t_time); - *time = (current_time.tv_sec * 1000000000LL + current_time.tv_nsec); - pthread_mutex_unlock(&in->lock); - return 0; -} - -static int in_get_active_microphones(const struct audio_stream_in *stream, - struct audio_microphone_characteristic_t *mic_array, - size_t *mic_count) -{ - return adev_get_microphones(NULL, mic_array, mic_count); -} - -static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - // in_add_audio_effect is a no op - return 0; -} - -static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) -{ - // in_add_audio_effect is a no op - return 0; -} - -static int adev_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address __unused) -{ - struct generic_audio_device *adev = (struct generic_audio_device *)dev; - struct generic_stream_out *out; - int ret = 0; - - if (refine_output_parameters(&config->sample_rate, &config->format, &config->channel_mask)) { - ALOGE("Error opening output stream format %d, channel_mask %04x, sample_rate %u", - config->format, config->channel_mask, config->sample_rate); - ret = -EINVAL; - goto error; - } - - out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out)); - - if (!out) - return -ENOMEM; - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - out->stream.get_presentation_position = out_get_presentation_position; - out->stream.get_next_write_timestamp = out_get_next_write_timestamp; - - pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL); - out->dev = adev; - out->device = devices; - memcpy(&out->req_config, config, sizeof(struct audio_config)); - memcpy(&out->pcm_config, &pcm_config_out, sizeof(struct pcm_config)); - out->pcm_config.rate = config->sample_rate; - out->pcm_config.period_size = out->pcm_config.rate*OUT_PERIOD_MS/1000; - - out->standby = true; - out->underrun_position = 0; - out->underrun_time.tv_sec = 0; - out->underrun_time.tv_nsec = 0; - out->last_write_time_us = 0; - out->frames_total_buffered = 0; - out->frames_written = 0; - out->frames_rendered = 0; - - ret = audio_vbuffer_init(&out->buffer, - out->pcm_config.period_size*out->pcm_config.period_count, - out->pcm_config.channels * - pcm_format_to_bits(out->pcm_config.format) >> 3); - if (ret == 0) { - pthread_cond_init(&out->worker_wake, NULL); - out->worker_standby = true; - out->worker_exit = false; - pthread_create(&out->worker_thread, NULL, out_write_worker, out); - - } - *stream_out = &out->stream; - - -error: - - return ret; -} - -static void adev_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) -{ - struct generic_stream_out *out = (struct generic_stream_out *)stream; - pthread_mutex_lock(&out->lock); - do_out_standby(out); - - out->worker_exit = true; - pthread_cond_signal(&out->worker_wake); - pthread_mutex_unlock(&out->lock); - - pthread_join(out->worker_thread, NULL); - pthread_mutex_destroy(&out->lock); - audio_vbuffer_destroy(&out->buffer); - free(stream); -} - -static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) -{ - return 0; -} - -static char * adev_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - return strdup(""); -} - -static int adev_init_check(const struct audio_hw_device *dev) -{ - return 0; -} - -static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - // adev_set_voice_volume is a no op (simulates phones) - return 0; -} - -static int adev_set_master_volume(struct audio_hw_device *dev, float volume) -{ - return -ENOSYS; -} - -static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) -{ - return -ENOSYS; -} - -static int adev_set_master_mute(struct audio_hw_device *dev, bool muted) -{ - return -ENOSYS; -} - -static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted) -{ - return -ENOSYS; -} - -static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) -{ - // adev_set_mode is a no op (simulates phones) - return 0; -} - -static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - struct generic_audio_device *adev = (struct generic_audio_device *)dev; - pthread_mutex_lock(&adev->lock); - adev->mic_mute = state; - pthread_mutex_unlock(&adev->lock); - return 0; -} - -static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - struct generic_audio_device *adev = (struct generic_audio_device *)dev; - pthread_mutex_lock(&adev->lock); - *state = adev->mic_mute; - pthread_mutex_unlock(&adev->lock); - return 0; -} - - -static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - return get_input_buffer_size(config->sample_rate, config->format, config->channel_mask); -} - - -static void adev_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream) -{ - struct generic_stream_in *in = (struct generic_stream_in *)stream; - pthread_mutex_lock(&in->lock); - do_in_standby(in); - - in->worker_exit = true; - pthread_cond_signal(&in->worker_wake); - pthread_mutex_unlock(&in->lock); - pthread_join(in->worker_thread, NULL); - - if (in->stereo_to_mono_buf != NULL) { - free(in->stereo_to_mono_buf); - in->stereo_to_mono_buf_size = 0; - } - - pthread_mutex_destroy(&in->lock); - audio_vbuffer_destroy(&in->buffer); - free(stream); -} - - -static int adev_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags __unused, - const char *address __unused, - audio_source_t source __unused) -{ - struct generic_audio_device *adev = (struct generic_audio_device *)dev; - struct generic_stream_in *in; - int ret = 0; - if (refine_input_parameters(&config->sample_rate, &config->format, &config->channel_mask)) { - ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u", - config->format, config->channel_mask, config->sample_rate); - ret = -EINVAL; - goto error; - } - - in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in)); - if (!in) { - ret = -ENOMEM; - goto error; - } - - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; // no op - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; // no op - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; // no op - in->stream.common.remove_audio_effect = in_remove_audio_effect; // no op - in->stream.set_gain = in_set_gain; // no op - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; // no op - in->stream.get_capture_position = in_get_capture_position; - in->stream.get_active_microphones = in_get_active_microphones; - - pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); - in->dev = adev; - in->device = devices; - memcpy(&in->req_config, config, sizeof(struct audio_config)); - memcpy(&in->pcm_config, &pcm_config_in, sizeof(struct pcm_config)); - in->pcm_config.rate = config->sample_rate; - in->pcm_config.period_size = in->pcm_config.rate*IN_PERIOD_MS/1000; - - in->stereo_to_mono_buf = NULL; - in->stereo_to_mono_buf_size = 0; - - in->standby = true; - in->standby_position = 0; - in->standby_exit_time.tv_sec = 0; - in->standby_exit_time.tv_nsec = 0; - in->standby_frames_read = 0; - - ret = audio_vbuffer_init(&in->buffer, - in->pcm_config.period_size*in->pcm_config.period_count, - in->pcm_config.channels * - pcm_format_to_bits(in->pcm_config.format) >> 3); - if (ret == 0) { - pthread_cond_init(&in->worker_wake, NULL); - in->worker_standby = true; - in->worker_exit = false; - pthread_create(&in->worker_thread, NULL, in_read_worker, in); - } - - *stream_in = &in->stream; - -error: - return ret; -} - - -static int adev_dump(const audio_hw_device_t *dev, int fd) -{ - return 0; -} - -static int adev_get_microphones(const audio_hw_device_t *dev, - struct audio_microphone_characteristic_t *mic_array, - size_t *mic_count) -{ - if (mic_count == NULL) { - return -ENOSYS; - } - - if (*mic_count == 0) { - *mic_count = 1; - return 0; - } - - if (mic_array == NULL) { - return -ENOSYS; - } - - strncpy(mic_array->device_id, "mic_goldfish", AUDIO_MICROPHONE_ID_MAX_LEN - 1); - mic_array->device = AUDIO_DEVICE_IN_BUILTIN_MIC; - strncpy(mic_array->address, AUDIO_BOTTOM_MICROPHONE_ADDRESS, - AUDIO_DEVICE_MAX_ADDRESS_LEN - 1); - memset(mic_array->channel_mapping, AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED, - sizeof(mic_array->channel_mapping)); - mic_array->location = AUDIO_MICROPHONE_LOCATION_UNKNOWN; - mic_array->group = 0; - mic_array->index_in_the_group = 0; - mic_array->sensitivity = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN; - mic_array->max_spl = AUDIO_MICROPHONE_SPL_UNKNOWN; - mic_array->min_spl = AUDIO_MICROPHONE_SPL_UNKNOWN; - mic_array->directionality = AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN; - mic_array->num_frequency_responses = 0; - mic_array->geometric_location.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - mic_array->geometric_location.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - mic_array->geometric_location.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - mic_array->orientation.x = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - mic_array->orientation.y = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - mic_array->orientation.z = AUDIO_MICROPHONE_COORDINATE_UNKNOWN; - - *mic_count = 1; - return 0; -} - -static int adev_close(hw_device_t *dev) -{ - struct generic_audio_device *adev = (struct generic_audio_device *)dev; - int ret = 0; - if (!adev) - return 0; - - pthread_mutex_lock(&adev_init_lock); - - if (audio_device_ref_count == 0) { - ALOGE("adev_close called when ref_count 0"); - ret = -EINVAL; - goto error; - } - - if ((--audio_device_ref_count) == 0) { - if (adev->mixer) { - mixer_close(adev->mixer); - } - free(adev); - } - -error: - pthread_mutex_unlock(&adev_init_lock); - return ret; -} - -static int adev_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ - static struct generic_audio_device *adev; - - if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) - return -EINVAL; - - pthread_mutex_lock(&adev_init_lock); - if (audio_device_ref_count != 0) { - *device = &adev->device.common; - audio_device_ref_count++; - ALOGV("%s: returning existing instance of adev", __func__); - ALOGV("%s: exit", __func__); - goto unlock; - } - adev = calloc(1, sizeof(struct generic_audio_device)); - - pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL); - - adev->device.common.tag = HARDWARE_DEVICE_TAG; - adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; - adev->device.common.module = (struct hw_module_t *) module; - adev->device.common.close = adev_close; - - adev->device.init_check = adev_init_check; // no op - adev->device.set_voice_volume = adev_set_voice_volume; // no op - adev->device.set_master_volume = adev_set_master_volume; // no op - adev->device.get_master_volume = adev_get_master_volume; // no op - adev->device.set_master_mute = adev_set_master_mute; // no op - adev->device.get_master_mute = adev_get_master_mute; // no op - adev->device.set_mode = adev_set_mode; // no op - adev->device.set_mic_mute = adev_set_mic_mute; - adev->device.get_mic_mute = adev_get_mic_mute; - adev->device.set_parameters = adev_set_parameters; // no op - adev->device.get_parameters = adev_get_parameters; // no op - adev->device.get_input_buffer_size = adev_get_input_buffer_size; - adev->device.open_output_stream = adev_open_output_stream; - adev->device.close_output_stream = adev_close_output_stream; - adev->device.open_input_stream = adev_open_input_stream; - adev->device.close_input_stream = adev_close_input_stream; - adev->device.dump = adev_dump; - adev->device.get_microphones = adev_get_microphones; - - *device = &adev->device.common; - - adev->mixer = mixer_open(PCM_CARD); - struct mixer_ctl *ctl; - - // Set default mixer ctls - // Enable channels and set volume - for (int i = 0; i < (int)mixer_get_num_ctls(adev->mixer); i++) { - ctl = mixer_get_ctl(adev->mixer, i); - ALOGD("mixer %d name %s", i, mixer_ctl_get_name(ctl)); - if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Volume") || - !strcmp(mixer_ctl_get_name(ctl), "Capture Volume")) { - for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) { - ALOGD("set ctl %d to %d", z, 100); - mixer_ctl_set_percent(ctl, z, 100); - } - continue; - } - if (!strcmp(mixer_ctl_get_name(ctl), "Master Playback Switch") || - !strcmp(mixer_ctl_get_name(ctl), "Capture Switch")) { - for (int z = 0; z < (int)mixer_ctl_get_num_values(ctl); z++) { - ALOGD("set ctl %d to %d", z, 1); - mixer_ctl_set_value(ctl, z, 1); - } - continue; - } - } - - audio_device_ref_count++; - -unlock: - pthread_mutex_unlock(&adev_init_lock); - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = adev_open, -}; - -struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = AUDIO_MODULE_API_VERSION_0_1, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "Generic audio HW HAL", - .author = "The Android Open Source Project", - .methods = &hal_module_methods, - }, -}; diff --git a/guest/hals/camera/Android.mk b/guest/hals/camera/Android.mk deleted file mode 100644 index 6a37cae9..00000000 --- a/guest/hals/camera/Android.mk +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -# Emulator camera module######################################################## - -emulator_camera_module_relative_path := hw -emulator_camera_cflags := -fno-short-enums $(VSOC_VERSION_CFLAGS) -emulator_camera_cflags += \ - -std=gnu++17 \ - -Wall \ - -Werror - -emulator_camera_shared_libraries := \ - libbase \ - libbinder \ - libexif \ - liblog \ - libutils \ - libcutils \ - libui \ - libdl \ - libjpeg \ - libcamera_metadata \ - libhardware - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -lt 27; echo $$?)) -emulator_camera_shared_libraries += libcamera_client -else -emulator_camera_static_libraries += android.hardware.camera.common@1.0-helper -endif - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -le 22; echo $$?)) -emulator_camera_shared_libraries += libjsoncpp -else -emulator_camera_static_libraries += libjsoncpp -endif - - -emulator_camera_static_libraries += android.hardware.camera.common@1.0-helper - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -le 26; echo $$?)) -emulator_camera_static_libraries += libyuv_static -else -emulator_camera_static_libraries += libyuv -endif - -emulator_camera_c_includes := \ - device/google/cuttlefish_common \ - frameworks/native/include/media/hardware \ - $(call include-path-for, camera) \ - -emulator_camera_src := \ - CameraConfiguration.cpp \ - EmulatedCameraHal.cpp \ - EmulatedCameraFactory.cpp \ - EmulatedBaseCamera.cpp \ - EmulatedCamera.cpp \ - EmulatedCameraDevice.cpp \ - EmulatedFakeCamera.cpp \ - EmulatedFakeCameraDevice.cpp \ - Exif.cpp \ - Thumbnail.cpp \ - Converters.cpp \ - PreviewWindow.cpp \ - CallbackNotifier.cpp \ - JpegCompressor.cpp -emulated_camera2_src := \ - VSoCEmulatedCameraHotplugThread.cpp \ - EmulatedCamera2.cpp \ - EmulatedFakeCamera2.cpp \ - fake-pipeline2/Scene.cpp \ - fake-pipeline2/Sensor.cpp \ - fake-pipeline2/JpegCompressor.cpp -emulated_camera3_src := \ - EmulatedCamera3.cpp \ - EmulatedFakeCamera3.cpp - - -emulated_camera2_stub_src := \ - StubEmulatedCamera2.cpp \ - StubEmulatedFakeCamera2.cpp - -enable_emulated_camera3 = $(shell test $(PLATFORM_SDK_VERSION) -ge 23 && echo yes) -enable_emulated_camera2 = $(shell test $(PLATFORM_SDK_VERSION) -ge 19 && echo yes) - -# Emulated camera - cuttlefish / vbox_x86 build################################### -# -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 24; echo $$?)) -emulator_camera_c_includes += external/libjpeg-turbo -else -emulator_camera_c_includes += external/jpeg -endif - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?)) -LOCAL_MODULE_RELATIVE_PATH := ${emulator_camera_module_relative_path} -else -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/${emulator_camera_module_relative_path} -endif -ifeq (true, $(TARGET_TRANSLATE_2ND_ARCH)) -LOCAL_MULTILIB := first -endif -LOCAL_CFLAGS := ${emulator_camera_cflags} -LOCAL_CLANG_CFLAGS += ${emulator_camera_clang_flags} - -LOCAL_SHARED_LIBRARIES := ${emulator_camera_shared_libraries} -LOCAL_STATIC_LIBRARIES := ${emulator_camera_static_libraries} -LOCAL_C_INCLUDES += ${emulator_camera_c_includes} -LOCAL_SRC_FILES := ${emulator_camera_src} ${emulator_camera_ext_src} \ - $(if $(enable_emulated_camera2),$(emulated_camera2_src),) \ - $(if $(enable_emulated_camera3),$(emulated_camera3_src),) - -LOCAL_MODULE := camera.cutf -LOCAL_MODULE_TAGS := optional -LOCAL_VENDOR_MODULE := true - -include $(BUILD_SHARED_LIBRARY) - -# JPEG stub##################################################################### - -include $(CLEAR_VARS) - -jpeg_module_relative_path := hw -jpeg_cflags := \ - -fno-short-enums \ - -Wall \ - -Werror - -jpeg_shared_libraries := \ - libcutils \ - libexif \ - liblog \ - libjpeg \ - -jpeg_c_includes := external/libexif \ - frameworks/native/include -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 24; echo $$?)) -jpeg_c_includes += external/libjpeg-turbo -else -jpeg_c_includes += external/jpeg -endif - -jpeg_src := \ - Compressor.cpp \ - JpegStub.cpp \ - -# JPEG stub - cuttlefish build#################################################### - -ifeq (true, $(TARGET_TRANSLATE_2ND_ARCH)) -LOCAL_MULTILIB := first -endif - -LOCAL_C_INCLUDES += ${jpeg_c_includes} -LOCAL_SRC_FILES := ${jpeg_src} - -LOCAL_MODULE_RELATIVE_PATH := ${jpeg_module_relative_path} -LOCAL_CFLAGS += ${jpeg_cflags} - -LOCAL_SHARED_LIBRARIES := ${jpeg_shared_libraries} - -LOCAL_C_INCLUDES += ${jpeg_c_includes} -LOCAL_SRC_FILES := ${jpeg_src} - -LOCAL_MODULE := camera.cutf.jpeg -LOCAL_MODULE_TAGS := optional -LOCAL_VENDOR_MODULE := true - -include $(BUILD_SHARED_LIBRARY) diff --git a/guest/hals/camera/CallbackNotifier.cpp b/guest/hals/camera/CallbackNotifier.cpp deleted file mode 100644 index 765d4e7d..00000000 --- a/guest/hals/camera/CallbackNotifier.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class CallbackNotifier that manages callbacks - * set via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_CallbackNotifier" -#include "CallbackNotifier.h" -#include <MetadataBufferType.h> -#include <log/log.h> -#include "EmulatedCameraDevice.h" -#include "JpegCompressor.h" -#include "Exif.h" -#include "Thumbnail.h" - -namespace android { - -/* String representation of camera messages. */ -static const char* lCameraMessages[] = {"CAMERA_MSG_ERROR", - "CAMERA_MSG_SHUTTER", - "CAMERA_MSG_FOCUS", - "CAMERA_MSG_ZOOM", - "CAMERA_MSG_PREVIEW_FRAME", - "CAMERA_MSG_VIDEO_FRAME", - "CAMERA_MSG_POSTVIEW_FRAME", - "CAMERA_MSG_RAW_IMAGE", - "CAMERA_MSG_COMPRESSED_IMAGE", - "CAMERA_MSG_RAW_IMAGE_NOTIFY", - "CAMERA_MSG_PREVIEW_METADATA"}; -static const int lCameraMessagesNum = sizeof(lCameraMessages) / sizeof(char*); - -/* Builds an array of strings for the given set of messages. - * Param: - * msg - Messages to get strings for, - * strings - Array where to save strings - * max - Maximum number of entries in the array. - * Return: - * Number of strings saved into the 'strings' array. - */ -static int GetMessageStrings(uint32_t msg, const char** strings, int max) { - int index = 0; - int out = 0; - while (msg != 0 && out < max && index < lCameraMessagesNum) { - while ((msg & 0x1) == 0 && index < lCameraMessagesNum) { - msg >>= 1; - index++; - } - if ((msg & 0x1) != 0 && index < lCameraMessagesNum) { - strings[out] = lCameraMessages[index]; - out++; - msg >>= 1; - index++; - } - } - - return out; -} - -/* Logs messages, enabled by the mask. */ -static void PrintMessages(uint32_t msg) { - const char* strs[lCameraMessagesNum]; - const int translated = GetMessageStrings(msg, strs, lCameraMessagesNum); - for (int n = 0; n < translated; n++) { - ALOGV(" %s", strs[n]); - } -} - -CallbackNotifier::CallbackNotifier() - : mNotifyCB(NULL), - mDataCB(NULL), - mDataCBTimestamp(NULL), - mGetMemoryCB(NULL), - mCBOpaque(NULL), - mLastFrameTimestamp(0), - mFrameRefreshFreq(0), - mMessageEnabler(0), - mJpegQuality(90), - mVideoRecEnabled(false), - mTakingPicture(false) {} - -CallbackNotifier::~CallbackNotifier() {} - -/**************************************************************************** - * Camera API - ***************************************************************************/ - -void CallbackNotifier::setCallbacks( - camera_notify_callback notify_cb, camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user) { - ALOGV("%s: %p, %p, %p, %p (%p)", __FUNCTION__, notify_cb, data_cb, - data_cb_timestamp, get_memory, user); - - Mutex::Autolock locker(&mObjectLock); - mNotifyCB = notify_cb; - mDataCB = data_cb; - mDataCBTimestamp = data_cb_timestamp; - mGetMemoryCB = get_memory; - mCBOpaque = user; -} - -void CallbackNotifier::enableMessage(uint msg_type) { - ALOGV("%s: msg_type = 0x%x", __FUNCTION__, msg_type); - PrintMessages(msg_type); - - Mutex::Autolock locker(&mObjectLock); - mMessageEnabler |= msg_type; - ALOGV("**** Currently enabled messages:"); - PrintMessages(mMessageEnabler); -} - -void CallbackNotifier::disableMessage(uint msg_type) { - ALOGV("%s: msg_type = 0x%x", __FUNCTION__, msg_type); - PrintMessages(msg_type); - - Mutex::Autolock locker(&mObjectLock); - mMessageEnabler &= ~msg_type; - ALOGV("**** Currently enabled messages:"); - PrintMessages(mMessageEnabler); -} - -status_t CallbackNotifier::enableVideoRecording(int fps) { - ALOGV("%s: FPS = %d", __FUNCTION__, fps); - - Mutex::Autolock locker(&mObjectLock); - mVideoRecEnabled = true; - mLastFrameTimestamp = 0; - mFrameRefreshFreq = 1000000000LL / fps; - - return NO_ERROR; -} - -void CallbackNotifier::disableVideoRecording() { - ALOGV("%s:", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - mVideoRecEnabled = false; - mLastFrameTimestamp = 0; - mFrameRefreshFreq = 0; -} - -void CallbackNotifier::releaseRecordingFrame(const void* opaque) { - List<camera_memory_t*>::iterator it = mCameraMemoryTs.begin(); - for (; it != mCameraMemoryTs.end(); ++it) { - if ((*it)->data == opaque) { - (*it)->release(*it); - mCameraMemoryTs.erase(it); - break; - } - } -} - -status_t CallbackNotifier::storeMetaDataInBuffers(bool enable) { - // Return error if metadata is request, otherwise silently agree. - return enable ? INVALID_OPERATION : NO_ERROR; -} - -/**************************************************************************** - * Public API - ***************************************************************************/ - -void CallbackNotifier::cleanupCBNotifier() { - Mutex::Autolock locker(&mObjectLock); - mMessageEnabler = 0; - mNotifyCB = NULL; - mDataCB = NULL; - mDataCBTimestamp = NULL; - mGetMemoryCB = NULL; - mCBOpaque = NULL; - mLastFrameTimestamp = 0; - mFrameRefreshFreq = 0; - mJpegQuality = 90; - mVideoRecEnabled = false; - mTakingPicture = false; -} - -void CallbackNotifier::onNextFrameAvailable(const void* frame, - nsecs_t timestamp, - EmulatedCameraDevice* camera_dev) { - if (isMessageEnabled(CAMERA_MSG_VIDEO_FRAME) && isVideoRecordingEnabled() && - isNewVideoFrameTime(timestamp)) { - camera_memory_t* cam_buff = - mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, mCBOpaque); - if (NULL != cam_buff && NULL != cam_buff->data) { - memcpy(cam_buff->data, frame, camera_dev->getFrameBufferSize()); - mDataCBTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, cam_buff, 0, - mCBOpaque); - - mCameraMemoryTs.push_back(cam_buff); - } else { - ALOGE("%s: Memory failure in CAMERA_MSG_VIDEO_FRAME", __FUNCTION__); - } - } - - if (isMessageEnabled(CAMERA_MSG_PREVIEW_FRAME)) { - camera_memory_t* cam_buff = - mGetMemoryCB(-1, camera_dev->getFrameBufferSize(), 1, mCBOpaque); - if (NULL != cam_buff && NULL != cam_buff->data) { - memcpy(cam_buff->data, frame, camera_dev->getFrameBufferSize()); - mDataCB(CAMERA_MSG_PREVIEW_FRAME, cam_buff, 0, NULL, mCBOpaque); - cam_buff->release(cam_buff); - } else { - ALOGE("%s: Memory failure in CAMERA_MSG_PREVIEW_FRAME", __FUNCTION__); - } - } - - if (mTakingPicture) { - /* This happens just once. */ - mTakingPicture = false; - /* The sequence of callbacks during picture taking is: - * - CAMERA_MSG_SHUTTER - * - CAMERA_MSG_RAW_IMAGE_NOTIFY - * - CAMERA_MSG_COMPRESSED_IMAGE - */ - if (isMessageEnabled(CAMERA_MSG_SHUTTER)) { - mNotifyCB(CAMERA_MSG_SHUTTER, 0, 0, mCBOpaque); - } - if (isMessageEnabled(CAMERA_MSG_RAW_IMAGE_NOTIFY)) { - mNotifyCB(CAMERA_MSG_RAW_IMAGE_NOTIFY, 0, 0, mCBOpaque); - } - if (isMessageEnabled(CAMERA_MSG_COMPRESSED_IMAGE)) { - /* Compress the frame to JPEG. Note that when taking pictures, we - * have requested camera device to provide us with NV21 frames. */ - NV21JpegCompressor compressor; - const CameraParameters* cameraParameters = camera_dev->getCameraParameters(); - if (cameraParameters == nullptr) { - ALOGE("%s: Could not get camera parameters to take picture.", __FUNCTION__); - return; - } - - ExifData* exifData = createExifData(*cameraParameters); - - // Create a thumbnail and place the pointer and size in the EXIF - // data structure. This transfers ownership to the EXIF data and - // the memory will be deallocated in the freeExifData call below. - int width = camera_dev->getFrameWidth(); - int height = camera_dev->getFrameHeight(); - int thumbWidth = cameraParameters->getInt( - CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); - int thumbHeight = cameraParameters->getInt( - CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); - if (thumbWidth > 0 && thumbHeight > 0) { - if (!createThumbnail(static_cast<const unsigned char*>(frame), - width, height, thumbWidth, thumbHeight, - mJpegQuality, exifData)) { - // Not really a fatal error, we'll just keep going - ALOGE("%s: Failed to create thumbnail for image", - __FUNCTION__); - } - } - - status_t res = compressor.compressRawImage(frame, exifData, mJpegQuality, width, height); - if (res == NO_ERROR) { - camera_memory_t* jpeg_buff = - mGetMemoryCB(-1, compressor.getCompressedSize(), 1, mCBOpaque); - if (NULL != jpeg_buff && NULL != jpeg_buff->data) { - compressor.getCompressedImage(jpeg_buff->data); - mDataCB(CAMERA_MSG_COMPRESSED_IMAGE, jpeg_buff, 0, NULL, mCBOpaque); - jpeg_buff->release(jpeg_buff); - } else { - ALOGE("%s: Memory failure in CAMERA_MSG_VIDEO_FRAME", __FUNCTION__); - } - } else { - ALOGE("%s: Compression failure in CAMERA_MSG_VIDEO_FRAME", - __FUNCTION__); - } - freeExifData(exifData); - } - } -} - -void CallbackNotifier::onCameraDeviceError(int err) { - if (isMessageEnabled(CAMERA_MSG_ERROR) && mNotifyCB != NULL) { - mNotifyCB(CAMERA_MSG_ERROR, err, 0, mCBOpaque); - } -} - -void CallbackNotifier::onCameraFocusAcquired() { - if (isMessageEnabled(CAMERA_MSG_FOCUS) && mNotifyCB != NULL) { - mNotifyCB(CAMERA_MSG_FOCUS, 1, 0, mCBOpaque); - } -} - -/**************************************************************************** - * Private API - ***************************************************************************/ - -bool CallbackNotifier::isNewVideoFrameTime(nsecs_t timestamp) { - Mutex::Autolock locker(&mObjectLock); - if ((timestamp - mLastFrameTimestamp) >= mFrameRefreshFreq) { - mLastFrameTimestamp = timestamp; - return true; - } - return false; -} - -}; /* namespace android */ diff --git a/guest/hals/camera/CallbackNotifier.h b/guest/hals/camera/CallbackNotifier.h deleted file mode 100644 index 38a59798..00000000 --- a/guest/hals/camera/CallbackNotifier.h +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H -#define HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H - -/* - * Contains declaration of a class CallbackNotifier that manages callbacks set - * via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API. - */ - -#include <hardware/camera.h> -#include <utils/List.h> -#include <utils/Mutex.h> -#include <utils/Timers.h> - -namespace android { - -class EmulatedCameraDevice; - -/* Manages callbacks set via set_callbacks, enable_msg_type, and - * disable_msg_type camera HAL API. - * - * Objects of this class are contained in EmulatedCamera objects, and handle - * relevant camera API callbacks. - * Locking considerations. Apparently, it's not allowed to call callbacks - * registered in this class, while holding a lock: recursion is quite possible, - * which will cause a deadlock. - */ -class CallbackNotifier { - public: - /* Constructs CallbackNotifier instance. */ - CallbackNotifier(); - - /* Destructs CallbackNotifier instance. */ - ~CallbackNotifier(); - - /**************************************************************************** - * Camera API - ***************************************************************************/ - - public: - /* Actual handler for camera_device_ops_t::set_callbacks callback. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::set_callbacks callback. - */ - void setCallbacks(camera_notify_callback notify_cb, - camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user); - - /* Actual handler for camera_device_ops_t::enable_msg_type callback. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::enable_msg_type callback. - */ - void enableMessage(uint msg_type); - - /* Actual handler for camera_device_ops_t::disable_msg_type callback. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::disable_msg_type callback. - */ - void disableMessage(uint msg_type); - - /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers - * callback. This method is called by the containing emulated camera object - * when it is handing the camera_device_ops_t::store_meta_data_in_buffers - * callback. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - status_t storeMetaDataInBuffers(bool enable); - - /* Enables video recording. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::start_recording callback. - * Param: - * fps - Video frame frequency. This parameter determins when a frame - * received via onNextFrameAvailable call will be pushed through the - * callback. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - status_t enableVideoRecording(int fps); - - /* Disables video recording. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::stop_recording callback. - */ - void disableVideoRecording(); - - /* Releases video frame, sent to the framework. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::release_recording_frame callback. - */ - void releaseRecordingFrame(const void* opaque); - - /* Actual handler for camera_device_ops_t::msg_type_enabled callback. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::msg_type_enabled callback. - * Note: this method doesn't grab a lock while checking message status, since - * upon exit the status would be undefined anyway. So, grab a lock before - * calling this method if you care about persisting a defined message status. - * Return: - * 0 if message is disabled, or non-zero value, if message is enabled. - */ - inline int isMessageEnabled(uint msg_type) { - return mMessageEnabler & msg_type; - } - - /* Checks id video recording is enabled. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::recording_enabled callback. - * Note: this method doesn't grab a lock while checking video recordin status, - * since upon exit the status would be undefined anyway. So, grab a lock - * before calling this method if you care about persisting of a defined video - * recording status. - * Return: - * true if video recording is enabled, or false if it is disabled. - */ - inline bool isVideoRecordingEnabled() { return mVideoRecEnabled; } - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Resets the callback notifier. */ - void cleanupCBNotifier(); - - /* Next frame is available in the camera device. - * This is a notification callback that is invoked by the camera device when - * a new frame is available. - * Note that most likely this method is called in context of a worker thread - * that camera device has created for frame capturing. - * Param: - * frame - Captured frame, or NULL if camera device didn't pull the frame - * yet. If NULL is passed in this parameter use GetCurrentFrame method - * of the camera device class to obtain the next frame. Also note that - * the size of the frame that is passed here (as well as the frame - * returned from the GetCurrentFrame method) is defined by the current - * frame settings (width + height + pixel format) for the camera device. - * timestamp - Frame's timestamp. - * camera_dev - Camera device instance that delivered the frame. - */ - void onNextFrameAvailable(const void* frame, nsecs_t timestamp, - EmulatedCameraDevice* camera_dev); - - /* Entry point for notifications that occur in camera device. - * Param: - * err - CAMERA_ERROR_XXX error code. - */ - void onCameraDeviceError(int err); - - /* Reports focus operation completion to camera client. - */ - void onCameraFocusAcquired(); - - /* Sets, or resets taking picture state. - * This state control whether or not to notify the framework about compressed - * image, shutter, and other picture related events. - */ - void setTakingPicture(bool taking) { mTakingPicture = taking; } - - /* Sets JPEG quality used to compress frame during picture taking. */ - void setJpegQuality(int jpeg_quality) { mJpegQuality = jpeg_quality; } - - /**************************************************************************** - * Private API - ***************************************************************************/ - - protected: - /* Checks if it's time to push new video frame. - * Note that this method must be called while object is locked. - * Param: - * timestamp - Timestamp for the new frame. */ - bool isNewVideoFrameTime(nsecs_t timestamp); - - /**************************************************************************** - * Data members - ***************************************************************************/ - - protected: - /* Locks this instance for data change. */ - Mutex mObjectLock; - - /* - * Callbacks, registered in set_callbacks. - */ - - camera_notify_callback mNotifyCB; - camera_data_callback mDataCB; - camera_data_timestamp_callback mDataCBTimestamp; - camera_request_memory mGetMemoryCB; - void* mCBOpaque; - - /* video frame queue for the CameraHeapMemory destruction */ - List<camera_memory_t*> mCameraMemoryTs; - - /* Timestamp when last frame has been delivered to the framework. */ - nsecs_t mLastFrameTimestamp; - - /* Video frequency in nanosec. */ - nsecs_t mFrameRefreshFreq; - - /* Message enabler. */ - uint32_t mMessageEnabler; - - /* JPEG quality used to compress frame during picture taking. */ - int mJpegQuality; - - /* Video recording status. */ - bool mVideoRecEnabled; - - /* Picture taking status. */ - bool mTakingPicture; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H */ diff --git a/guest/hals/camera/CameraConfiguration.cpp b/guest/hals/camera/CameraConfiguration.cpp deleted file mode 100644 index 32ac3327..00000000 --- a/guest/hals/camera/CameraConfiguration.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "CameraConfiguration.h" - -#define LOG_TAG "CameraConfiguration" - -#include <android-base/file.h> -#include <android-base/strings.h> -#include <log/log.h> -#include <json/json.h> -#include <json/reader.h> -#include <stdlib.h> - -namespace cvd { -namespace { -////////////////////// Device Personality keys ////////////////////// -// -// **** Camera **** -// -// Example segment (transcribed to constants): -// -// kCameraDefinitionsKey: [ -// { -// kCameraDefinitionOrientationKey: "front", -// kCameraDefinitionHalVersionKey: "1", -// kCameraDefinitionResolutionsKey: [ -// { -// kCameraDefinitionResolutionWidthKey: "1600", -// kCameraDefinitionResolutionHeightKey: "1200", -// }, -// { -// kCameraDefinitionResolutionWidthKey: "1280", -// kCameraDefinitionResolutionHeightKey: "800", -// } -// ] -// }, -// { -// kCameraDefinitionOrientationKey: "back", -// kCameraDefinitionHalVersionKey: "1", -// kCameraDefinitionResolutionsKey: [ -// { -// kCameraDefinitionResolutionWidthKey: "1024", -// kCameraDefinitionResolutionHeightKey: "768", -// }, -// { -// kCameraDefinitionResolutionWidthKey: "800", -// kCameraDefinitionResolutionHeightKey: "600", -// } -// ] -// } -// ] -// - -// Location of the camera configuration files. -const char* const kConfigurationFileLocation = "/vendor/etc/config/camera.json"; - -// -// Array of camera definitions for all cameras available on the device (array). -// Top Level Key. -const char* const kCameraDefinitionsKey = "camera_definitions"; - -// Camera orientation of currently defined camera (string). -// Currently supported values: -// - "back", -// - "front". -const char* const kCameraDefinitionOrientationKey = "orientation"; - -// Camera HAL version of currently defined camera (int). -// Currently supported values: -// - 1 (Camera HALv1) -// - 2 (Camera HALv2) -// - 3 (Camera HALv3) -const char* const kCameraDefinitionHalVersionKey = "hal_version"; - -// Array of resolutions supported by camera (array). -const char* const kCameraDefinitionResolutionsKey = "resolutions"; - -// Width of currently defined resolution (int). -// Must be divisible by 8. -const char* const kCameraDefinitionResolutionWidthKey = "width"; - -// Height of currently defined resolution (int). -// Must be divisible by 8. -const char* const kCameraDefinitionResolutionHeightKey = "height"; - -// Convert string value to camera orientation. -bool ValueToCameraOrientation(const std::string& value, - CameraDefinition::Orientation* orientation) { - if (value == "back") { - *orientation = CameraDefinition::kBack; - return true; - } else if (value == "front") { - *orientation = CameraDefinition::kFront; - return true; - } - ALOGE("%s: Invalid camera orientation: %s.", __FUNCTION__, value.c_str()); - return false; -} - -// Convert string value to camera HAL version. -bool ValueToCameraHalVersion(const std::string& value, - CameraDefinition::HalVersion* hal_version) { - int temp; - char* endptr; - - temp = strtol(value.c_str(), &endptr, 10); - if (endptr != value.c_str() + value.size()) { - ALOGE("%s: Invalid camera HAL version. Expected number, got %s.", - __FUNCTION__, value.c_str()); - return false; - } - - switch (temp) { - case 1: - *hal_version = CameraDefinition::kHalV1; - break; - - case 2: - *hal_version = CameraDefinition::kHalV2; - break; - - case 3: - *hal_version = CameraDefinition::kHalV3; - break; - - default: - ALOGE("%s: Invalid camera HAL version. Version %d not supported.", - __FUNCTION__, temp); - return false; - } - - return true; -} - -bool ValueToCameraResolution(const std::string& width, - const std::string& height, - CameraDefinition::Resolution* resolution) { - char* endptr; - - resolution->width = strtol(width.c_str(), &endptr, 10); - if (endptr != width.c_str() + width.size()) { - ALOGE("%s: Invalid camera resolution width. Expected number, got %s.", - __FUNCTION__, width.c_str()); - return false; - } - - resolution->height = strtol(height.c_str(), &endptr, 10); - if (endptr != height.c_str() + height.size()) { - ALOGE("%s: Invalid camera resolution height. Expected number, got %s.", - __FUNCTION__, height.c_str()); - return false; - } - - // Validate width and height parameters are sane. - if (resolution->width <= 0 || resolution->height <= 0) { - ALOGE("%s: Invalid camera resolution: %dx%d", __FUNCTION__, - resolution->width, resolution->height); - return false; - } - - // Validate width and height divisible by 8. - if ((resolution->width & 7) != 0 || (resolution->height & 7) != 0) { - ALOGE( - "%s: Invalid camera resolution: width and height must be " - "divisible by 8, got %dx%d (%dx%d).", - __FUNCTION__, resolution->width, resolution->height, - resolution->width & 7, resolution->height & 7); - return false; - } - - return true; -} - -// Process camera definitions. -// Returns true, if definitions were sane. -bool ConfigureCameras(const Json::Value& value, - std::vector<CameraDefinition>* cameras) { - if (!value.isObject()) { - ALOGE("%s: Configuration root is not an object", __FUNCTION__); - return false; - } - - if (!value.isMember(kCameraDefinitionsKey)) return true; - for (Json::ValueConstIterator iter = value[kCameraDefinitionsKey].begin(); - iter != value[kCameraDefinitionsKey].end(); ++iter) { - cameras->push_back(CameraDefinition()); - CameraDefinition& camera = cameras->back(); - - if (!iter->isObject()) { - ALOGE("%s: Camera definition is not an object", __FUNCTION__); - continue; - } - - // Camera without orientation -> invalid setting. - if (!iter->isMember(kCameraDefinitionOrientationKey)) { - ALOGE("%s: Invalid camera definition: key %s is missing.", __FUNCTION__, - kCameraDefinitionOrientationKey); - return false; - } - - if (!ValueToCameraOrientation( - (*iter)[kCameraDefinitionOrientationKey].asString(), - &camera.orientation)) - return false; - - // Camera without HAL version -> invalid setting. - if (!(*iter).isMember(kCameraDefinitionHalVersionKey)) { - ALOGE("%s: Invalid camera definition: key %s is missing.", __FUNCTION__, - kCameraDefinitionHalVersionKey); - return false; - } - - if (!ValueToCameraHalVersion( - (*iter)[kCameraDefinitionHalVersionKey].asString(), - &camera.hal_version)) - return false; - - // Camera without resolutions -> invalid setting. - if (!iter->isMember(kCameraDefinitionResolutionsKey)) { - ALOGE("%s: Invalid camera definition: key %s is missing.", __FUNCTION__, - kCameraDefinitionResolutionsKey); - return false; - } - - const Json::Value& json_resolutions = - (*iter)[kCameraDefinitionResolutionsKey]; - - // Resolutions not an array, or an empty array -> invalid setting. - if (!json_resolutions.isArray() || json_resolutions.empty()) { - ALOGE("%s: Invalid camera definition: %s is not an array or is empty.", - __FUNCTION__, kCameraDefinitionResolutionsKey); - return false; - } - - // Process all resolutions. - for (Json::ValueConstIterator json_res_iter = json_resolutions.begin(); - json_res_iter != json_resolutions.end(); ++json_res_iter) { - // Check presence of width and height keys. - if (!json_res_iter->isObject()) { - ALOGE("%s: Camera resolution item is not an object", __FUNCTION__); - continue; - } - if (!json_res_iter->isMember(kCameraDefinitionResolutionWidthKey) || - !json_res_iter->isMember(kCameraDefinitionResolutionHeightKey)) { - ALOGE( - "%s: Invalid camera resolution: keys %s and %s are both required.", - __FUNCTION__, kCameraDefinitionResolutionWidthKey, - kCameraDefinitionResolutionHeightKey); - return false; - } - - camera.resolutions.push_back(CameraDefinition::Resolution()); - CameraDefinition::Resolution& resolution = camera.resolutions.back(); - - if (!ValueToCameraResolution( - (*json_res_iter)[kCameraDefinitionResolutionWidthKey].asString(), - (*json_res_iter)[kCameraDefinitionResolutionHeightKey].asString(), - &resolution)) - return false; - } - } - - return true; -} -} // namespace - -bool CameraConfiguration::Init() { - cameras_.clear(); - std::string config; - if (!android::base::ReadFileToString(kConfigurationFileLocation, &config)) { - ALOGE("%s: Could not open configuration file: %s", __FUNCTION__, - kConfigurationFileLocation); - return false; - } - - Json::Reader config_reader; - Json::Value root; - if (!config_reader.parse(config, root)) { - ALOGE("Could not parse configuration file: %s", - config_reader.getFormattedErrorMessages().c_str()); - return false; - } - - return ConfigureCameras(root, &cameras_); -} - -} // namespace cvd diff --git a/guest/hals/camera/CameraConfiguration.h b/guest/hals/camera/CameraConfiguration.h deleted file mode 100644 index 983963b1..00000000 --- a/guest/hals/camera/CameraConfiguration.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef GUEST_HALS_CAMERA_CAMERACONFIGURATION_H_ -#define GUEST_HALS_CAMERA_CAMERACONFIGURATION_H_ - -#undef max -#undef min -#include <algorithm> -#include <vector> - -namespace cvd { - -// Camera properties and features. -struct CameraDefinition { - // Camera facing direction. - enum Orientation { kFront, kBack }; - - // Camera recognized HAL versions. - enum HalVersion { kHalV1, kHalV2, kHalV3 }; - - struct Resolution { - int width; - int height; - }; - - Orientation orientation; - HalVersion hal_version; - std::vector<Resolution> resolutions; -}; - -class CameraConfiguration { - public: - CameraConfiguration() {} - ~CameraConfiguration() {} - - const std::vector<CameraDefinition>& cameras() const { return cameras_; } - - bool Init(); - - private: - std::vector<CameraDefinition> cameras_; -}; - -} // namespace cvd - -#endif // GUEST_HALS_CAMERA_CAMERACONFIGURATION_H_ diff --git a/guest/hals/camera/Compressor.cpp b/guest/hals/camera/Compressor.cpp deleted file mode 100644 index 3fe0bd6c..00000000 --- a/guest/hals/camera/Compressor.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* -* Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Compressor.h" - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_JPEGStub_Compressor" -#include <log/log.h> -#include <libexif/exif-data.h> - -Compressor::Compressor() { - -} - -bool Compressor::compress(const unsigned char* data, - int width, int height, int quality, - ExifData* exifData) { - if (!configureCompressor(width, height, quality)) { - // The method will have logged a more detailed error message than we can - // provide here so just return. - return false; - } - - return compressData(data, exifData); -} - -const std::vector<uint8_t>& Compressor::getCompressedData() const { - return mDestManager.mBuffer; -} - -bool Compressor::configureCompressor(int width, int height, int quality) { - mCompressInfo.err = jpeg_std_error(&mErrorManager); - // NOTE! DANGER! Do not construct any non-trivial objects below setjmp! - // The compiler will not generate code to destroy them during the return - // below so they will leak. Additionally, do not place any calls to libjpeg - // that can fail above this line or any error will cause undefined behavior. - if (setjmp(mErrorManager.mJumpBuffer)) { - // This is where the error handler will jump in case setup fails - // The error manager will ALOG an appropriate error message - return false; - } - - jpeg_create_compress(&mCompressInfo); - - mCompressInfo.image_width = width; - mCompressInfo.image_height = height; - mCompressInfo.input_components = 3; - mCompressInfo.in_color_space = JCS_YCbCr; - jpeg_set_defaults(&mCompressInfo); - - jpeg_set_quality(&mCompressInfo, quality, TRUE); - // It may seem weird to set color space here again but this will also set - // other fields. These fields might be overwritten by jpeg_set_defaults - jpeg_set_colorspace(&mCompressInfo, JCS_YCbCr); - mCompressInfo.raw_data_in = TRUE; - mCompressInfo.dct_method = JDCT_IFAST; - // Set sampling factors - mCompressInfo.comp_info[0].h_samp_factor = 2; - mCompressInfo.comp_info[0].v_samp_factor = 2; - mCompressInfo.comp_info[1].h_samp_factor = 1; - mCompressInfo.comp_info[1].v_samp_factor = 1; - mCompressInfo.comp_info[2].h_samp_factor = 1; - mCompressInfo.comp_info[2].v_samp_factor = 1; - - mCompressInfo.dest = &mDestManager; - - return true; -} - -static void deinterleave(const uint8_t* vuPlanar, std::vector<uint8_t>& uRows, - std::vector<uint8_t>& vRows, int rowIndex, int width, - int height, int stride) { - int numRows = (height - rowIndex) / 2; - if (numRows > 8) numRows = 8; - for (int row = 0; row < numRows; ++row) { - int offset = ((rowIndex >> 1) + row) * stride; - const uint8_t* vu = vuPlanar + offset; - for (int i = 0; i < (width >> 1); ++i) { - int index = row * (width >> 1) + i; - uRows[index] = vu[1]; - vRows[index] = vu[0]; - vu += 2; - } - } -} - - -bool Compressor::compressData(const unsigned char* data, ExifData* exifData) { - const uint8_t* y[16]; - const uint8_t* cb[8]; - const uint8_t* cr[8]; - const uint8_t** planes[3] = { y, cb, cr }; - - int i, offset; - int width = mCompressInfo.image_width; - int height = mCompressInfo.image_height; - const uint8_t* yPlanar = data; - const uint8_t* vuPlanar = data + (width * height); - std::vector<uint8_t> uRows(8 * (width >> 1)); - std::vector<uint8_t> vRows(8 * (width >> 1)); - - // NOTE! DANGER! Do not construct any non-trivial objects below setjmp! - // The compiler will not generate code to destroy them during the return - // below so they will leak. Additionally, do not place any calls to libjpeg - // that can fail above this line or any error will cause undefined behavior. - if (setjmp(mErrorManager.mJumpBuffer)) { - // This is where the error handler will jump in case compression fails - // The error manager will ALOG an appropriate error message - return false; - } - - jpeg_start_compress(&mCompressInfo, TRUE); - - attachExifData(exifData); - - // process 16 lines of Y and 8 lines of U/V each time. - while (mCompressInfo.next_scanline < mCompressInfo.image_height) { - //deinterleave u and v - deinterleave(vuPlanar, uRows, vRows, mCompressInfo.next_scanline, - width, height, width); - - // Jpeg library ignores the rows whose indices are greater than height. - for (i = 0; i < 16; i++) { - // y row - y[i] = yPlanar + (mCompressInfo.next_scanline + i) * width; - - // construct u row and v row - if ((i & 1) == 0) { - // height and width are both halved because of downsampling - offset = (i >> 1) * (width >> 1); - cb[i/2] = &uRows[offset]; - cr[i/2] = &vRows[offset]; - } - } - jpeg_write_raw_data(&mCompressInfo, const_cast<JSAMPIMAGE>(planes), 16); - } - - jpeg_finish_compress(&mCompressInfo); - jpeg_destroy_compress(&mCompressInfo); - - return true; -} - -bool Compressor::attachExifData(ExifData* exifData) { - if (exifData == nullptr) { - // This is not an error, we don't require EXIF data - return true; - } - - // Save the EXIF data to memory - unsigned char* rawData = nullptr; - unsigned int size = 0; - exif_data_save_data(exifData, &rawData, &size); - if (rawData == nullptr) { - ALOGE("Failed to create EXIF data block"); - return false; - } - - jpeg_write_marker(&mCompressInfo, JPEG_APP0 + 1, rawData, size); - free(rawData); - return true; -} - -Compressor::ErrorManager::ErrorManager() { - error_exit = &onJpegError; -} - -void Compressor::ErrorManager::onJpegError(j_common_ptr cinfo) { - // NOTE! Do not construct any non-trivial objects in this method at the top - // scope. Their destructors will not be called. If you do need such an - // object create a local scope that does not include the longjmp call, - // that ensures the object is destroyed before longjmp is called. - ErrorManager* errorManager = reinterpret_cast<ErrorManager*>(cinfo->err); - - // Format and log error message - char errorMessage[JMSG_LENGTH_MAX]; - (*errorManager->format_message)(cinfo, errorMessage); - errorMessage[sizeof(errorMessage) - 1] = '\0'; - ALOGE("JPEG compression error: %s", errorMessage); - jpeg_destroy(cinfo); - - // And through the looking glass we go - longjmp(errorManager->mJumpBuffer, 1); -} - -Compressor::DestinationManager::DestinationManager() { - init_destination = &initDestination; - empty_output_buffer = &emptyOutputBuffer; - term_destination = &termDestination; -} - -void Compressor::DestinationManager::initDestination(j_compress_ptr cinfo) { - auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest); - - // Start out with some arbitrary but not too large buffer size - manager->mBuffer.resize(16 * 1024); - manager->next_output_byte = &manager->mBuffer[0]; - manager->free_in_buffer = manager->mBuffer.size(); -} - -boolean Compressor::DestinationManager::emptyOutputBuffer( - j_compress_ptr cinfo) { - auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest); - - // Keep doubling the size of the buffer for a very low, amortized - // performance cost of the allocations - size_t oldSize = manager->mBuffer.size(); - manager->mBuffer.resize(oldSize * 2); - manager->next_output_byte = &manager->mBuffer[oldSize]; - manager->free_in_buffer = manager->mBuffer.size() - oldSize; - return manager->free_in_buffer != 0; -} - -void Compressor::DestinationManager::termDestination(j_compress_ptr cinfo) { - auto manager = reinterpret_cast<DestinationManager*>(cinfo->dest); - - // Resize down to the exact size of the output, that is remove as many - // bytes as there are left in the buffer - manager->mBuffer.resize(manager->mBuffer.size() - manager->free_in_buffer); -} - diff --git a/guest/hals/camera/Compressor.h b/guest/hals/camera/Compressor.h deleted file mode 100644 index 10f5e805..00000000 --- a/guest/hals/camera/Compressor.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -#ifndef CUTTLEFISH_CAMERA_JPEG_STUB_COMPRESSOR_H -#define CUTTLEFISH_CAMERA_JPEG_STUB_COMPRESSOR_H - -#include <setjmp.h> -#include <stdlib.h> -extern "C" { -#include <jpeglib.h> -#include <jerror.h> -} - -#include <vector> - -struct _ExifData; -typedef _ExifData ExifData; - -class Compressor { -public: - Compressor(); - - /* Compress |data| which represents raw NV21 encoded data of dimensions - * |width| * |height|. |exifData| is optional EXIF data that will be - * attached to the compressed data if present, set to null if not needed. - */ - bool compress(const unsigned char* data, - int width, int height, int quality, - ExifData* exifData); - - /* Get a reference to the compressed data, this will return an empty vector - * if compress has not been called yet - */ - const std::vector<unsigned char>& getCompressedData() const; - -private: - struct DestinationManager : jpeg_destination_mgr { - DestinationManager(); - - static void initDestination(j_compress_ptr cinfo); - static boolean emptyOutputBuffer(j_compress_ptr cinfo); - static void termDestination(j_compress_ptr cinfo); - - std::vector<unsigned char> mBuffer; - }; - struct ErrorManager : jpeg_error_mgr { - ErrorManager(); - - static void onJpegError(j_common_ptr cinfo); - - jmp_buf mJumpBuffer; - }; - - jpeg_compress_struct mCompressInfo; - DestinationManager mDestManager; - ErrorManager mErrorManager; - - bool configureCompressor(int width, int height, int quality); - bool compressData(const unsigned char* data, ExifData* exifData); - bool attachExifData(ExifData* exifData); -}; - -#endif // CUTTLEFISH_CAMERA_JPEG_STUB_COMPRESSOR_H - diff --git a/guest/hals/camera/Converters.cpp b/guest/hals/camera/Converters.cpp deleted file mode 100644 index 7553d959..00000000 --- a/guest/hals/camera/Converters.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implemenation of framebuffer conversion routines. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Converter" -#include "Converters.h" -#include <log/log.h> - -namespace android { - -static void _YUV420SToRGB565(const uint8_t* Y, const uint8_t* U, - const uint8_t* V, int dUV, uint16_t* rgb, - int width, int height) { - const uint8_t* U_pos = U; - const uint8_t* V_pos = V; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x += 2, U += dUV, V += dUV) { - const uint8_t nU = *U; - const uint8_t nV = *V; - *rgb = YUVToRGB565(*Y, nU, nV); - Y++; - rgb++; - *rgb = YUVToRGB565(*Y, nU, nV); - Y++; - rgb++; - } - if (y & 0x1) { - U_pos = U; - V_pos = V; - } else { - U = U_pos; - V = V_pos; - } - } -} - -static void _YUV420SToRGB32(const uint8_t* Y, const uint8_t* U, - const uint8_t* V, int dUV, uint32_t* rgb, int width, - int height) { - const uint8_t* U_pos = U; - const uint8_t* V_pos = V; - - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x += 2, U += dUV, V += dUV) { - const uint8_t nU = *U; - const uint8_t nV = *V; - *rgb = YUVToRGB32(*Y, nU, nV); - Y++; - rgb++; - *rgb = YUVToRGB32(*Y, nU, nV); - Y++; - rgb++; - } - if (y & 0x1) { - U_pos = U; - V_pos = V; - } else { - U = U_pos; - V = V_pos; - } - } -} - -void YV12ToRGB565(const void* yv12, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12); - const uint8_t* U = Y + pix_total; - const uint8_t* V = U + pix_total / 4; - _YUV420SToRGB565(Y, U, V, 1, reinterpret_cast<uint16_t*>(rgb), width, height); -} - -void YV12ToRGB32(const void* yv12, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* Y = reinterpret_cast<const uint8_t*>(yv12); - const uint8_t* V = Y + pix_total; - const uint8_t* U = V + pix_total / 4; - _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height); -} - -void YU12ToRGB32(const void* yu12, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* Y = reinterpret_cast<const uint8_t*>(yu12); - const uint8_t* U = Y + pix_total; - const uint8_t* V = U + pix_total / 4; - _YUV420SToRGB32(Y, U, V, 1, reinterpret_cast<uint32_t*>(rgb), width, height); -} - -/* Common converter for YUV 4:2:0 interleaved to RGB565. - * y, u, and v point to Y,U, and V panes, where U and V values are interleaved. - */ -static void _NVXXToRGB565(const uint8_t* Y, const uint8_t* U, const uint8_t* V, - uint16_t* rgb, int width, int height) { - _YUV420SToRGB565(Y, U, V, 2, rgb, width, height); -} - -/* Common converter for YUV 4:2:0 interleaved to RGB32. - * y, u, and v point to Y,U, and V panes, where U and V values are interleaved. - */ -static void _NVXXToRGB32(const uint8_t* Y, const uint8_t* U, const uint8_t* V, - uint32_t* rgb, int width, int height) { - _YUV420SToRGB32(Y, U, V, 2, rgb, width, height); -} - -void NV12ToRGB565(const void* nv12, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12); - _NVXXToRGB565(y, y + pix_total, y + pix_total + 1, - reinterpret_cast<uint16_t*>(rgb), width, height); -} - -void NV12ToRGB32(const void* nv12, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* y = reinterpret_cast<const uint8_t*>(nv12); - _NVXXToRGB32(y, y + pix_total, y + pix_total + 1, - reinterpret_cast<uint32_t*>(rgb), width, height); -} - -void NV21ToRGB565(const void* nv21, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21); - _NVXXToRGB565(y, y + pix_total + 1, y + pix_total, - reinterpret_cast<uint16_t*>(rgb), width, height); -} - -void NV21ToRGB32(const void* nv21, void* rgb, int width, int height) { - const int pix_total = width * height; - const uint8_t* y = reinterpret_cast<const uint8_t*>(nv21); - _NVXXToRGB32(y, y + pix_total + 1, y + pix_total, - reinterpret_cast<uint32_t*>(rgb), width, height); -} - -}; /* namespace android */ diff --git a/guest/hals/camera/Converters.h b/guest/hals/camera/Converters.h deleted file mode 100644 index 9d7f6a9a..00000000 --- a/guest/hals/camera/Converters.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_CONVERTERS_H -#define HW_EMULATOR_CAMERA_CONVERTERS_H - -#include <endian.h> - -#ifndef __BYTE_ORDER -#error "could not determine byte order" -#endif - -/* - * Contains declaration of framebuffer conversion routines. - * - * NOTE: RGB and big/little endian considerations. Wherewer in this code RGB - * pixels are represented as WORD, or DWORD, the color order inside the - * WORD / DWORD matches the one that would occur if that WORD / DWORD would have - * been read from the typecasted framebuffer: - * - * const uint32_t rgb = *reinterpret_cast<const uint32_t*>(framebuffer); - * - * So, if this code runs on the little endian CPU, red color in 'rgb' would be - * masked as 0x000000ff, and blue color would be masked as 0x00ff0000, while if - * the code runs on a big endian CPU, the red color in 'rgb' would be masked as - * 0xff000000, and blue color would be masked as 0x0000ff00, - */ - -namespace android { - -/* - * RGB565 color masks - */ - -#if __BYTE_ORDER == __LITTLE_ENDIAN -static const uint16_t kRed5 = 0x001f; -static const uint16_t kGreen6 = 0x07e0; -static const uint16_t kBlue5 = 0xf800; -#else // __BYTE_ORDER -static const uint16_t kRed5 = 0xf800; -static const uint16_t kGreen6 = 0x07e0; -static const uint16_t kBlue5 = 0x001f; -#endif // __BYTE_ORDER -static const uint32_t kBlack16 = 0x0000; -static const uint32_t kWhite16 = kRed5 | kGreen6 | kBlue5; - -/* - * RGB32 color masks - */ - -#if __BYTE_ORDER == __LITTLE_ENDIAN -static const uint32_t kRed8 = 0x000000ff; -static const uint32_t kGreen8 = 0x0000ff00; -static const uint32_t kBlue8 = 0x00ff0000; -#else // __BYTE_ORDER -static const uint32_t kRed8 = 0x00ff0000; -static const uint32_t kGreen8 = 0x0000ff00; -static const uint32_t kBlue8 = 0x000000ff; -#endif // __BYTE_ORDER -static const uint32_t kBlack32 = 0x00000000; -static const uint32_t kWhite32 = kRed8 | kGreen8 | kBlue8; - -/* - * Extracting, and saving color bytes from / to WORD / DWORD RGB. - */ - -#if __BYTE_ORDER == __LITTLE_ENDIAN -/* Extract red, green, and blue bytes from RGB565 word. */ -#define R16(rgb) static_cast<uint8_t>(rgb & kRed5) -#define G16(rgb) static_cast<uint8_t>((rgb & kGreen6) >> 5) -#define B16(rgb) static_cast<uint8_t>((rgb & kBlue5) >> 11) -/* Make 8 bits red, green, and blue, extracted from RGB565 word. */ -#define R16_32(rgb) \ - static_cast<uint8_t>(((rgb & kRed5) << 3) | ((rgb & kRed5) >> 2)) -#define G16_32(rgb) \ - static_cast<uint8_t>(((rgb & kGreen6) >> 3) | ((rgb & kGreen6) >> 9)) -#define B16_32(rgb) \ - static_cast<uint8_t>(((rgb & kBlue5) >> 8) | ((rgb & kBlue5) >> 14)) -/* Extract red, green, and blue bytes from RGB32 dword. */ -#define R32(rgb) static_cast<uint8_t>(rgb & kRed8) -#define G32(rgb) static_cast<uint8_t>(((rgb & kGreen8) >> 8) & 0xff) -#define B32(rgb) static_cast<uint8_t>(((rgb & kBlue8) >> 16) & 0xff) -/* Build RGB565 word from red, green, and blue bytes. */ -#define RGB565(r, g, b) \ - static_cast<uint16_t>((((static_cast<uint16_t>(b) << 6) | g) << 5) | r) -/* Build RGB32 dword from red, green, and blue bytes. */ -#define RGB32(r, g, b) \ - static_cast<uint32_t>((((static_cast<uint32_t>(b) << 8) | g) << 8) | r) -#else // __BYTE_ORDER -/* Extract red, green, and blue bytes from RGB565 word. */ -#define R16(rgb) static_cast<uint8_t>((rgb & kRed5) >> 11) -#define G16(rgb) static_cast<uint8_t>((rgb & kGreen6) >> 5) -#define B16(rgb) static_cast<uint8_t>(rgb & kBlue5) -/* Make 8 bits red, green, and blue, extracted from RGB565 word. */ -#define R16_32(rgb) \ - static_cast<uint8_t>(((rgb & kRed5) >> 8) | ((rgb & kRed5) >> 14)) -#define G16_32(rgb) \ - static_cast<uint8_t>(((rgb & kGreen6) >> 3) | ((rgb & kGreen6) >> 9)) -#define B16_32(rgb) \ - static_cast<uint8_t>(((rgb & kBlue5) << 3) | ((rgb & kBlue5) >> 2)) -/* Extract red, green, and blue bytes from RGB32 dword. */ -#define R32(rgb) static_cast<uint8_t>((rgb & kRed8) >> 16) -#define G32(rgb) static_cast<uint8_t>((rgb & kGreen8) >> 8) -#define B32(rgb) static_cast<uint8_t>(rgb & kBlue8) -/* Build RGB565 word from red, green, and blue bytes. */ -#define RGB565(r, g, b) \ - static_cast<uint16_t>((((static_cast<uint16_t>(r) << 6) | g) << 5) | b) -/* Build RGB32 dword from red, green, and blue bytes. */ -#define RGB32(r, g, b) \ - static_cast<uint32_t>((((static_cast<uint32_t>(r) << 8) | g) << 8) | b) -#endif // __BYTE_ORDER - -/* An union that simplifies breaking 32 bit RGB into separate R, G, and B - * colors. - */ -typedef union RGB32_t { - uint32_t color; - struct { -#if __BYTE_ORDER == __LITTLE_ENDIAN - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; -#else // __BYTE_ORDER - uint8_t a; - uint8_t b; - uint8_t g; - uint8_t r; -#endif // __BYTE_ORDER - }; -} RGB32_t; - -/* Clips a value to the unsigned 0-255 range, treating negative values as zero. - */ -static __inline__ int clamp(int x) { - if (x > 255) return 255; - if (x < 0) return 0; - return x; -} - -/******************************************************************************** - * Basics of RGB -> YUV conversion - *******************************************************************************/ - -/* - * RGB -> YUV conversion macros - */ -#define RGB2Y(r, g, b) \ - (uint8_t)(((66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16) -#define RGB2U(r, g, b) \ - (uint8_t)(((-38 * (r)-74 * (g) + 112 * (b) + 128) >> 8) + 128) -#define RGB2V(r, g, b) \ - (uint8_t)(((112 * (r)-94 * (g)-18 * (b) + 128) >> 8) + 128) - -/* Converts R8 G8 B8 color to YUV. */ -static __inline__ void R8G8B8ToYUV(uint8_t r, uint8_t g, uint8_t b, uint8_t* y, - uint8_t* u, uint8_t* v) { - *y = RGB2Y((int)r, (int)g, (int)b); - *u = RGB2U((int)r, (int)g, (int)b); - *v = RGB2V((int)r, (int)g, (int)b); -} - -/* Converts RGB565 color to YUV. */ -static __inline__ void RGB565ToYUV(uint16_t rgb, uint8_t* y, uint8_t* u, - uint8_t* v) { - R8G8B8ToYUV(R16_32(rgb), G16_32(rgb), B16_32(rgb), y, u, v); -} - -/* Converts RGB32 color to YUV. */ -static __inline__ void RGB32ToYUV(uint32_t rgb, uint8_t* y, uint8_t* u, - uint8_t* v) { - RGB32_t rgb_c; - rgb_c.color = rgb; - R8G8B8ToYUV(rgb_c.r, rgb_c.g, rgb_c.b, y, u, v); -} - -/******************************************************************************** - * Basics of YUV -> RGB conversion. - * Note that due to the fact that guest uses RGB only on preview window, and the - * RGB format that is used is RGB565, we can limit YUV -> RGB conversions to - * RGB565 only. - *******************************************************************************/ - -/* - * YUV -> RGB conversion macros - */ - -/* "Optimized" macros that take specialy prepared Y, U, and V values: - * C = Y - 16 - * D = U - 128 - * E = V - 128 - */ -#define YUV2RO(C, D, E) clamp((298 * (C) + 409 * (E) + 128) >> 8) -#define YUV2GO(C, D, E) clamp((298 * (C)-100 * (D)-208 * (E) + 128) >> 8) -#define YUV2BO(C, D, E) clamp((298 * (C) + 516 * (D) + 128) >> 8) - -/* - * Main macros that take the original Y, U, and V values - */ -#define YUV2R(y, u, v) clamp((298 * ((y)-16) + 409 * ((v)-128) + 128) >> 8) -#define YUV2G(y, u, v) \ - clamp((298 * ((y)-16) - 100 * ((u)-128) - 208 * ((v)-128) + 128) >> 8) -#define YUV2B(y, u, v) clamp((298 * ((y)-16) + 516 * ((u)-128) + 128) >> 8) - -/* Converts YUV color to RGB565. */ -static __inline__ uint16_t YUVToRGB565(int y, int u, int v) { - /* Calculate C, D, and E values for the optimized macro. */ - y -= 16; - u -= 128; - v -= 128; - const uint16_t r = (YUV2RO(y, u, v) >> 3) & 0x1f; - const uint16_t g = (YUV2GO(y, u, v) >> 2) & 0x3f; - const uint16_t b = (YUV2BO(y, u, v) >> 3) & 0x1f; - return RGB565(r, g, b); -} - -/* Converts YUV color to RGB32. */ -static __inline__ uint32_t YUVToRGB32(int y, int u, int v) { - /* Calculate C, D, and E values for the optimized macro. */ - y -= 16; - u -= 128; - v -= 128; - RGB32_t rgb; - rgb.r = YUV2RO(y, u, v) & 0xff; - rgb.g = YUV2GO(y, u, v) & 0xff; - rgb.b = YUV2BO(y, u, v) & 0xff; - return rgb.color; -} - -/* YUV pixel descriptor. */ -struct YUVPixel { - uint8_t Y; - uint8_t U; - uint8_t V; - - inline YUVPixel() : Y(0), U(0), V(0) {} - - inline explicit YUVPixel(uint16_t rgb565) { RGB565ToYUV(rgb565, &Y, &U, &V); } - - inline explicit YUVPixel(uint32_t rgb32) { RGB32ToYUV(rgb32, &Y, &U, &V); } - - inline void get(uint8_t* pY, uint8_t* pU, uint8_t* pV) const { - *pY = Y; - *pU = U; - *pV = V; - } -}; - -/* Converts an YV12 framebuffer to RGB565 framebuffer. - * Param: - * yv12 - YV12 framebuffer. - * rgb - RGB565 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void YV12ToRGB565(const void* yv12, void* rgb, int width, int height); - -/* Converts an YV12 framebuffer to RGB32 framebuffer. - * Param: - * yv12 - YV12 framebuffer. - * rgb - RGB32 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void YV12ToRGB32(const void* yv12, void* rgb, int width, int height); - -/* Converts an YU12 framebuffer to RGB32 framebuffer. - * Param: - * yu12 - YU12 framebuffer. - * rgb - RGB32 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void YU12ToRGB32(const void* yu12, void* rgb, int width, int height); - -/* Converts an NV12 framebuffer to RGB565 framebuffer. - * Param: - * nv12 - NV12 framebuffer. - * rgb - RGB565 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void NV12ToRGB565(const void* nv12, void* rgb, int width, int height); - -/* Converts an NV12 framebuffer to RGB32 framebuffer. - * Param: - * nv12 - NV12 framebuffer. - * rgb - RGB32 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void NV12ToRGB32(const void* nv12, void* rgb, int width, int height); - -/* Converts an NV21 framebuffer to RGB565 framebuffer. - * Param: - * nv21 - NV21 framebuffer. - * rgb - RGB565 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void NV21ToRGB565(const void* nv21, void* rgb, int width, int height); - -/* Converts an NV21 framebuffer to RGB32 framebuffer. - * Param: - * nv21 - NV21 framebuffer. - * rgb - RGB32 framebuffer. - * width, height - Dimensions for both framebuffers. - */ -void NV21ToRGB32(const void* nv21, void* rgb, int width, int height); - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_CONVERTERS_H */ diff --git a/guest/hals/camera/EmulatedBaseCamera.cpp b/guest/hals/camera/EmulatedBaseCamera.cpp deleted file mode 100644 index 8ef553a1..00000000 --- a/guest/hals/camera/EmulatedBaseCamera.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* - * Contains implementation of a class EmulatedBaseCamera that encapsulates - * functionality common to all emulated camera device versions ("fake", - * "webcam", "video file", "cam2.0" etc.). Instances of this class (for each - * emulated camera) are created during the construction of the - * EmulatedCameraFactory instance. This class serves as an entry point for all - * camera API calls that are common across all versions of the - * camera_device_t/camera_module_t structures. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_BaseCamera" -#include <log/log.h> - -#include "EmulatedBaseCamera.h" - -namespace android { - -EmulatedBaseCamera::EmulatedBaseCamera(int cameraId, uint32_t cameraVersion, - struct hw_device_t* device, - struct hw_module_t* module) - : mCameraInfo(NULL), - mCameraID(cameraId), - mCameraDeviceVersion(cameraVersion) { - /* - * Initialize camera_device descriptor for this object. - */ - - /* Common header */ - device->tag = HARDWARE_DEVICE_TAG; - device->version = cameraVersion; - device->module = module; - device->close = NULL; // Must be filled in by child implementation -} - -EmulatedBaseCamera::~EmulatedBaseCamera() {} - -status_t EmulatedBaseCamera::getCameraInfo(struct camera_info* info) { - ALOGV("%s", __FUNCTION__); - - info->device_version = mCameraDeviceVersion; - if (mCameraDeviceVersion >= HARDWARE_DEVICE_API_VERSION(2, 0)) { - info->static_camera_characteristics = mCameraInfo; - } else { - info->static_camera_characteristics = (camera_metadata_t*)0xcafef00d; - } - - return NO_ERROR; -} - -status_t EmulatedBaseCamera::plugCamera() { - ALOGE("%s: not supported", __FUNCTION__); - return INVALID_OPERATION; -} - -status_t EmulatedBaseCamera::unplugCamera() { - ALOGE("%s: not supported", __FUNCTION__); - return INVALID_OPERATION; -} - -camera_device_status_t EmulatedBaseCamera::getHotplugStatus() { - return CAMERA_DEVICE_STATUS_PRESENT; -} - -status_t EmulatedBaseCamera::setTorchMode(bool /* enabled */) { - ALOGE("%s: not supported", __FUNCTION__); - return INVALID_OPERATION; -} - -} /* namespace android */ diff --git a/guest/hals/camera/EmulatedBaseCamera.h b/guest/hals/camera/EmulatedBaseCamera.h deleted file mode 100644 index ba4b98e8..00000000 --- a/guest/hals/camera/EmulatedBaseCamera.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H -#define HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H - -#include <hardware/camera_common.h> -#include <utils/Errors.h> -#include "CameraConfiguration.h" -#include <CameraParameters.h> -using ::android::hardware::camera::common::V1_0::helper::CameraParameters; - -namespace android { - -/* - * Contains declaration of a class EmulatedBaseCamera that encapsulates - * functionality common to all emulated camera device versions ("fake", - * "webcam", "video file", etc.). Instances of this class (for each emulated - * camera) are created during the construction of the EmulatedCameraFactory - * instance. This class serves as an entry point for all camera API calls that - * are common across all versions of the camera_device_t/camera_module_t - * structures. - */ - -class EmulatedBaseCamera { - public: - EmulatedBaseCamera(int cameraId, uint32_t cameraVersion, - struct hw_device_t* device, struct hw_module_t* module); - - virtual ~EmulatedBaseCamera(); - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Initializes EmulatedCamera instance. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - virtual status_t Initialize(const cvd::CameraDefinition& params) = 0; - - /**************************************************************************** - * Camera API implementation - ***************************************************************************/ - - public: - /* Creates connection to the emulated camera device. - * This method is called in response to hw_module_methods_t::open callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negative EXXX statuses. - */ - virtual status_t connectCamera(hw_device_t** device) = 0; - - /* Plug the connection for the emulated camera. Until it's plugged in - * calls to connectCamera should fail with -ENODEV. - */ - virtual status_t plugCamera(); - - /* Unplug the connection from underneath the emulated camera. - * This is similar to closing the camera, except that - * all function calls into the camera device will return - * -EPIPE errors until the camera is reopened. - */ - virtual status_t unplugCamera(); - - virtual camera_device_status_t getHotplugStatus(); - - /* Closes connection to the emulated camera. - * This method is called in response to camera_device::close callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negative EXXX statuses. - */ - virtual status_t closeCamera() = 0; - - /* Gets camera information. - * This method is called in response to camera_module_t::get_camera_info - * callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negative EXXX statuses. - */ - virtual status_t getCameraInfo(struct camera_info* info) = 0; - - /* Gets camera parameters. - * This method is called to collect metadata for (currently) taken picture. - */ - virtual const CameraParameters* getCameraParameters() { - return NULL; - } - - /* Set torch mode. - * This method is called in response to camera_module_t::set_torch_mode - * callback. - */ - virtual status_t setTorchMode(bool enabled); - - /**************************************************************************** - * Data members - ***************************************************************************/ - - protected: - /* Fixed camera information for camera2 devices. Must be valid to access if - * mCameraDeviceVersion is >= HARDWARE_DEVICE_API_VERSION(2,0) */ - camera_metadata_t* mCameraInfo; - - /* Zero-based ID assigned to this camera. */ - int mCameraID; - - private: - /* Version of the camera device HAL implemented by this camera */ - int mCameraDeviceVersion; -}; - -} /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_BASE_CAMERA_H */ diff --git a/guest/hals/camera/EmulatedCamera.cpp b/guest/hals/camera/EmulatedCamera.cpp deleted file mode 100644 index e48d5795..00000000 --- a/guest/hals/camera/EmulatedCamera.cpp +++ /dev/null @@ -1,1034 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedCamera that encapsulates - * functionality common to all emulated cameras ("fake", "webcam", "video file", - * etc.). Instances of this class (for each emulated camera) are created during - * the construction of the EmulatedCameraFactory instance. This class serves as - * an entry point for all camera API calls that defined by camera_device_ops_t - * API. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Camera" -#include <log/log.h> -#include "EmulatedCamera.h" -//#include "EmulatedFakeCameraDevice.h" -#include "Converters.h" - -/* Defines whether we should trace parameter changes. */ -#define DEBUG_PARAM 1 - -namespace android { -namespace { -const char* kSupportedFlashModes[] = { - CameraParameters::FLASH_MODE_OFF, CameraParameters::FLASH_MODE_AUTO, - CameraParameters::FLASH_MODE_ON, CameraParameters::FLASH_MODE_RED_EYE, - CameraParameters::FLASH_MODE_TORCH, NULL}; - -std::string BuildParameterValue(const char** value_array) { - std::string result; - - for (int index = 0; value_array[index] != NULL; ++index) { - if (index) result.append(","); - result.append(value_array[index]); - } - return result; -} - -bool CheckParameterValue(const char* value, const char** supported_values) { - for (int index = 0; supported_values[index] != NULL; ++index) { - if (!strcmp(value, supported_values[index])) return true; - } - return false; -} - -} // namespace - -#if DEBUG_PARAM -/* Calculates and logs parameter changes. - * Param: - * current - Current set of camera parameters. - * new_par - String representation of new parameters. - */ -static void PrintParamDiff(const CameraParameters& current, - const char* new_par); -#else -#define PrintParamDiff(current, new_par) (void(0)) -#endif /* DEBUG_PARAM */ - -EmulatedCamera::EmulatedCamera(int cameraId, struct hw_module_t* module) - : EmulatedBaseCamera(cameraId, HARDWARE_DEVICE_API_VERSION(1, 0), &common, - module), - mPreviewWindow(), - mCallbackNotifier() { - /* camera_device v1 fields. */ - common.close = EmulatedCamera::close; - ops = &mDeviceOps; - priv = this; -} - -EmulatedCamera::~EmulatedCamera() {} - -/**************************************************************************** - * Public API - ***************************************************************************/ - -status_t EmulatedCamera::Initialize(const cvd::CameraDefinition&) { - /* Preview formats supported by this HAL. */ - char preview_formats[1024]; - snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s", - CameraParameters::PIXEL_FORMAT_YUV420SP, - CameraParameters::PIXEL_FORMAT_YUV420P, - CameraParameters::PIXEL_FORMAT_RGBA8888); - - /* - * Fake required parameters. - */ - - mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, - "320x240,0x0"); - - mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512"); - mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384"); - mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90"); - mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31"); - mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8"); - mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5"); - mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90"); - - /* Preview format settings used here are related to panoramic view only. It's - * not related to the preview window that works only with RGB frames, which - * is explicitly stated when set_buffers_geometry is called on the preview - * window object. */ - mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, - preview_formats); - mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP); - - /* We don't relay on the actual frame rates supported by the camera device, - * since we will emulate them through timeouts in the emulated camera device - * worker thread. */ - mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, - "30,24,20,15,10,5"); - mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, - "(5000,30000),(15000,15000),(30000,30000)"); - mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5000,30000"); - mParameters.setPreviewFrameRate(30000); - - /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */ - mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, - CameraParameters::PIXEL_FORMAT_YUV420P); - mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, - CameraParameters::PIXEL_FORMAT_JPEG); - mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG); - - /* Set exposure compensation. */ - mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6"); - mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6"); - mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5"); - mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); - - /* Sets the white balance modes and the device-dependent scale factors. */ - char supported_white_balance[1024]; - snprintf(supported_white_balance, sizeof(supported_white_balance), - "%s,%s,%s,%s", CameraParameters::WHITE_BALANCE_AUTO, - CameraParameters::WHITE_BALANCE_INCANDESCENT, - CameraParameters::WHITE_BALANCE_DAYLIGHT, - CameraParameters::WHITE_BALANCE_TWILIGHT); - mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, - supported_white_balance); - mParameters.set(CameraParameters::KEY_WHITE_BALANCE, - CameraParameters::WHITE_BALANCE_AUTO); - getCameraDevice()->initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f); - getCameraDevice()->initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f); - getCameraDevice()->initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f); - getCameraDevice()->initializeWhiteBalanceModes( - CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f); - getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO); - - /* - * Not supported features - */ - mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, - CameraParameters::FOCUS_MODE_FIXED); - mParameters.set(CameraParameters::KEY_FOCUS_MODE, - CameraParameters::FOCUS_MODE_FIXED); - mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES, - BuildParameterValue(kSupportedFlashModes).c_str()); - mParameters.set(CameraParameters::KEY_FLASH_MODE, - CameraParameters::FLASH_MODE_OFF); - mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, "0.1,0.1,0.1"); - mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "0"); - mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, "0"); - mParameters.set(CameraParameters::KEY_ZOOM_RATIOS, "100"); - mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED, - CameraParameters::FALSE); - mParameters.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED, - CameraParameters::FALSE); - mParameters.set(CameraParameters::KEY_ZOOM, "0"); - mParameters.set(CameraParameters::KEY_MAX_ZOOM, "0"); - - return NO_ERROR; -} - -void EmulatedCamera::onNextFrameAvailable(const void* frame, nsecs_t timestamp, - EmulatedCameraDevice* camera_dev) { - /* Notify the preview window first. */ - mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev); - - /* Notify callback notifier next. */ - mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev); -} - -void EmulatedCamera::onCameraDeviceError(int err) { - /* Errors are reported through the callback notifier */ - mCallbackNotifier.onCameraDeviceError(err); -} - -void EmulatedCamera::onCameraFocusAcquired() { - mCallbackNotifier.onCameraFocusAcquired(); -} - -/**************************************************************************** - * Camera API implementation. - ***************************************************************************/ - -status_t EmulatedCamera::connectCamera(hw_device_t** device) { - ALOGV("%s", __FUNCTION__); - - status_t res = EINVAL; - EmulatedCameraDevice* const camera_dev = getCameraDevice(); - ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__); - - if (camera_dev != NULL) { - /* Connect to the camera device. */ - res = getCameraDevice()->connectDevice(); - if (res == NO_ERROR) { - *device = &common; - } - } - - return -res; -} - -status_t EmulatedCamera::closeCamera() { - ALOGV("%s", __FUNCTION__); - - return cleanupCamera(); -} - -status_t EmulatedCamera::getCameraInfo(struct camera_info* info) { - ALOGV("%s", __FUNCTION__); - - const char* valstr = NULL; - - valstr = mParameters.get(EmulatedCamera::FACING_KEY); - if (valstr != NULL) { - if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) { - info->facing = CAMERA_FACING_FRONT; - } else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) { - info->facing = CAMERA_FACING_BACK; - } - } else { - info->facing = CAMERA_FACING_BACK; - } - - valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY); - if (valstr != NULL) { - info->orientation = atoi(valstr); - } else { - info->orientation = 0; - } - - info->resource_cost = 100; - info->conflicting_devices = NULL; - info->conflicting_devices_length = 0; - - return EmulatedBaseCamera::getCameraInfo(info); -} - -const CameraParameters* EmulatedCamera::getCameraParameters() { - return &mParameters; -} - -status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window) { - /* Callback should return a negative errno. */ - return -mPreviewWindow.setPreviewWindow(window, - mParameters.getPreviewFrameRate()); -} - -void EmulatedCamera::setCallbacks( - camera_notify_callback notify_cb, camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user) { - mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, - get_memory, user); -} - -void EmulatedCamera::enableMsgType(int32_t msg_type) { - mCallbackNotifier.enableMessage(msg_type); -} - -void EmulatedCamera::disableMsgType(int32_t msg_type) { - mCallbackNotifier.disableMessage(msg_type); -} - -int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type) { - return mCallbackNotifier.isMessageEnabled(msg_type); -} - -status_t EmulatedCamera::startPreview() { - /* Callback should return a negative errno. */ - return -doStartPreview(); -} - -void EmulatedCamera::stopPreview() { doStopPreview(); } - -int EmulatedCamera::isPreviewEnabled() { - return mPreviewWindow.isPreviewEnabled(); -} - -status_t EmulatedCamera::storeMetaDataInBuffers(int enable) { - /* Callback should return a negative errno. */ - return -mCallbackNotifier.storeMetaDataInBuffers(enable); -} - -status_t EmulatedCamera::startRecording() { - /* Callback should return a negative errno. */ - return -mCallbackNotifier.enableVideoRecording( - mParameters.getPreviewFrameRate()); -} - -void EmulatedCamera::stopRecording() { - mCallbackNotifier.disableVideoRecording(); -} - -int EmulatedCamera::isRecordingEnabled() { - return mCallbackNotifier.isVideoRecordingEnabled(); -} - -void EmulatedCamera::releaseRecordingFrame(const void* opaque) { - mCallbackNotifier.releaseRecordingFrame(opaque); -} - -status_t EmulatedCamera::setAutoFocus() { - ALOGV("%s", __FUNCTION__); - - /* Trigger auto-focus. Focus response cannot be sent directly from here. */ - getCameraDevice()->startAutoFocus(); - - /* TODO: Future enhancements. */ - return NO_ERROR; -} - -status_t EmulatedCamera::cancelAutoFocus() { - ALOGV("%s", __FUNCTION__); - - /* TODO: Future enhancements. */ - return NO_ERROR; -} - -status_t EmulatedCamera::takePicture() { - ALOGV("%s", __FUNCTION__); - - status_t res; - int width, height; - uint32_t org_fmt; - - /* Collect frame info for the picture. */ - mParameters.getPictureSize(&width, &height); - const char* pix_fmt = mParameters.getPictureFormat(); - if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { - org_fmt = V4L2_PIX_FMT_YUV420; - } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) { - org_fmt = V4L2_PIX_FMT_RGB32; - } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { - org_fmt = V4L2_PIX_FMT_NV21; - } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) { - /* We only have JPEG converted for NV21 format. */ - org_fmt = V4L2_PIX_FMT_NV21; - } else { - ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt); - return EINVAL; - } - /* Get JPEG quality. */ - int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY); - if (jpeg_quality <= 0) { - jpeg_quality = 90; /* Fall back to default. */ - } - - /* - * Make sure preview is not running, and device is stopped before taking - * picture. - */ - - const bool preview_on = mPreviewWindow.isPreviewEnabled(); - if (preview_on) { - doStopPreview(); - } - - /* Camera device should have been stopped when the shutter message has been - * enabled. */ - EmulatedCameraDevice* const camera_dev = getCameraDevice(); - if (camera_dev->isStarted()) { - ALOGW("%s: Camera device is started", __FUNCTION__); - camera_dev->stopDeliveringFrames(); - camera_dev->stopDevice(); - } - - /* Compute target FPS rate. - * Pretend to simulate generation of (max_fps_rate) */ - int min_fps_rate, max_fps_rate; - mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate); - - /* - * Take the picture now. - */ - - /* Start camera device for the picture frame. */ - ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]", - reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height); - res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate); - if (res != NO_ERROR) { - if (preview_on) { - doStartPreview(); - } - return res; - } - - /* Deliver one frame only. */ - mCallbackNotifier.setJpegQuality(jpeg_quality); - mCallbackNotifier.setTakingPicture(true); - res = camera_dev->startDeliveringFrames(true); - if (res != NO_ERROR) { - mCallbackNotifier.setTakingPicture(false); - if (preview_on) { - doStartPreview(); - } - } - return res; -} - -status_t EmulatedCamera::cancelPicture() { - ALOGV("%s", __FUNCTION__); - - return NO_ERROR; -} - -status_t EmulatedCamera::setParameters(const char* parms) { - ALOGV("%s", __FUNCTION__); - PrintParamDiff(mParameters, parms); - - CameraParameters new_param; - String8 str8_param(parms); - new_param.unflatten(str8_param); - - /* - * Check if requested dimensions are valid. - */ - if (!CheckParameterValue(new_param.get(CameraParameters::KEY_FLASH_MODE), - kSupportedFlashModes)) { - ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__, - new_param.get(CameraParameters::KEY_FLASH_MODE)); - return -EINVAL; - } - if (strcmp(new_param.get(CameraParameters::KEY_FOCUS_MODE), - CameraParameters::FOCUS_MODE_FIXED)) { - ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__, - new_param.get(CameraParameters::KEY_FOCUS_MODE)); - return -EINVAL; - } - - int preview_width, preview_height; - new_param.getPreviewSize(&preview_width, &preview_height); - if (preview_width <= 0 || preview_height <= 0) return -EINVAL; - - /* - * Check for new exposure compensation parameter. - */ - int new_exposure_compensation = - new_param.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); - const int min_exposure_compensation = - new_param.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); - const int max_exposure_compensation = - new_param.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); - - // Checks if the exposure compensation change is supported. - if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) { - if (new_exposure_compensation > max_exposure_compensation) { - new_exposure_compensation = max_exposure_compensation; - } - if (new_exposure_compensation < min_exposure_compensation) { - new_exposure_compensation = min_exposure_compensation; - } - - const int current_exposure_compensation = - mParameters.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION); - if (current_exposure_compensation != new_exposure_compensation) { - const float exposure_value = - new_exposure_compensation * - new_param.getFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP); - - getCameraDevice()->setExposureCompensation(exposure_value); - } - } - - const char* new_white_balance = - new_param.get(CameraParameters::KEY_WHITE_BALANCE); - const char* supported_white_balance = - new_param.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE); - - if ((supported_white_balance != NULL) && (new_white_balance != NULL) && - (strstr(supported_white_balance, new_white_balance) != NULL)) { - const char* current_white_balance = - mParameters.get(CameraParameters::KEY_WHITE_BALANCE); - if ((current_white_balance == NULL) || - (strcmp(current_white_balance, new_white_balance) != 0)) { - ALOGV("Setting white balance to %s", new_white_balance); - getCameraDevice()->setWhiteBalanceMode(new_white_balance); - } - } - - mParameters = new_param; - - return NO_ERROR; -} - -/* A dumb variable indicating "no params" / error on the exit from - * EmulatedCamera::getParameters(). */ -static char lNoParam = '\0'; -char* EmulatedCamera::getParameters() { - String8 params(mParameters.flatten()); - char* ret_str = - reinterpret_cast<char*>(malloc(sizeof(char) * (params.length() + 1))); - memset(ret_str, 0, params.length() + 1); - if (ret_str != NULL) { - strncpy(ret_str, params.string(), params.length() + 1); - return ret_str; - } else { - ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, - params.string()); - /* Apparently, we can't return NULL fron this routine. */ - return &lNoParam; - } -} - -void EmulatedCamera::putParameters(char* params) { - /* This method simply frees parameters allocated in getParameters(). */ - if (params != NULL && params != &lNoParam) { - free(params); - } -} - -status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { - ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2); - - switch (cmd) { - case CAMERA_CMD_START_FACE_DETECTION: - case CAMERA_CMD_STOP_FACE_DETECTION: - return -EINVAL; - } - - /* TODO: Future enhancements. */ - return 0; -} - -void EmulatedCamera::releaseCamera() { - ALOGV("%s", __FUNCTION__); - - cleanupCamera(); -} - -status_t EmulatedCamera::dumpCamera(int /*fd*/) { - ALOGV("%s", __FUNCTION__); - - /* TODO: Future enhancements. */ - return -EINVAL; -} - -/**************************************************************************** - * Preview management. - ***************************************************************************/ - -status_t EmulatedCamera::doStartPreview() { - ALOGV("%s", __FUNCTION__); - - EmulatedCameraDevice* camera_dev = getCameraDevice(); - if (camera_dev->isStarted()) { - camera_dev->stopDeliveringFrames(); - camera_dev->stopDevice(); - } - - status_t res = mPreviewWindow.startPreview(); - if (res != NO_ERROR) { - return res; - } - - /* Make sure camera device is connected. */ - if (!camera_dev->isConnected()) { - res = camera_dev->connectDevice(); - if (res != NO_ERROR) { - mPreviewWindow.stopPreview(); - return res; - } - } - - int width, height; - /* Lets see what should we use for frame width, and height. */ - if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) { - mParameters.getVideoSize(&width, &height); - } else { - mParameters.getPreviewSize(&width, &height); - } - /* Lets see what should we use for the frame pixel format. Note that there - * are two parameters that define pixel formats for frames sent to the - * application via notification callbacks: - * - KEY_VIDEO_FRAME_FORMAT, that is used when recording video, and - * - KEY_PREVIEW_FORMAT, that is used for preview frame notification. - * We choose one or the other, depending on "recording-hint" property set by - * the framework that indicating intention: video, or preview. */ - const char* pix_fmt = NULL; - const char* is_video = mParameters.get(EmulatedCamera::RECORDING_HINT_KEY); - if (is_video == NULL) { - is_video = CameraParameters::FALSE; - } - if (strcmp(is_video, CameraParameters::TRUE) == 0) { - /* Video recording is requested. Lets see if video frame format is set. */ - pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT); - } - /* If this was not video recording, or video frame format is not set, lets - * use preview pixel format for the main framebuffer. */ - if (pix_fmt == NULL) { - pix_fmt = mParameters.getPreviewFormat(); - } - if (pix_fmt == NULL) { - ALOGE("%s: Unable to obtain video format", __FUNCTION__); - mPreviewWindow.stopPreview(); - return EINVAL; - } - - /* Convert framework's pixel format to the FOURCC one. */ - uint32_t org_fmt; - if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { - org_fmt = V4L2_PIX_FMT_YUV420; - } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) { - org_fmt = V4L2_PIX_FMT_RGB32; - } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { - org_fmt = V4L2_PIX_FMT_NV21; - } else { - ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt); - mPreviewWindow.stopPreview(); - return EINVAL; - } - - /* Fetch the desired frame rate. */ - int min_fps_rate, max_fps_rate; - mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate); - - ALOGD("Starting camera: %dx%d -> %.4s(%s)", width, height, - reinterpret_cast<const char*>(&org_fmt), pix_fmt); - res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate); - if (res != NO_ERROR) { - mPreviewWindow.stopPreview(); - return res; - } - - res = camera_dev->startDeliveringFrames(false); - if (res != NO_ERROR) { - camera_dev->stopDevice(); - mPreviewWindow.stopPreview(); - } - - return res; -} - -status_t EmulatedCamera::doStopPreview() { - ALOGV("%s", __FUNCTION__); - - status_t res = NO_ERROR; - if (mPreviewWindow.isPreviewEnabled()) { - /* Stop the camera. */ - if (getCameraDevice()->isStarted()) { - getCameraDevice()->stopDeliveringFrames(); - res = getCameraDevice()->stopDevice(); - } - - if (res == NO_ERROR) { - /* Disable preview as well. */ - mPreviewWindow.stopPreview(); - } - } - - return NO_ERROR; -} - -/**************************************************************************** - * Private API. - ***************************************************************************/ - -status_t EmulatedCamera::cleanupCamera() { - status_t res = NO_ERROR; - - /* If preview is running - stop it. */ - res = doStopPreview(); - if (res != NO_ERROR) { - return -res; - } - - /* Stop and disconnect the camera device. */ - EmulatedCameraDevice* const camera_dev = getCameraDevice(); - if (camera_dev != NULL) { - if (camera_dev->isStarted()) { - camera_dev->stopDeliveringFrames(); - res = camera_dev->stopDevice(); - if (res != NO_ERROR) { - return -res; - } - } - if (camera_dev->isConnected()) { - res = camera_dev->disconnectDevice(); - if (res != NO_ERROR) { - return -res; - } - } - } - - mCallbackNotifier.cleanupCBNotifier(); - - return NO_ERROR; -} - -/**************************************************************************** - * Camera API callbacks as defined by camera_device_ops structure. - * - * Callbacks here simply dispatch the calls to an appropriate method inside - * EmulatedCamera instance, defined by the 'dev' parameter. - ***************************************************************************/ - -int EmulatedCamera::set_preview_window(struct camera_device* dev, - struct preview_stream_ops* window) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->setPreviewWindow(window); -} - -void EmulatedCamera::set_callbacks( - struct camera_device* dev, camera_notify_callback notify_cb, - camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user); -} - -void EmulatedCamera::enable_msg_type(struct camera_device* dev, - int32_t msg_type) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->enableMsgType(msg_type); -} - -void EmulatedCamera::disable_msg_type(struct camera_device* dev, - int32_t msg_type) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->disableMsgType(msg_type); -} - -int EmulatedCamera::msg_type_enabled(struct camera_device* dev, - int32_t msg_type) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->isMsgTypeEnabled(msg_type); -} - -int EmulatedCamera::start_preview(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->startPreview(); -} - -void EmulatedCamera::stop_preview(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->stopPreview(); -} - -int EmulatedCamera::preview_enabled(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->isPreviewEnabled(); -} - -int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev, - int enable) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->storeMetaDataInBuffers(enable); -} - -int EmulatedCamera::start_recording(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->startRecording(); -} - -void EmulatedCamera::stop_recording(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->stopRecording(); -} - -int EmulatedCamera::recording_enabled(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->isRecordingEnabled(); -} - -void EmulatedCamera::release_recording_frame(struct camera_device* dev, - const void* opaque) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->releaseRecordingFrame(opaque); -} - -int EmulatedCamera::auto_focus(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->setAutoFocus(); -} - -int EmulatedCamera::cancel_auto_focus(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->cancelAutoFocus(); -} - -int EmulatedCamera::take_picture(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->takePicture(); -} - -int EmulatedCamera::cancel_picture(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->cancelPicture(); -} - -int EmulatedCamera::set_parameters(struct camera_device* dev, - const char* parms) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->setParameters(parms); -} - -char* EmulatedCamera::get_parameters(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return NULL; - } - return ec->getParameters(); -} - -void EmulatedCamera::put_parameters(struct camera_device* dev, char* params) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->putParameters(params); -} - -int EmulatedCamera::send_command(struct camera_device* dev, int32_t cmd, - int32_t arg1, int32_t arg2) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->sendCommand(cmd, arg1, arg2); -} - -void EmulatedCamera::release(struct camera_device* dev) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return; - } - ec->releaseCamera(); -} - -int EmulatedCamera::dump(struct camera_device* dev, int fd) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->dumpCamera(fd); -} - -int EmulatedCamera::close(struct hw_device_t* device) { - EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>( - reinterpret_cast<struct camera_device*>(device)->priv); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); - return -EINVAL; - } - return ec->closeCamera(); -} - -/**************************************************************************** - * Static initializer for the camera callback API - ****************************************************************************/ - -camera_device_ops_t EmulatedCamera::mDeviceOps = { - EmulatedCamera::set_preview_window, - EmulatedCamera::set_callbacks, - EmulatedCamera::enable_msg_type, - EmulatedCamera::disable_msg_type, - EmulatedCamera::msg_type_enabled, - EmulatedCamera::start_preview, - EmulatedCamera::stop_preview, - EmulatedCamera::preview_enabled, - EmulatedCamera::store_meta_data_in_buffers, - EmulatedCamera::start_recording, - EmulatedCamera::stop_recording, - EmulatedCamera::recording_enabled, - EmulatedCamera::release_recording_frame, - EmulatedCamera::auto_focus, - EmulatedCamera::cancel_auto_focus, - EmulatedCamera::take_picture, - EmulatedCamera::cancel_picture, - EmulatedCamera::set_parameters, - EmulatedCamera::get_parameters, - EmulatedCamera::put_parameters, - EmulatedCamera::send_command, - EmulatedCamera::release, - EmulatedCamera::dump}; - -/**************************************************************************** - * Common keys - ***************************************************************************/ - -const char EmulatedCamera::FACING_KEY[] = "prop-facing"; -const char EmulatedCamera::ORIENTATION_KEY[] = "prop-orientation"; -const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint"; - -/**************************************************************************** - * Common string values - ***************************************************************************/ - -const char EmulatedCamera::FACING_BACK[] = "back"; -const char EmulatedCamera::FACING_FRONT[] = "front"; - -/**************************************************************************** - * Parameter debugging helpers - ***************************************************************************/ - -#if DEBUG_PARAM -static void PrintParamDiff(const CameraParameters& current, - const char* new_par) { - char tmp[2048]; - const char* wrk = new_par; - - /* Divided with ';' */ - const char* next = strchr(wrk, ';'); - while (next != NULL) { - snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next - wrk), wrk); - /* in the form key=value */ - char* val = strchr(tmp, '='); - if (val != NULL) { - *val = '\0'; - val++; - const char* in_current = current.get(tmp); - if (in_current != NULL) { - if (strcmp(in_current, val)) { - ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val); - } - } else { - ALOGD("+++ New parameter: %s=%s", tmp, val); - } - } else { - ALOGW("No value separator in %s", tmp); - } - wrk = next + 1; - next = strchr(wrk, ';'); - } -} -#endif /* DEBUG_PARAM */ - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedCamera.h b/guest/hals/camera/EmulatedCamera.h deleted file mode 100644 index a2de643e..00000000 --- a/guest/hals/camera/EmulatedCamera.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_H - -/* - * Contains declaration of a class EmulatedCamera that encapsulates - * functionality common to all version 1.0 emulated camera devices ("fake", - * "webcam", "video file", etc.). Instances of this class (for each emulated - * camera) are created during the construction of the EmulatedCameraFactory - * instance. This class serves as an entry point for all camera API calls that - * defined by camera_device_ops_t API. - */ - -#include <CameraParameters.h> -using ::android::hardware::camera::common::V1_0::helper::CameraParameters; -using ::android::hardware::camera::common::V1_0::helper::Size; - -#include "CallbackNotifier.h" -#include "EmulatedBaseCamera.h" -#include "EmulatedCameraDevice.h" -#include "PreviewWindow.h" - -namespace android { - -/* Encapsulates functionality common to all version 1.0 emulated camera devices - * ("fake", "webcam", "file stream", etc.). - * - * Note that EmulatedCameraFactory instantiates object of this class just once, - * when EmulatedCameraFactory instance gets constructed. Connection to / - * disconnection from the actual camera device is handled by calls to - * connectDevice(), and closeCamera() methods of this class that are ivoked in - * response to hw_module_methods_t::open, and camera_device::close callbacks. - */ -class EmulatedCamera : public camera_device, public EmulatedBaseCamera { - public: - /* Constructs EmulatedCamera instance. - * Param: - * cameraId - Zero based camera identifier, which is an index of the camera - * instance in camera factory's array. - * module - Emulated camera HAL module descriptor. - */ - EmulatedCamera(int cameraId, struct hw_module_t* module); - - /* Destructs EmulatedCamera instance. */ - virtual ~EmulatedCamera(); - - /**************************************************************************** - * Abstract API - ***************************************************************************/ - - public: - /* Gets emulated camera device used by this instance of the emulated camera. - */ - virtual EmulatedCameraDevice* getCameraDevice() = 0; - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /** Override of base class method */ - virtual status_t Initialize(const cvd::CameraDefinition& properties); - - /* Next frame is available in the camera device. - * This is a notification callback that is invoked by the camera device when - * a new frame is available. - * Note that most likely this method is called in context of a worker thread - * that camera device has created for frame capturing. - * Param: - * frame - Captured frame, or NULL if camera device didn't pull the frame - * yet. If NULL is passed in this parameter use GetCurrentFrame method - * of the camera device class to obtain the next frame. Also note that - * the size of the frame that is passed here (as well as the frame - * returned from the GetCurrentFrame method) is defined by the current - * frame settings (width + height + pixel format) for the camera device. - * timestamp - Frame's timestamp. - * camera_dev - Camera device instance that delivered the frame. - */ - virtual void onNextFrameAvailable(const void* frame, nsecs_t timestamp, - EmulatedCameraDevice* camera_dev); - - /* Entry point for notifications that occur in camera device. - * Param: - * err - CAMERA_ERROR_XXX error code. - */ - virtual void onCameraDeviceError(int err); - - /* Device acquired focus. - * This is a notification callback that is invoked by the camera device - * when focusing operation (requested by client) completes. - */ - virtual void onCameraFocusAcquired(); - - /**************************************************************************** - * Camera API implementation - ***************************************************************************/ - - public: - /** Override of base class method */ - virtual status_t connectCamera(hw_device_t** device); - - /** Override of base class method */ - virtual status_t closeCamera(); - - /** Override of base class method */ - virtual status_t getCameraInfo(struct camera_info* info); - - /** Override of base class method */ - virtual const CameraParameters* getCameraParameters() override; - - /**************************************************************************** - * Camera API implementation. - * These methods are called from the camera API callback routines. - ***************************************************************************/ - - protected: - /* Actual handler for camera_device_ops_t::set_preview_window callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t setPreviewWindow(struct preview_stream_ops* window); - - /* Actual handler for camera_device_ops_t::set_callbacks callback. - * NOTE: When this method is called the object is locked. - */ - virtual void setCallbacks(camera_notify_callback notify_cb, - camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user); - - /* Actual handler for camera_device_ops_t::enable_msg_type callback. - * NOTE: When this method is called the object is locked. - */ - virtual void enableMsgType(int32_t msg_type); - - /* Actual handler for camera_device_ops_t::disable_msg_type callback. - * NOTE: When this method is called the object is locked. - */ - virtual void disableMsgType(int32_t msg_type); - - /* Actual handler for camera_device_ops_t::msg_type_enabled callback. - * NOTE: When this method is called the object is locked. - * Return: - * 0 if message(s) is (are) disabled, != 0 if enabled. - */ - virtual int isMsgTypeEnabled(int32_t msg_type); - - /* Actual handler for camera_device_ops_t::start_preview callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t startPreview(); - - /* Actual handler for camera_device_ops_t::stop_preview callback. - * NOTE: When this method is called the object is locked. - */ - virtual void stopPreview(); - - /* Actual handler for camera_device_ops_t::preview_enabled callback. - * NOTE: When this method is called the object is locked. - * Return: - * 0 if preview is disabled, != 0 if enabled. - */ - virtual int isPreviewEnabled(); - - /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers - * callback. NOTE: When this method is called the object is locked. Note that - * failures in this method are reported as negave EXXX statuses. - */ - virtual status_t storeMetaDataInBuffers(int enable); - - /* Actual handler for camera_device_ops_t::start_recording callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t startRecording(); - - /* Actual handler for camera_device_ops_t::stop_recording callback. - * NOTE: When this method is called the object is locked. - */ - virtual void stopRecording(); - - /* Actual handler for camera_device_ops_t::recording_enabled callback. - * NOTE: When this method is called the object is locked. - * Return: - * 0 if recording is disabled, != 0 if enabled. - */ - virtual int isRecordingEnabled(); - - /* Actual handler for camera_device_ops_t::release_recording_frame callback. - * NOTE: When this method is called the object is locked. - */ - virtual void releaseRecordingFrame(const void* opaque); - - /* Actual handler for camera_device_ops_t::auto_focus callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t setAutoFocus(); - - /* Actual handler for camera_device_ops_t::cancel_auto_focus callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t cancelAutoFocus(); - - /* Actual handler for camera_device_ops_t::take_picture callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t takePicture(); - - /* Actual handler for camera_device_ops_t::cancel_picture callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t cancelPicture(); - - /* Actual handler for camera_device_ops_t::set_parameters callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t setParameters(const char* parms); - - /* Actual handler for camera_device_ops_t::get_parameters callback. - * NOTE: When this method is called the object is locked. - * Return: - * Flattened parameters string. The caller will free the buffer allocated - * for the string by calling camera_device_ops_t::put_parameters callback. - */ - virtual char* getParameters(); - - /* Actual handler for camera_device_ops_t::put_parameters callback. - * Called to free the string returned from camera_device_ops_t::get_parameters - * callback. There is nothing more to it: the name of the callback is just - * misleading. - * NOTE: When this method is called the object is locked. - */ - virtual void putParameters(char* params); - - /* Actual handler for camera_device_ops_t::send_command callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); - - /* Actual handler for camera_device_ops_t::release callback. - * NOTE: When this method is called the object is locked. - */ - virtual void releaseCamera(); - - /* Actual handler for camera_device_ops_t::dump callback. - * NOTE: When this method is called the object is locked. - * Note that failures in this method are reported as negave EXXX statuses. - */ - virtual status_t dumpCamera(int fd); - - /**************************************************************************** - * Preview management. - ***************************************************************************/ - - protected: - /* Starts preview. - * Note that when this method is called mPreviewWindow may be NULL, - * indicating that framework has an intention to start displaying video - * frames, but didn't create the preview window yet. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - virtual status_t doStartPreview(); - - /* Stops preview. - * This method reverts DoStartPreview. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - virtual status_t doStopPreview(); - - /**************************************************************************** - * Private API. - ***************************************************************************/ - - protected: - /* Cleans up camera when released. */ - virtual status_t cleanupCamera(); - - /**************************************************************************** - * Camera API callbacks as defined by camera_device_ops structure. - * See hardware/libhardware/include/hardware/camera.h for information on - * each of these callbacks. Implemented in this class, these callbacks simply - * dispatch the call into an instance of EmulatedCamera class defined by the - * 'camera_device' parameter. - ***************************************************************************/ - - private: - static int set_preview_window(struct camera_device* dev, - struct preview_stream_ops* window); - - static void set_callbacks(struct camera_device* dev, - camera_notify_callback notify_cb, - camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, void* user); - - static void enable_msg_type(struct camera_device* dev, int32_t msg_type); - - static void disable_msg_type(struct camera_device* dev, int32_t msg_type); - - static int msg_type_enabled(struct camera_device* dev, int32_t msg_type); - - static int start_preview(struct camera_device* dev); - - static void stop_preview(struct camera_device* dev); - - static int preview_enabled(struct camera_device* dev); - - static int store_meta_data_in_buffers(struct camera_device* dev, int enable); - - static int start_recording(struct camera_device* dev); - - static void stop_recording(struct camera_device* dev); - - static int recording_enabled(struct camera_device* dev); - - static void release_recording_frame(struct camera_device* dev, - const void* opaque); - - static int auto_focus(struct camera_device* dev); - - static int cancel_auto_focus(struct camera_device* dev); - - static int take_picture(struct camera_device* dev); - - static int cancel_picture(struct camera_device* dev); - - static int set_parameters(struct camera_device* dev, const char* parms); - - static char* get_parameters(struct camera_device* dev); - - static void put_parameters(struct camera_device* dev, char* params); - - static int send_command(struct camera_device* dev, int32_t cmd, int32_t arg1, - int32_t arg2); - - static void release(struct camera_device* dev); - - static int dump(struct camera_device* dev, int fd); - - static int close(struct hw_device_t* device); - - /**************************************************************************** - * Data members - ***************************************************************************/ - - protected: - /* Locks this instance for parameters, state, etc. change. */ - Mutex mObjectLock; - - /* Camera parameters. */ - CameraParameters mParameters; - - /* Preview window. */ - PreviewWindow mPreviewWindow; - - /* Callback notifier. */ - CallbackNotifier mCallbackNotifier; - - private: - /* Registered callbacks implementing camera API. */ - static camera_device_ops_t mDeviceOps; - - /**************************************************************************** - * Common keys - ***************************************************************************/ - - public: - static const char FACING_KEY[]; - static const char ORIENTATION_KEY[]; - static const char RECORDING_HINT_KEY[]; - - /**************************************************************************** - * Common string values - ***************************************************************************/ - - /* Possible values for FACING_KEY */ - static const char FACING_BACK[]; - static const char FACING_FRONT[]; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_H */ diff --git a/guest/hals/camera/EmulatedCamera2.cpp b/guest/hals/camera/EmulatedCamera2.cpp deleted file mode 100644 index ccb8006f..00000000 --- a/guest/hals/camera/EmulatedCamera2.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* - * Contains implementation of a class EmulatedCamera that encapsulates - * functionality common to all version 2.0 emulated camera devices. Instances - * of this class (for each emulated camera) are created during the construction - * of the EmulatedCameraFactory instance. This class serves as an entry point - * for all camera API calls that defined by camera2_device_ops_t API. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera2_Camera" -#include <log/log.h> - -#include "EmulatedCamera2.h" -#include "system/camera_metadata.h" - -namespace android { - -/* Constructs EmulatedCamera2 instance. - * Param: - * cameraId - Zero based camera identifier, which is an index of the camera - * instance in camera factory's array. - * module - Emulated camera HAL module descriptor. - */ -EmulatedCamera2::EmulatedCamera2(int cameraId, struct hw_module_t *module) - : EmulatedBaseCamera(cameraId, CAMERA_DEVICE_API_VERSION_2_0, &common, - module) { - common.close = EmulatedCamera2::close; - ops = &sDeviceOps; - priv = this; - - mNotifyCb = NULL; - - mRequestQueueSrc = NULL; - mFrameQueueDst = NULL; - - mVendorTagOps.get_camera_vendor_section_name = - EmulatedCamera2::get_camera_vendor_section_name; - mVendorTagOps.get_camera_vendor_tag_name = - EmulatedCamera2::get_camera_vendor_tag_name; - mVendorTagOps.get_camera_vendor_tag_type = - EmulatedCamera2::get_camera_vendor_tag_type; - mVendorTagOps.parent = this; - - mStatusPresent = true; -} - -/* Destructs EmulatedCamera2 instance. */ -EmulatedCamera2::~EmulatedCamera2() {} - -/**************************************************************************** - * Abstract API - ***************************************************************************/ - -/**************************************************************************** - * Public API - ***************************************************************************/ - -status_t EmulatedCamera2::Initialize(const cvd::CameraDefinition & /*props*/) { - return NO_ERROR; -} - -/**************************************************************************** - * Camera API implementation - ***************************************************************************/ - -status_t EmulatedCamera2::connectCamera(hw_device_t **device) { - *device = &common; - return NO_ERROR; -} - -status_t EmulatedCamera2::closeCamera() { return NO_ERROR; } - -status_t EmulatedCamera2::getCameraInfo(struct camera_info *info) { - return EmulatedBaseCamera::getCameraInfo(info); -} - -/**************************************************************************** - * Camera Device API implementation. - * These methods are called from the camera API callback routines. - ***************************************************************************/ - -/** Request input queue */ - -int EmulatedCamera2::requestQueueNotify() { return INVALID_OPERATION; } - -/** Count of requests in flight */ -int EmulatedCamera2::getInProgressCount() { return INVALID_OPERATION; } - -/** Cancel all captures in flight */ -int EmulatedCamera2::flushCapturesInProgress() { return INVALID_OPERATION; } - -/** Construct a default request for a given use case */ -int EmulatedCamera2::constructDefaultRequest(int /*request_template*/, - camera_metadata_t ** /*request*/) { - return INVALID_OPERATION; -} - -/** Output stream creation and management */ - -int EmulatedCamera2::allocateStream(uint32_t /*width*/, uint32_t /*height*/, - int /*format*/, - const camera2_stream_ops_t * /*stream_ops*/, - uint32_t * /*stream_id*/, - uint32_t * /*format_actual*/, - uint32_t * /*usage*/, - uint32_t * /*max_buffers*/) { - return INVALID_OPERATION; -} - -int EmulatedCamera2::registerStreamBuffers(uint32_t /*stream_id*/, - int /*num_buffers*/, - buffer_handle_t * /*buffers*/) { - return INVALID_OPERATION; -} - -int EmulatedCamera2::releaseStream(uint32_t /*stream_id*/) { - return INVALID_OPERATION; -} - -/** Reprocessing input stream management */ - -int EmulatedCamera2::allocateReprocessStream( - uint32_t /*width*/, uint32_t /*height*/, uint32_t /*format*/, - const camera2_stream_in_ops_t * /*reprocess_stream_ops*/, - uint32_t * /*stream_id*/, uint32_t * /*consumer_usage*/, - uint32_t * /*max_buffers*/) { - return INVALID_OPERATION; -} - -int EmulatedCamera2::allocateReprocessStreamFromStream( - uint32_t /*output_stream_id*/, - const camera2_stream_in_ops_t * /*reprocess_stream_ops*/, - uint32_t * /*stream_id*/) { - return INVALID_OPERATION; -} - -int EmulatedCamera2::releaseReprocessStream(uint32_t /*stream_id*/) { - return INVALID_OPERATION; -} - -/** 3A triggering */ - -int EmulatedCamera2::triggerAction(uint32_t /*trigger_id*/, int /*ext1*/, - int /*ext2*/) { - return INVALID_OPERATION; -} - -/** Custom tag query methods */ - -const char *EmulatedCamera2::getVendorSectionName(uint32_t /*tag*/) { - return NULL; -} - -const char *EmulatedCamera2::getVendorTagName(uint32_t /*tag*/) { return NULL; } - -int EmulatedCamera2::getVendorTagType(uint32_t /*tag*/) { return -1; } - -/** Debug methods */ - -int EmulatedCamera2::dump(int /*fd*/) { return INVALID_OPERATION; } - -/**************************************************************************** - * Private API. - ***************************************************************************/ - -/**************************************************************************** - * Camera API callbacks as defined by camera2_device_ops structure. See - * hardware/libhardware/include/hardware/camera2.h for information on each - * of these callbacks. Implemented in this class, these callbacks simply - * dispatch the call into an instance of EmulatedCamera2 class defined by the - * 'camera_device2' parameter, or set a member value in the same. - ***************************************************************************/ - -EmulatedCamera2 *getInstance(const camera2_device_t *d) { - const EmulatedCamera2 *cec = static_cast<const EmulatedCamera2 *>(d); - return const_cast<EmulatedCamera2 *>(cec); -} - -int EmulatedCamera2::set_request_queue_src_ops( - const camera2_device_t *d, - const camera2_request_queue_src_ops *queue_src_ops) { - EmulatedCamera2 *ec = getInstance(d); - ec->mRequestQueueSrc = queue_src_ops; - return NO_ERROR; -} - -int EmulatedCamera2::notify_request_queue_not_empty(const camera2_device_t *d) { - EmulatedCamera2 *ec = getInstance(d); - return ec->requestQueueNotify(); -} - -int EmulatedCamera2::set_frame_queue_dst_ops( - const camera2_device_t *d, - const camera2_frame_queue_dst_ops *queue_dst_ops) { - EmulatedCamera2 *ec = getInstance(d); - ec->mFrameQueueDst = queue_dst_ops; - return NO_ERROR; -} - -int EmulatedCamera2::get_in_progress_count(const camera2_device_t *d) { - EmulatedCamera2 *ec = getInstance(d); - return ec->getInProgressCount(); -} - -int EmulatedCamera2::flush_captures_in_progress(const camera2_device_t *d) { - EmulatedCamera2 *ec = getInstance(d); - return ec->flushCapturesInProgress(); -} - -int EmulatedCamera2::construct_default_request(const camera2_device_t *d, - int request_template, - camera_metadata_t **request) { - EmulatedCamera2 *ec = getInstance(d); - return ec->constructDefaultRequest(request_template, request); -} - -int EmulatedCamera2::allocate_stream(const camera2_device_t *d, uint32_t width, - uint32_t height, int format, - const camera2_stream_ops_t *stream_ops, - uint32_t *stream_id, - uint32_t *format_actual, uint32_t *usage, - uint32_t *max_buffers) { - EmulatedCamera2 *ec = getInstance(d); - return ec->allocateStream(width, height, format, stream_ops, stream_id, - format_actual, usage, max_buffers); -} - -int EmulatedCamera2::register_stream_buffers(const camera2_device_t *d, - uint32_t stream_id, - int num_buffers, - buffer_handle_t *buffers) { - EmulatedCamera2 *ec = getInstance(d); - return ec->registerStreamBuffers(stream_id, num_buffers, buffers); -} -int EmulatedCamera2::release_stream(const camera2_device_t *d, - uint32_t stream_id) { - EmulatedCamera2 *ec = getInstance(d); - return ec->releaseStream(stream_id); -} - -int EmulatedCamera2::allocate_reprocess_stream( - const camera2_device_t *d, uint32_t width, uint32_t height, uint32_t format, - const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id, - uint32_t *consumer_usage, uint32_t *max_buffers) { - EmulatedCamera2 *ec = getInstance(d); - return ec->allocateReprocessStream(width, height, format, - reprocess_stream_ops, stream_id, - consumer_usage, max_buffers); -} - -int EmulatedCamera2::allocate_reprocess_stream_from_stream( - const camera2_device_t *d, uint32_t output_stream_id, - const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id) { - EmulatedCamera2 *ec = getInstance(d); - return ec->allocateReprocessStreamFromStream(output_stream_id, - reprocess_stream_ops, stream_id); -} - -int EmulatedCamera2::release_reprocess_stream(const camera2_device_t *d, - uint32_t stream_id) { - EmulatedCamera2 *ec = getInstance(d); - return ec->releaseReprocessStream(stream_id); -} - -int EmulatedCamera2::trigger_action(const camera2_device_t *d, - uint32_t trigger_id, int ext1, int ext2) { - EmulatedCamera2 *ec = getInstance(d); - return ec->triggerAction(trigger_id, ext1, ext2); -} - -int EmulatedCamera2::set_notify_callback(const camera2_device_t *d, - camera2_notify_callback notify_cb, - void *user) { - EmulatedCamera2 *ec = getInstance(d); - Mutex::Autolock l(ec->mMutex); - ec->mNotifyCb = notify_cb; - ec->mNotifyUserPtr = user; - return NO_ERROR; -} - -int EmulatedCamera2::get_instance_metadata( - const struct camera2_device *d, camera_metadata **instance_metadata) { - EmulatedCamera2 *ec = getInstance(d); - if (!ec) { - return INVALID_OPERATION; - } - *instance_metadata = ec->mCameraInfo; - return NO_ERROR; -} - -int EmulatedCamera2::get_metadata_vendor_tag_ops(const camera2_device_t *d, - vendor_tag_query_ops_t **ops) { - EmulatedCamera2 *ec = getInstance(d); - *ops = static_cast<vendor_tag_query_ops_t *>(&ec->mVendorTagOps); - return NO_ERROR; -} - -const char *EmulatedCamera2::get_camera_vendor_section_name( - const vendor_tag_query_ops_t *v, uint32_t tag) { - EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; - return ec->getVendorSectionName(tag); -} - -const char *EmulatedCamera2::get_camera_vendor_tag_name( - const vendor_tag_query_ops_t *v, uint32_t tag) { - EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; - return ec->getVendorTagName(tag); -} - -int EmulatedCamera2::get_camera_vendor_tag_type(const vendor_tag_query_ops_t *v, - uint32_t tag) { - EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; - return ec->getVendorTagType(tag); -} - -int EmulatedCamera2::dump(const camera2_device_t *d, int fd) { - EmulatedCamera2 *ec = getInstance(d); - return ec->dump(fd); -} - -int EmulatedCamera2::close(struct hw_device_t *device) { - EmulatedCamera2 *ec = static_cast<EmulatedCamera2 *>( - reinterpret_cast<camera2_device_t *>(device)); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera2 device", __FUNCTION__); - return -EINVAL; - } - return ec->closeCamera(); -} - -void EmulatedCamera2::sendNotification(int32_t msgType, int32_t ext1, - int32_t ext2, int32_t ext3) { - camera2_notify_callback notifyCb; - { - Mutex::Autolock l(mMutex); - notifyCb = mNotifyCb; - } - if (notifyCb != NULL) { - notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr); - } -} - -camera2_device_ops_t EmulatedCamera2::sDeviceOps = { - EmulatedCamera2::set_request_queue_src_ops, - EmulatedCamera2::notify_request_queue_not_empty, - EmulatedCamera2::set_frame_queue_dst_ops, - EmulatedCamera2::get_in_progress_count, - EmulatedCamera2::flush_captures_in_progress, - EmulatedCamera2::construct_default_request, - EmulatedCamera2::allocate_stream, - EmulatedCamera2::register_stream_buffers, - EmulatedCamera2::release_stream, - EmulatedCamera2::allocate_reprocess_stream, - EmulatedCamera2::allocate_reprocess_stream_from_stream, - EmulatedCamera2::release_reprocess_stream, - EmulatedCamera2::trigger_action, - EmulatedCamera2::set_notify_callback, - EmulatedCamera2::get_metadata_vendor_tag_ops, - EmulatedCamera2::dump, -#ifdef CAMERA_DEVICE_API_VERSION_2_1 - EmulatedCamera2::get_instance_metadata, -#endif -}; - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedCamera2.h b/guest/hals/camera/EmulatedCamera2.h deleted file mode 100644 index ad8b1138..00000000 --- a/guest/hals/camera/EmulatedCamera2.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H - -/* - * Contains declaration of a class EmulatedCamera that encapsulates - * functionality common to all version 2.0 emulated camera devices. Instances - * of this class (for each emulated camera) are created during the construction - * of the EmulatedCameraFactory instance. This class serves as an entry point - * for all camera API calls that defined by camera2_device_ops_t API. - */ - -#include <utils/Mutex.h> -#include <utils/Thread.h> -#include "EmulatedBaseCamera.h" -#include "hardware/camera2.h" -#include "system/camera_metadata.h" - -namespace android { - -/* Encapsulates functionality common to all version 2.0 emulated camera devices - * - * Note that EmulatedCameraFactory instantiates object of this class just once, - * when EmulatedCameraFactory instance gets constructed. Connection to / - * disconnection from the actual camera device is handled by calls to - * connectDevice(), and closeCamera() methods of this class that are invoked in - * response to hw_module_methods_t::open, and camera_device::close callbacks. - */ -class EmulatedCamera2 : public camera2_device, public EmulatedBaseCamera { - public: - /* Constructs EmulatedCamera2 instance. - * Param: - * cameraId - Zero based camera identifier, which is an index of the camera - * instance in camera factory's array. - * module - Emulated camera HAL module descriptor. - */ - EmulatedCamera2(int cameraId, struct hw_module_t *module); - - /* Destructs EmulatedCamera2 instance. */ - virtual ~EmulatedCamera2(); - - /**************************************************************************** - * Abstract API - ***************************************************************************/ - - public: - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - virtual status_t Initialize(const cvd::CameraDefinition &props); - - /**************************************************************************** - * Camera module API and generic hardware device API implementation - ***************************************************************************/ - - public: - virtual status_t connectCamera(hw_device_t **device); - - virtual status_t closeCamera(); - - virtual status_t getCameraInfo(struct camera_info *info) = 0; - - /**************************************************************************** - * Camera API implementation. - * These methods are called from the camera API callback routines. - ***************************************************************************/ - - protected: - /** Request input queue notification */ - virtual int requestQueueNotify(); - - /** Count of requests in flight */ - virtual int getInProgressCount(); - - /** Cancel all captures in flight */ - virtual int flushCapturesInProgress(); - - virtual int constructDefaultRequest(int request_template, - camera_metadata_t **request); - - /** Output stream creation and management */ - virtual int allocateStream(uint32_t width, uint32_t height, int format, - const camera2_stream_ops_t *stream_ops, - uint32_t *stream_id, uint32_t *format_actual, - uint32_t *usage, uint32_t *max_buffers); - - virtual int registerStreamBuffers(uint32_t stream_id, int num_buffers, - buffer_handle_t *buffers); - - virtual int releaseStream(uint32_t stream_id); - - /** Input stream creation and management */ - virtual int allocateReprocessStream( - uint32_t width, uint32_t height, uint32_t format, - const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id, - uint32_t *consumer_usage, uint32_t *max_buffers); - - virtual int allocateReprocessStreamFromStream( - uint32_t output_stream_id, - const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id); - - virtual int releaseReprocessStream(uint32_t stream_id); - - /** 3A action triggering */ - virtual int triggerAction(uint32_t trigger_id, int32_t ext1, int32_t ext2); - - /** Custom tag definitions */ - virtual const char *getVendorSectionName(uint32_t tag); - virtual const char *getVendorTagName(uint32_t tag); - virtual int getVendorTagType(uint32_t tag); - - /** Debug methods */ - - virtual int dump(int fd); - - /**************************************************************************** - * Camera API callbacks as defined by camera2_device_ops structure. See - * hardware/libhardware/include/hardware/camera2.h for information on each - * of these callbacks. Implemented in this class, these callbacks simply - * dispatch the call into an instance of EmulatedCamera2 class defined in - * the 'camera_device2' parameter. - ***************************************************************************/ - - private: - /** Input request queue */ - static int set_request_queue_src_ops( - const camera2_device_t *, - const camera2_request_queue_src_ops *queue_src_ops); - static int notify_request_queue_not_empty(const camera2_device_t *); - - /** Output frame queue */ - static int set_frame_queue_dst_ops( - const camera2_device_t *, - const camera2_frame_queue_dst_ops *queue_dst_ops); - - /** In-progress request management */ - static int get_in_progress_count(const camera2_device_t *); - - static int get_instance_metadata(const struct camera2_device *, - camera_metadata **); - - static int flush_captures_in_progress(const camera2_device_t *); - - /** Request template creation */ - static int construct_default_request(const camera2_device_t *, - int request_template, - camera_metadata_t **request); - - /** Stream management */ - static int allocate_stream(const camera2_device_t *, uint32_t width, - uint32_t height, int format, - const camera2_stream_ops_t *stream_ops, - uint32_t *stream_id, uint32_t *format_actual, - uint32_t *usage, uint32_t *max_buffers); - - static int register_stream_buffers(const camera2_device_t *, - uint32_t stream_id, int num_buffers, - buffer_handle_t *buffers); - - static int release_stream(const camera2_device_t *, uint32_t stream_id); - - static int allocate_reprocess_stream( - const camera2_device_t *, uint32_t width, uint32_t height, - uint32_t format, const camera2_stream_in_ops_t *reprocess_stream_ops, - uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers); - - static int allocate_reprocess_stream_from_stream( - const camera2_device_t *, uint32_t output_stream_id, - const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id); - - static int release_reprocess_stream(const camera2_device_t *, - uint32_t stream_id); - - /** 3A triggers*/ - static int trigger_action(const camera2_device_t *, uint32_t trigger_id, - int ext1, int ext2); - - /** Notifications to application */ - static int set_notify_callback(const camera2_device_t *, - camera2_notify_callback notify_cb, void *user); - - /** Vendor metadata registration */ - static int get_metadata_vendor_tag_ops(const camera2_device_t *, - vendor_tag_query_ops_t **ops); - // for get_metadata_vendor_tag_ops - static const char *get_camera_vendor_section_name( - const vendor_tag_query_ops_t *, uint32_t tag); - static const char *get_camera_vendor_tag_name(const vendor_tag_query_ops_t *, - uint32_t tag); - static int get_camera_vendor_tag_type(const vendor_tag_query_ops_t *, - uint32_t tag); - - static int dump(const camera2_device_t *, int fd); - - /** For hw_device_t ops */ - static int close(struct hw_device_t *device); - - /**************************************************************************** - * Data members shared with implementations - ***************************************************************************/ - protected: - /** Mutex for calls through camera2 device interface */ - Mutex mMutex; - - bool mStatusPresent; - - const camera2_request_queue_src_ops *mRequestQueueSrc; - const camera2_frame_queue_dst_ops *mFrameQueueDst; - - struct TagOps : public vendor_tag_query_ops { - EmulatedCamera2 *parent; - }; - TagOps mVendorTagOps; - - void sendNotification(int32_t msgType, int32_t ext1, int32_t ext2, - int32_t ext3); - - /**************************************************************************** - * Data members - ***************************************************************************/ - private: - static camera2_device_ops_t sDeviceOps; - camera2_notify_callback mNotifyCb; - void *mNotifyUserPtr; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA2_H */ diff --git a/guest/hals/camera/EmulatedCamera3.cpp b/guest/hals/camera/EmulatedCamera3.cpp deleted file mode 100644 index 8b8921a2..00000000 --- a/guest/hals/camera/EmulatedCamera3.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -/** - * Contains implementation of a class EmulatedCamera that encapsulates - * functionality common to all version 3.0 emulated camera devices. Instances - * of this class (for each emulated camera) are created during the construction - * of the EmulatedCameraFactory instance. This class serves as an entry point - * for all camera API calls that defined by camera3_device_ops_t API. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera3_Camera" -#include <log/log.h> - -#include "EmulatedCamera3.h" -#include "system/camera_metadata.h" - -namespace android { - -/** - * Constructs EmulatedCamera3 instance. - * Param: - * cameraId - Zero based camera identifier, which is an index of the camera - * instance in camera factory's array. - * module - Emulated camera HAL module descriptor. - */ -EmulatedCamera3::EmulatedCamera3(int cameraId, struct hw_module_t* module) - : EmulatedBaseCamera(cameraId, CAMERA_DEVICE_API_VERSION_3_3, &common, - module), - mStatus(STATUS_ERROR) { - common.close = EmulatedCamera3::close; - ops = &sDeviceOps; - - mCallbackOps = NULL; -} - -/* Destructs EmulatedCamera3 instance. */ -EmulatedCamera3::~EmulatedCamera3() {} - -/**************************************************************************** - * Abstract API - ***************************************************************************/ - -/**************************************************************************** - * Public API - ***************************************************************************/ - -status_t EmulatedCamera3::Initialize(const cvd::CameraDefinition& /*params*/) { - ALOGV("%s", __FUNCTION__); - - mStatus = STATUS_CLOSED; - return NO_ERROR; -} - -/**************************************************************************** - * Camera API implementation - ***************************************************************************/ - -status_t EmulatedCamera3::connectCamera(hw_device_t** device) { - ALOGV("%s", __FUNCTION__); - if (device == NULL) return BAD_VALUE; - - if (mStatus != STATUS_CLOSED) { - ALOGE("%s: Trying to open a camera in state %d!", __FUNCTION__, mStatus); - return INVALID_OPERATION; - } - - *device = &common; - mStatus = STATUS_OPEN; - return NO_ERROR; -} - -status_t EmulatedCamera3::closeCamera() { - mStatus = STATUS_CLOSED; - return NO_ERROR; -} - -status_t EmulatedCamera3::getCameraInfo(struct camera_info* info) { - return EmulatedBaseCamera::getCameraInfo(info); -} - -/**************************************************************************** - * Camera Device API implementation. - * These methods are called from the camera API callback routines. - ***************************************************************************/ - -status_t EmulatedCamera3::initializeDevice( - const camera3_callback_ops* callbackOps) { - if (callbackOps == NULL) { - ALOGE("%s: NULL callback ops provided to HAL!", __FUNCTION__); - return BAD_VALUE; - } - - if (mStatus != STATUS_OPEN) { - ALOGE("%s: Trying to initialize a camera in state %d!", __FUNCTION__, - mStatus); - return INVALID_OPERATION; - } - - mCallbackOps = callbackOps; - mStatus = STATUS_READY; - - return NO_ERROR; -} - -status_t EmulatedCamera3::configureStreams( - camera3_stream_configuration* /*streamList*/) { - ALOGE("%s: Not implemented", __FUNCTION__); - return INVALID_OPERATION; -} - -status_t EmulatedCamera3::registerStreamBuffers( - const camera3_stream_buffer_set* /*bufferSet*/) { - ALOGE("%s: Not implemented", __FUNCTION__); - return INVALID_OPERATION; -} - -const camera_metadata_t* EmulatedCamera3::constructDefaultRequestSettings( - int /*type*/) { - ALOGE("%s: Not implemented", __FUNCTION__); - return NULL; -} - -status_t EmulatedCamera3::processCaptureRequest( - camera3_capture_request* /*request*/) { - ALOGE("%s: Not implemented", __FUNCTION__); - return INVALID_OPERATION; -} - -status_t EmulatedCamera3::flush() { - ALOGE("%s: Not implemented", __FUNCTION__); - return INVALID_OPERATION; -} - -/** Debug methods */ - -void EmulatedCamera3::dump(int /*fd*/) { - ALOGE("%s: Not implemented", __FUNCTION__); - return; -} - -/**************************************************************************** - * Protected API. Callbacks to the framework. - ***************************************************************************/ - -void EmulatedCamera3::sendCaptureResult(camera3_capture_result_t* result) { - mCallbackOps->process_capture_result(mCallbackOps, result); -} - -void EmulatedCamera3::sendNotify(camera3_notify_msg_t* msg) { - mCallbackOps->notify(mCallbackOps, msg); -} - -/**************************************************************************** - * Private API. - ***************************************************************************/ - -/**************************************************************************** - * Camera API callbacks as defined by camera3_device_ops structure. See - * hardware/libhardware/include/hardware/camera3.h for information on each - * of these callbacks. Implemented in this class, these callbacks simply - * dispatch the call into an instance of EmulatedCamera3 class defined by the - * 'camera_device3' parameter, or set a member value in the same. - ***************************************************************************/ - -EmulatedCamera3* getInstance(const camera3_device_t* d) { - const EmulatedCamera3* cec = static_cast<const EmulatedCamera3*>(d); - return const_cast<EmulatedCamera3*>(cec); -} - -int EmulatedCamera3::initialize(const struct camera3_device* d, - const camera3_callback_ops_t* callback_ops) { - EmulatedCamera3* ec = getInstance(d); - return ec->initializeDevice(callback_ops); -} - -int EmulatedCamera3::configure_streams( - const struct camera3_device* d, - camera3_stream_configuration_t* stream_list) { - EmulatedCamera3* ec = getInstance(d); - return ec->configureStreams(stream_list); -} - -int EmulatedCamera3::register_stream_buffers( - const struct camera3_device* d, - const camera3_stream_buffer_set_t* buffer_set) { - EmulatedCamera3* ec = getInstance(d); - return ec->registerStreamBuffers(buffer_set); -} - -int EmulatedCamera3::process_capture_request( - const struct camera3_device* d, camera3_capture_request_t* request) { - EmulatedCamera3* ec = getInstance(d); - return ec->processCaptureRequest(request); -} - -const camera_metadata_t* EmulatedCamera3::construct_default_request_settings( - const camera3_device_t* d, int type) { - EmulatedCamera3* ec = getInstance(d); - return ec->constructDefaultRequestSettings(type); -} - -void EmulatedCamera3::dump(const camera3_device_t* d, int fd) { - EmulatedCamera3* ec = getInstance(d); - ec->dump(fd); -} - -int EmulatedCamera3::flush(const camera3_device_t* d) { - EmulatedCamera3* ec = getInstance(d); - return ec->flush(); -} - -int EmulatedCamera3::close(struct hw_device_t* device) { - EmulatedCamera3* ec = static_cast<EmulatedCamera3*>( - reinterpret_cast<camera3_device_t*>(device)); - if (ec == NULL) { - ALOGE("%s: Unexpected NULL camera3 device", __FUNCTION__); - return BAD_VALUE; - } - return ec->closeCamera(); -} - -camera3_device_ops_t EmulatedCamera3::sDeviceOps = { - EmulatedCamera3::initialize, - EmulatedCamera3::configure_streams, - /* DEPRECATED: register_stream_buffers */ nullptr, - EmulatedCamera3::construct_default_request_settings, - EmulatedCamera3::process_capture_request, - /* DEPRECATED: get_metadata_vendor_tag_ops */ nullptr, - EmulatedCamera3::dump, - EmulatedCamera3::flush, -#ifdef CAMERA_DEVICE_API_VERSION_3_6 - /*UNUSED: signal_stream_flush*/nullptr, - /*UNUSED: is_reconfiguration_required*/nullptr, -#endif - {0}}; - -const char* EmulatedCamera3::sAvailableCapabilitiesStrings[NUM_CAPABILITIES] = { - "BACKWARD_COMPATIBLE", - "MANUAL_SENSOR", - "MANUAL_POST_PROCESSING", - "RAW", - "PRIVATE_REPROCESSING", - "READ_SENSOR_SETTINGS", - "BURST_CAPTURE", - "YUV_REPROCESSING", - "DEPTH_OUTPUT", - "CONSTRAINED_HIGH_SPEED_VIDEO", - "FULL_LEVEL"}; - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedCamera3.h b/guest/hals/camera/EmulatedCamera3.h deleted file mode 100644 index 92fbb4d7..00000000 --- a/guest/hals/camera/EmulatedCamera3.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA3_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA3_H - -/** - * Contains declaration of a class EmulatedCamera that encapsulates - * functionality common to all version 3.0 emulated camera devices. Instances - * of this class (for each emulated camera) are created during the construction - * of the EmulatedCameraFactory instance. This class serves as an entry point - * for all camera API calls that defined by camera3_device_ops_t API. - */ - -#include "EmulatedBaseCamera.h" -#include "hardware/camera3.h" -#include "system/camera_metadata.h" - -namespace android { - -/** - * Encapsulates functionality common to all version 3.0 emulated camera devices - * - * Note that EmulatedCameraFactory instantiates an object of this class just - * once, when EmulatedCameraFactory instance gets constructed. Connection to / - * disconnection from the actual camera device is handled by calls to - * connectDevice(), and closeCamera() methods of this class that are invoked in - * response to hw_module_methods_t::open, and camera_device::close callbacks. - */ -class EmulatedCamera3 : public camera3_device, public EmulatedBaseCamera { - public: - /* Constructs EmulatedCamera3 instance. - * Param: - * cameraId - Zero based camera identifier, which is an index of the camera - * instance in camera factory's array. - * module - Emulated camera HAL module descriptor. - */ - EmulatedCamera3(int cameraId, struct hw_module_t *module); - - /* Destructs EmulatedCamera2 instance. */ - virtual ~EmulatedCamera3(); - - /* List of all defined capabilities plus useful HW levels */ - enum AvailableCapabilities { - BACKWARD_COMPATIBLE, - MANUAL_SENSOR, - MANUAL_POST_PROCESSING, - RAW, - PRIVATE_REPROCESSING, - READ_SENSOR_SETTINGS, - BURST_CAPTURE, - YUV_REPROCESSING, - DEPTH_OUTPUT, - CONSTRAINED_HIGH_SPEED_VIDEO, - // Levels - FULL_LEVEL, - - NUM_CAPABILITIES - }; - - // Char strings for above enum, with size NUM_CAPABILITIES - static const char *sAvailableCapabilitiesStrings[]; - - /**************************************************************************** - * Abstract API - ***************************************************************************/ - - public: - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - virtual status_t Initialize(const cvd::CameraDefinition ¶ms); - - /**************************************************************************** - * Camera module API and generic hardware device API implementation - ***************************************************************************/ - - public: - virtual status_t connectCamera(hw_device_t **device); - - virtual status_t closeCamera(); - - virtual status_t getCameraInfo(struct camera_info *info); - - /**************************************************************************** - * Camera API implementation. - * These methods are called from the camera API callback routines. - ***************************************************************************/ - - protected: - virtual status_t initializeDevice(const camera3_callback_ops *callbackOps); - - virtual status_t configureStreams(camera3_stream_configuration *streamList); - - virtual status_t registerStreamBuffers( - const camera3_stream_buffer_set *bufferSet); - - virtual const camera_metadata_t *constructDefaultRequestSettings(int type); - - virtual status_t processCaptureRequest(camera3_capture_request *request); - - virtual status_t flush(); - - /** Debug methods */ - - virtual void dump(int fd); - - /**************************************************************************** - * Camera API callbacks as defined by camera3_device_ops structure. See - * hardware/libhardware/include/hardware/camera3.h for information on each - * of these callbacks. Implemented in this class, these callbacks simply - * dispatch the call into an instance of EmulatedCamera3 class defined in - * the 'camera_device3' parameter. - ***************************************************************************/ - - private: - /** Startup */ - static int initialize(const struct camera3_device *, - const camera3_callback_ops_t *callback_ops); - - /** Stream configuration and buffer registration */ - - static int configure_streams(const struct camera3_device *, - camera3_stream_configuration_t *stream_list); - - static int register_stream_buffers( - const struct camera3_device *, - const camera3_stream_buffer_set_t *buffer_set); - - /** Template request settings provision */ - - static const camera_metadata_t *construct_default_request_settings( - const struct camera3_device *, int type); - - /** Submission of capture requests to HAL */ - - static int process_capture_request(const struct camera3_device *, - camera3_capture_request_t *request); - - static void dump(const camera3_device_t *, int fd); - - static int flush(const camera3_device_t *); - - /** For hw_device_t ops */ - static int close(struct hw_device_t *device); - - /**************************************************************************** - * Data members shared with implementations - ***************************************************************************/ - protected: - enum { - // State at construction time, and after a device operation error - STATUS_ERROR = 0, - // State after startup-time init and after device instance close - STATUS_CLOSED, - // State after being opened, before device instance init - STATUS_OPEN, - // State after device instance initialization - STATUS_READY, - // State while actively capturing data - STATUS_ACTIVE - } mStatus; - - /** - * Callbacks back to the framework - */ - - void sendCaptureResult(camera3_capture_result_t *result); - void sendNotify(camera3_notify_msg_t *msg); - - /**************************************************************************** - * Data members - ***************************************************************************/ - private: - static camera3_device_ops_t sDeviceOps; - const camera3_callback_ops_t *mCallbackOps; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA3_H */ diff --git a/guest/hals/camera/EmulatedCameraCommon.h b/guest/hals/camera/EmulatedCameraCommon.h deleted file mode 100644 index 0ec75011..00000000 --- a/guest/hals/camera/EmulatedCameraCommon.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H - -/* - * Contains common declarations that are used across the camera emulation. - */ - -#include <hardware/camera.h> -#include <linux/videodev2.h> - -/* A helper class that tracks a routine execution. - * Basically, it dumps an enry message in its constructor, and an exit message - * in its destructor. Use LOGRE() macro (declared bellow) to create instances - * of this class at the beginning of the tracked routines / methods. - */ -class HWERoutineTracker { - public: - /* Constructor that prints an "entry" trace message. */ - explicit HWERoutineTracker(const char* name) : mName(name) { - ALOGV("Entering %s", mName); - } - - /* Destructor that prints a "leave" trace message. */ - ~HWERoutineTracker() { ALOGV("Leaving %s", mName); } - - private: - /* Stores the routine name. */ - const char* mName; -}; - -/* Logs an execution of a routine / method. */ -#define LOGRE() HWERoutineTracker hwertracker_##__LINE__(__FUNCTION__) - -/* - * min / max macros - */ - -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_COMMON_H */ diff --git a/guest/hals/camera/EmulatedCameraDevice.cpp b/guest/hals/camera/EmulatedCameraDevice.cpp deleted file mode 100644 index d741b737..00000000 --- a/guest/hals/camera/EmulatedCameraDevice.cpp +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of an abstract class EmulatedCameraDevice that - * defines functionality expected from an emulated physical camera device: - * - Obtaining and setting camera parameters - * - Capturing frames - * - Streaming video - * - etc. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Device" -#include "EmulatedCameraDevice.h" -#include <log/log.h> -#include <sys/select.h> -#include <algorithm> -#include <cmath> -#include "EmulatedCamera.h" - -namespace android { - -const float GAMMA_CORRECTION = 2.2f; -EmulatedCameraDevice::EmulatedCameraDevice(EmulatedCamera* camera_hal) - : mObjectLock(), - mCurFrameTimestamp(0), - mCameraHAL(camera_hal), - mCurrentFrame(NULL), - mExposureCompensation(1.0f), - mWhiteBalanceScale(NULL), - mIsFocusing(false), - mSupportedWhiteBalanceScale(), - mState(ECDS_CONSTRUCTED) {} - -EmulatedCameraDevice::~EmulatedCameraDevice() { - ALOGV("EmulatedCameraDevice destructor"); - if (mCurrentFrame != NULL) { - delete[] mCurrentFrame; - } - for (size_t i = 0; i < mSupportedWhiteBalanceScale.size(); ++i) { - if (mSupportedWhiteBalanceScale.valueAt(i) != NULL) { - delete[] mSupportedWhiteBalanceScale.valueAt(i); - } - } -} - -/**************************************************************************** - * Emulated camera device public API - ***************************************************************************/ - -status_t EmulatedCameraDevice::Initialize() { - if (isInitialized()) { - ALOGW("%s: Emulated camera device is already initialized: mState = %d", - __FUNCTION__, mState); - return NO_ERROR; - } - - /* Instantiate worker thread object. */ - mWorkerThread = new WorkerThread(this); - if (getWorkerThread() == NULL) { - ALOGE("%s: Unable to instantiate worker thread object", __FUNCTION__); - return ENOMEM; - } - - mState = ECDS_INITIALIZED; - - return NO_ERROR; -} - -status_t EmulatedCameraDevice::startDeliveringFrames(bool one_burst) { - ALOGV("%s", __FUNCTION__); - - if (!isStarted()) { - ALOGE("%s: Device is not started", __FUNCTION__); - return EINVAL; - } - - /* Frames will be delivered from the thread routine. */ - const status_t res = startWorkerThread(one_burst); - ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__); - return res; -} - -status_t EmulatedCameraDevice::stopDeliveringFrames() { - ALOGV("%s", __FUNCTION__); - - if (!isStarted()) { - ALOGW("%s: Device is not started", __FUNCTION__); - return NO_ERROR; - } - - const status_t res = stopWorkerThread(); - ALOGE_IF(res != NO_ERROR, "%s: startWorkerThread failed", __FUNCTION__); - return res; -} - -void EmulatedCameraDevice::setExposureCompensation(const float ev) { - ALOGV("%s", __FUNCTION__); - - if (!isStarted()) { - ALOGW("%s: Fake camera device is not started.", __FUNCTION__); - } - - mExposureCompensation = std::pow(2.0f, ev / GAMMA_CORRECTION); - ALOGV("New exposure compensation is %f", mExposureCompensation); -} - -void EmulatedCameraDevice::initializeWhiteBalanceModes(const char* mode, - const float r_scale, - const float b_scale) { - ALOGV("%s with %s, %f, %f", __FUNCTION__, mode, r_scale, b_scale); - float* value = new float[3]; - value[0] = r_scale; - value[1] = 1.0f; - value[2] = b_scale; - mSupportedWhiteBalanceScale.add(String8(mode), value); -} - -void EmulatedCameraDevice::setWhiteBalanceMode(const char* mode) { - ALOGV("%s with white balance %s", __FUNCTION__, mode); - mWhiteBalanceScale = mSupportedWhiteBalanceScale.valueFor(String8(mode)); -} - -void EmulatedCameraDevice::startAutoFocus() { mIsFocusing = true; } - -/* Computes the pixel value after adjusting the white balance to the current - * one. The input the y, u, v channel of the pixel and the adjusted value will - * be stored in place. The adjustment is done in RGB space. - */ -void EmulatedCameraDevice::changeWhiteBalance(uint8_t& y, uint8_t& u, - uint8_t& v) const { - float r_scale = mWhiteBalanceScale[0]; - float b_scale = mWhiteBalanceScale[2]; - int r = static_cast<float>(YUV2R(y, u, v)) / r_scale; - int g = YUV2G(y, u, v); - int b = static_cast<float>(YUV2B(y, u, v)) / b_scale; - - y = RGB2Y(r, g, b); - u = RGB2U(r, g, b); - v = RGB2V(r, g, b); -} - -void EmulatedCameraDevice::simulateAutoFocus() { - if (mIsFocusing) { - ALOGV("%s: Simulating auto-focus", __FUNCTION__); - mCameraHAL->onCameraFocusAcquired(); - mIsFocusing = false; - } -} - -status_t EmulatedCameraDevice::getCurrentPreviewFrame(void* buffer) { - if (!isStarted()) { - ALOGE("%s: Device is not started", __FUNCTION__); - return EINVAL; - } - if (mCurrentFrame == NULL || buffer == NULL) { - ALOGE("%s: No framebuffer", __FUNCTION__); - return EINVAL; - } - - /* In emulation the framebuffer is never RGB. */ - switch (mPixelFormat) { - case V4L2_PIX_FMT_YVU420: - YV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight); - return NO_ERROR; - case V4L2_PIX_FMT_YUV420: - YU12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight); - return NO_ERROR; - case V4L2_PIX_FMT_NV21: - NV21ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight); - return NO_ERROR; - case V4L2_PIX_FMT_NV12: - NV12ToRGB32(mCurrentFrame, buffer, mFrameWidth, mFrameHeight); - return NO_ERROR; - - default: - ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__, - reinterpret_cast<const char*>(&mPixelFormat)); - return EINVAL; - } -} - -/**************************************************************************** - * Emulated camera device private API - ***************************************************************************/ - -status_t EmulatedCameraDevice::commonStartDevice(int width, int height, - uint32_t pix_fmt, int fps) { - /* Validate pixel format, and calculate framebuffer size at the same time. */ - switch (pix_fmt) { - case V4L2_PIX_FMT_YVU420: - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_NV21: - case V4L2_PIX_FMT_NV12: - mFrameBufferSize = (width * height * 12) / 8; - break; - - default: - ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__, - reinterpret_cast<const char*>(&pix_fmt)); - return EINVAL; - } - - /* Cache framebuffer info. */ - mFrameWidth = width; - mFrameHeight = height; - mPixelFormat = pix_fmt; - mTotalPixels = width * height; - mTargetFps = fps; - - /* Allocate framebuffer. */ - mCurrentFrame = new uint8_t[mFrameBufferSize]; - if (mCurrentFrame == NULL) { - ALOGE("%s: Unable to allocate framebuffer", __FUNCTION__); - return ENOMEM; - } - ALOGV("%s: Allocated %p %zu bytes for %d pixels in %.4s[%dx%d] frame", - __FUNCTION__, mCurrentFrame, mFrameBufferSize, mTotalPixels, - reinterpret_cast<const char*>(&mPixelFormat), mFrameWidth, - mFrameHeight); - return NO_ERROR; -} - -void EmulatedCameraDevice::commonStopDevice() { - mFrameWidth = mFrameHeight = mTotalPixels = 0; - mPixelFormat = 0; - mTargetFps = 0; - - if (mCurrentFrame != NULL) { - delete[] mCurrentFrame; - mCurrentFrame = NULL; - } -} - -const CameraParameters* EmulatedCameraDevice::getCameraParameters() { - return mCameraHAL->getCameraParameters(); -} - -/**************************************************************************** - * Worker thread management. - ***************************************************************************/ - -status_t EmulatedCameraDevice::startWorkerThread(bool one_burst) { - ALOGV("%s", __FUNCTION__); - - if (!isInitialized()) { - ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__); - return EINVAL; - } - - const status_t res = getWorkerThread()->startThread(one_burst); - ALOGE_IF(res != NO_ERROR, "%s: Unable to start worker thread", __FUNCTION__); - return res; -} - -status_t EmulatedCameraDevice::stopWorkerThread() { - ALOGV("%s", __FUNCTION__); - - if (!isInitialized()) { - ALOGE("%s: Emulated camera device is not initialized", __FUNCTION__); - return EINVAL; - } - - const status_t res = getWorkerThread()->stopThread(); - ALOGE_IF(res != NO_ERROR, "%s: Unable to stop worker thread", __FUNCTION__); - return res; -} - -bool EmulatedCameraDevice::inWorkerThread() { - /* This will end the thread loop, and will terminate the thread. Derived - * classes must override this method. */ - return false; -} - -/**************************************************************************** - * Worker thread implementation. - ***************************************************************************/ - -status_t EmulatedCameraDevice::WorkerThread::readyToRun() { - ALOGV("Starting emulated camera device worker thread..."); - - ALOGW_IF(mThreadControl >= 0 || mControlFD >= 0, - "%s: Thread control FDs are opened", __FUNCTION__); - /* Create a pair of FDs that would be used to control the thread. */ - int thread_fds[2]; - status_t ret; - Mutex::Autolock lock(mCameraDevice->mObjectLock); - if (pipe(thread_fds) == 0) { - mThreadControl = thread_fds[1]; - mControlFD = thread_fds[0]; - ALOGV("Emulated device's worker thread has been started."); - ret = NO_ERROR; - } else { - ALOGE("%s: Unable to create thread control FDs: %d -> %s", __FUNCTION__, - errno, strerror(errno)); - ret = errno; - } - - mSetup.signal(); - return ret; -} - -status_t EmulatedCameraDevice::WorkerThread::stopThread() { - ALOGV("Stopping emulated camera device's worker thread..."); - - status_t res = EINVAL; - - // Limit the scope of the Autolock - { - // If thread is running and readyToRun() has not finished running, - // then wait until it is done. - Mutex::Autolock lock(mCameraDevice->mObjectLock); - if (isRunning() && (mThreadControl < 0 || mControlFD < 0)) { - mSetup.wait(mCameraDevice->mObjectLock); - } - } - - if (mThreadControl >= 0) { - /* Send "stop" message to the thread loop. */ - const ControlMessage msg = THREAD_STOP; - const int wres = - TEMP_FAILURE_RETRY(write(mThreadControl, &msg, sizeof(msg))); - if (wres == sizeof(msg)) { - /* Stop the thread, and wait till it's terminated. */ - res = requestExitAndWait(); - if (res == NO_ERROR) { - /* Close control FDs. */ - if (mThreadControl >= 0) { - close(mThreadControl); - mThreadControl = -1; - } - if (mControlFD >= 0) { - close(mControlFD); - mControlFD = -1; - } - ALOGV("Emulated camera device's worker thread has been stopped."); - } else { - ALOGE("%s: requestExitAndWait failed: %d -> %s", __FUNCTION__, res, - strerror(-res)); - } - } else { - ALOGE("%s: Unable to send THREAD_STOP message: %d -> %s", __FUNCTION__, - errno, strerror(errno)); - res = errno ? errno : EINVAL; - } - } else { - ALOGE("%s: Thread control FDs are not opened", __FUNCTION__); - } - - return res; -} - -EmulatedCameraDevice::WorkerThread::SelectRes -EmulatedCameraDevice::WorkerThread::Select(int fd, int timeout) { - fd_set fds[1]; - struct timeval tv, *tvp = NULL; - - mCameraDevice->simulateAutoFocus(); - - const int fd_num = (fd >= 0) ? std::max(fd, mControlFD) + 1 : mControlFD + 1; - FD_ZERO(fds); - FD_SET(mControlFD, fds); - if (fd >= 0) { - FD_SET(fd, fds); - } - if (timeout) { - tv.tv_sec = timeout / 1000000; - tv.tv_usec = timeout % 1000000; - tvp = &tv; - } - int res = TEMP_FAILURE_RETRY(select(fd_num, fds, NULL, NULL, tvp)); - if (res < 0) { - ALOGE("%s: select returned %d and failed: %d -> %s", __FUNCTION__, res, - errno, strerror(errno)); - return ERROR; - } else if (res == 0) { - /* Timeout. */ - return TIMEOUT; - } else if (FD_ISSET(mControlFD, fds)) { - /* A control event. Lets read the message. */ - ControlMessage msg; - res = TEMP_FAILURE_RETRY(read(mControlFD, &msg, sizeof(msg))); - if (res != sizeof(msg)) { - ALOGE("%s: Unexpected message size %d, or an error %d -> %s", - __FUNCTION__, res, errno, strerror(errno)); - return ERROR; - } - /* THREAD_STOP is the only message expected here. */ - if (msg == THREAD_STOP) { - ALOGV("%s: THREAD_STOP message is received", __FUNCTION__); - return EXIT_THREAD; - } else { - ALOGE("Unknown worker thread message %d", msg); - return ERROR; - } - } else { - /* Must be an FD. */ - ALOGW_IF(fd < 0 || !FD_ISSET(fd, fds), "%s: Undefined 'select' result", - __FUNCTION__); - return READY; - } -} - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedCameraDevice.h b/guest/hals/camera/EmulatedCameraDevice.h deleted file mode 100644 index ab654eb3..00000000 --- a/guest/hals/camera/EmulatedCameraDevice.h +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H - -/* - * Contains declaration of an abstract class EmulatedCameraDevice that defines - * functionality expected from an emulated physical camera device: - * - Obtaining and setting camera device parameters - * - Capturing frames - * - Streaming video - * - etc. - */ - -#include <utils/KeyedVector.h> -#include <utils/String8.h> -#include <utils/threads.h> -#include "Converters.h" -#include "EmulatedCameraCommon.h" - -#include <CameraParameters.h> - -using ::android::hardware::camera::common::V1_0::helper::CameraParameters; - -namespace android { - -class EmulatedCamera; - -/* Encapsulates an abstract class EmulatedCameraDevice that defines - * functionality expected from an emulated physical camera device: - * - Obtaining and setting camera device parameters - * - Capturing frames - * - Streaming video - * - etc. - */ -class EmulatedCameraDevice { - public: - /* Constructs EmulatedCameraDevice instance. - * Param: - * camera_hal - Emulated camera that implements the camera HAL API, and - * manages (contains) this object. - */ - explicit EmulatedCameraDevice(EmulatedCamera* camera_hal); - - /* Destructs EmulatedCameraDevice instance. */ - virtual ~EmulatedCameraDevice(); - - /*************************************************************************** - * Emulated camera device abstract interface - **************************************************************************/ - - public: - /* Connects to the camera device. - * This method must be called on an initialized instance of this class. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t connectDevice() = 0; - - /* Disconnects from the camera device. - * Return: - * NO_ERROR on success, or an appropriate error status. If this method is - * called for already disconnected, or uninitialized instance of this class, - * a successful status must be returned from this method. If this method is - * called for an instance that is in the "started" state, this method must - * return a failure. - */ - virtual status_t disconnectDevice() = 0; - - /* Starts the camera device. - * This method tells the camera device to start capturing frames of the given - * dimensions for the given pixel format. Note that this method doesn't start - * the delivery of the captured frames to the emulated camera. Call - * startDeliveringFrames method to start delivering frames. This method must - * be called on a connected instance of this class. If it is called on a - * disconnected instance, this method must return a failure. - * Param: - * width, height - Frame dimensions to use when capturing video frames. - * pix_fmt - Pixel format to use when capturing video frames. - * fps - Target rate of frames per second. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t startDevice(int width, int height, uint32_t pix_fmt, - int fps) = 0; - - /* Stops the camera device. - * This method tells the camera device to stop capturing frames. Note that - * this method doesn't stop delivering frames to the emulated camera. Always - * call stopDeliveringFrames prior to calling this method. - * Return: - * NO_ERROR on success, or an appropriate error status. If this method is - * called for an object that is not capturing frames, or is disconnected, - * or is uninitialized, a successful status must be returned from this - * method. - */ - virtual status_t stopDevice() = 0; - - /*************************************************************************** - * Emulated camera device public API - **************************************************************************/ - - public: - /* Initializes EmulatedCameraDevice instance. - * Derived classes should override this method in order to cache static - * properties of the physical device (list of supported pixel formats, frame - * sizes, etc.) If this method is called on an already initialized instance, - * it must return a successful status. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t Initialize(); - - /* Initializes the white balance modes parameters. - * The parameters are passed by each individual derived camera API to - * represent that different camera manufacturers may have different - * preferences on the white balance parameters. Green channel in the RGB - * color space is fixed to keep the luminance to be reasonably constant. - * - * Param: - * mode the text describing the current white balance mode - * r_scale the scale factor for the R channel in RGB space - * b_scale the scale factor for the B channel in RGB space. - */ - void initializeWhiteBalanceModes(const char* mode, const float r_scale, - const float b_scale); - - /* Starts delivering frames captured from the camera device. - * This method will start the worker thread that would be pulling frames from - * the camera device, and will deliver the pulled frames back to the emulated - * camera via onNextFrameAvailable callback. This method must be called on a - * connected instance of this class with a started camera device. If it is - * called on a disconnected instance, or camera device has not been started, - * this method must return a failure. - * Param: - * one_burst - Controls how many frames should be delivered. If this - * parameter is 'true', only one captured frame will be delivered to the - * emulated camera. If this parameter is 'false', frames will keep - * coming until stopDeliveringFrames method is called. Typically, this - * parameter is set to 'true' only in order to obtain a single frame - * that will be used as a "picture" in takePicture method of the - * emulated camera. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t startDeliveringFrames(bool one_burst); - - /* Stops delivering frames captured from the camera device. - * This method will stop the worker thread started by startDeliveringFrames. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t stopDeliveringFrames(); - - /* Sets the exposure compensation for the camera device. - */ - void setExposureCompensation(const float ev); - - /* Sets the white balance mode for the device. - */ - void setWhiteBalanceMode(const char* mode); - - /* Initiates focus operation. - */ - virtual void startAutoFocus(); - - /* Gets current framebuffer, converted into preview frame format. - * This method must be called on a connected instance of this class with a - * started camera device. If it is called on a disconnected instance, or - * camera device has not been started, this method must return a failure. - * Note that this method should be called only after at least one frame has - * been captured and delivered. Otherwise it will return garbage in the - * preview frame buffer. Typically, this method shuld be called from - * onNextFrameAvailable callback. - * Param: - * buffer - Buffer, large enough to contain the entire preview frame. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t getCurrentPreviewFrame(void* buffer); - - /* Gets width of the frame obtained from the physical device. - * Return: - * Width of the frame obtained from the physical device. Note that value - * returned from this method is valid only in case if camera device has been - * started. - */ - inline int getFrameWidth() const { - ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__); - return mFrameWidth; - } - - /* Gets height of the frame obtained from the physical device. - * Return: - * Height of the frame obtained from the physical device. Note that value - * returned from this method is valid only in case if camera device has been - * started. - */ - inline int getFrameHeight() const { - ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__); - return mFrameHeight; - } - - /* Gets byte size of the current frame buffer. - * Return: - * Byte size of the frame buffer. Note that value returned from this method - * is valid only in case if camera device has been started. - */ - inline size_t getFrameBufferSize() const { - ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__); - return mFrameBufferSize; - } - - /* Gets number of pixels in the current frame buffer. - * Return: - * Number of pixels in the frame buffer. Note that value returned from this - * method is valid only in case if camera device has been started. - */ - inline int getPixelNum() const { - ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__); - return mTotalPixels; - } - - /* Gets pixel format of the frame that camera device streams to this class. - * Throughout camera framework, there are three different forms of pixel - * format representation: - * - Original format, as reported by the actual camera device. Values for - * this format are declared in bionic/libc/kernel/common/linux/videodev2.h - * - String representation as defined in CameraParameters::PIXEL_FORMAT_XXX - * strings in frameworks/base/include/camera/CameraParameters.h - * - HAL_PIXEL_FORMAT_XXX format, as defined in - * system/core/include/system/graphics.h Since emulated camera device gets its - * data from the actual device, it gets pixel format in the original form. And - * that's the pixel format representation that will be returned from this - * method. HAL components will need to translate value returned from this - * method to the appropriate form. This method must be called only on started - * instance of this class, since it's applicable only when camera device is - * ready to stream frames. Param: pix_fmt - Upon success contains the original - * pixel format. Return: Current framebuffer's pixel format. Note that value - * returned from this method is valid only in case if camera device has been - * started. - */ - inline uint32_t getOriginalPixelFormat() const { - ALOGE_IF(!isStarted(), "%s: Device is not started", __FUNCTION__); - return mPixelFormat; - } - - /* Gets image metadata (from HAL). - * Return: - * Filled in ImageMetadata structure (in/out parameter). - */ - const CameraParameters* getCameraParameters(); - - /* - * State checkers. - */ - - inline bool isInitialized() const { - /* Instance is initialized when the worker thread has been successfuly - * created (but not necessarily started). */ - return mWorkerThread.get() != NULL && mState != ECDS_CONSTRUCTED; - } - inline bool isConnected() const { - /* Instance is connected when its status is either"connected", or - * "started". */ - return mState == ECDS_CONNECTED || mState == ECDS_STARTED; - } - inline bool isStarted() const { return mState == ECDS_STARTED; } - - /**************************************************************************** - * Emulated camera device private API - ***************************************************************************/ - protected: - /* Performs common validation and calculation of startDevice parameters. - * Param: - * width, height, pix_fmt, fps - Parameters passed to startDevice method. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t commonStartDevice(int width, int height, uint32_t pix_fmt, - int fps); - - /* Performs common cleanup on stopDevice. - * This method will undo what commonStartDevice had done. - */ - virtual void commonStopDevice(); - - /** Computes a luminance value after taking the exposure compensation. - * value into account. - * - * Param: - * inputY - The input luminance value. - * Return: - * The luminance value after adjusting the exposure compensation. - */ - inline uint8_t changeExposure(const uint8_t& inputY) const { - return static_cast<uint8_t>( - clamp(static_cast<float>(inputY) * mExposureCompensation)); - } - - /** Simulates focusing and reports completion to the client. - */ - void simulateAutoFocus(); - - /** Computes the pixel value in YUV space after adjusting to the current - * white balance mode. - */ - void changeWhiteBalance(uint8_t& y, uint8_t& u, uint8_t& v) const; - - /**************************************************************************** - * Worker thread management. - * Typicaly when emulated camera device starts capturing frames from the - * actual device, it does that in a worker thread created in StartCapturing, - * and terminated in StopCapturing. Since this is such a typical scenario, - * it makes sence to encapsulate worker thread management in the base class - * for all emulated camera devices. - ***************************************************************************/ - - protected: - /* Starts the worker thread. - * Typically, worker thread is started from startDeliveringFrames method of - * this class. - * Param: - * one_burst - Controls how many times thread loop should run. If this - * parameter is 'true', thread routine will run only once If this - * parameter is 'false', thread routine will run until stopWorkerThread - * method is called. See startDeliveringFrames for more info. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t startWorkerThread(bool one_burst); - - /* Stops the worker thread. - * Note that this method will always wait for the worker thread to terminate. - * Typically, worker thread is started from stopDeliveringFrames method of - * this class. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t stopWorkerThread(); - - /* Implementation of the worker thread routine. - * In the default implementation of the worker thread routine we simply - * return 'false' forcing the thread loop to exit, and the thread to - * terminate. Derived class should override that method to provide there the - * actual frame delivery. - * Return: - * true To continue thread loop (this method will be called again), or false - * to exit the thread loop and to terminate the thread. - */ - virtual bool inWorkerThread(); - - /* Encapsulates a worker thread used by the emulated camera device. - */ - friend class WorkerThread; - class WorkerThread : public Thread { - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - inline explicit WorkerThread(EmulatedCameraDevice* camera_dev) - : Thread(true), // Callbacks may involve Java calls. - mCameraDevice(camera_dev), - mThreadControl(-1), - mControlFD(-1) {} - - inline ~WorkerThread() { - ALOGW_IF(mThreadControl >= 0 || mControlFD >= 0, - "%s: Control FDs are opened in the destructor", __FUNCTION__); - if (mThreadControl >= 0) { - close(mThreadControl); - } - if (mControlFD >= 0) { - close(mControlFD); - } - } - - /* Starts the thread - * Param: - * one_burst - Controls how many times thread loop should run. If - * this parameter is 'true', thread routine will run only once - * If this parameter is 'false', thread routine will run until - * stopThread method is called. See startWorkerThread for more - * info. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - inline status_t startThread(bool one_burst) { - mOneBurst = one_burst; - return run("Camera_startThread", ANDROID_PRIORITY_URGENT_DISPLAY, 0); - } - - /* Overriden base class method. - * It is overriden in order to provide one-time initialization just - * prior to starting the thread routine. - */ - status_t readyToRun(); - - /* Stops the thread. */ - status_t stopThread(); - - /* Values returned from the Select method of this class. */ - enum SelectRes { - /* A timeout has occurred. */ - TIMEOUT, - /* Data are available for read on the provided FD. */ - READY, - /* Thread exit request has been received. */ - EXIT_THREAD, - /* An error has occurred. */ - ERROR - }; - - /* Select on an FD event, keeping in mind thread exit message. - * Param: - * fd - File descriptor on which to wait for an event. This - * parameter may be negative. If it is negative this method will - * only wait on a control message to the thread. - * timeout - Timeout in microseconds. 0 indicates no timeout (wait - * forever). - * Return: - * See SelectRes enum comments. - */ - SelectRes Select(int fd, int timeout); - - /**************************************************************************** - * Private API - ***************************************************************************/ - - private: - /* Implements abstract method of the base Thread class. */ - bool threadLoop() { - /* Simply dispatch the call to the containing camera device. */ - if (mCameraDevice->inWorkerThread()) { - /* Respect "one burst" parameter (see startThread). */ - return !mOneBurst; - } else { - return false; - } - } - - /* Containing camera device object. */ - EmulatedCameraDevice* mCameraDevice; - - /* FD that is used to send control messages into the thread. */ - int mThreadControl; - - /* FD that thread uses to receive control messages. */ - int mControlFD; - - /* Controls number of times the thread loop runs. - * See startThread for more information. */ - bool mOneBurst; - - /* Enumerates control messages that can be sent into the thread. */ - enum ControlMessage { - /* Stop the thread. */ - THREAD_STOP - }; - - Condition mSetup; - }; - - /* Worker thread accessor. */ - inline WorkerThread* getWorkerThread() const { return mWorkerThread.get(); } - - /**************************************************************************** - * Data members - ***************************************************************************/ - - protected: - /* Locks this instance for parameters, state, etc. change. */ - Mutex mObjectLock; - - /* Worker thread that is used in frame capturing. */ - sp<WorkerThread> mWorkerThread; - - /* Timestamp of the current frame. */ - nsecs_t mCurFrameTimestamp; - - /* Emulated camera object containing this instance. */ - EmulatedCamera* mCameraHAL; - - /* Framebuffer containing the current frame. */ - uint8_t* mCurrentFrame; - - /* - * Framebuffer properties. - */ - - /* Byte size of the framebuffer. */ - size_t mFrameBufferSize; - - /* Original pixel format (one of the V4L2_PIX_FMT_XXX values, as defined in - * bionic/libc/kernel/common/linux/videodev2.h */ - uint32_t mPixelFormat; - - /* Frame width */ - int mFrameWidth; - - /* Frame height */ - int mFrameHeight; - - /* Total number of pixels */ - int mTotalPixels; - - /* Requested FPS rate */ - int mTargetFps; - - /* Exposure compensation value */ - float mExposureCompensation; - - float* mWhiteBalanceScale; - - bool mIsFocusing; - - DefaultKeyedVector<String8, float*> mSupportedWhiteBalanceScale; - - /* Defines possible states of the emulated camera device object. - */ - enum EmulatedCameraDeviceState { - /* Object has been constructed. */ - ECDS_CONSTRUCTED, - /* Object has been initialized. */ - ECDS_INITIALIZED, - /* Object has been connected to the physical device. */ - ECDS_CONNECTED, - /* Camera device has been started. */ - ECDS_STARTED, - }; - - /* Object state. */ - EmulatedCameraDeviceState mState; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_DEVICE_H */ diff --git a/guest/hals/camera/EmulatedCameraFactory.cpp b/guest/hals/camera/EmulatedCameraFactory.cpp deleted file mode 100644 index 857f2ed1..00000000 --- a/guest/hals/camera/EmulatedCameraFactory.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedCameraFactory that manages cameras - * available for emulation. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Factory" -#include <log/log.h> -#include <cutils/properties.h> -#include "EmulatedFakeCamera.h" - -#include "EmulatedCameraHotplugThread.h" -#include "EmulatedFakeCamera2.h" - -#include "EmulatedFakeCamera3.h" - -#include "EmulatedCameraFactory.h" - -extern camera_module_t HAL_MODULE_INFO_SYM; - -namespace android { -EmulatedCameraFactory& EmulatedCameraFactory::Instance() { - static EmulatedCameraFactory* factory = new EmulatedCameraFactory; - return *factory; -} - -EmulatedCameraFactory::EmulatedCameraFactory() - : mCallbacks(NULL) -{ - mCameraConfiguration.Init(); - const std::vector<cvd::CameraDefinition>& cameras = - mCameraConfiguration.cameras(); - for (size_t camera_index = 0; camera_index < cameras.size(); ++camera_index) { - mCameraDefinitions.push(cameras[camera_index]); - /* Reserve a spot for camera, but don't create just yet. */ - mEmulatedCameras.push(NULL); - } - - ALOGV("%zu cameras are being emulated.", getEmulatedCameraNum()); - - /* Create hotplug thread */ - { - mHotplugThread = new EmulatedCameraHotplugThread(getEmulatedCameraNum()); - mHotplugThread->run("EmulatedCameraHotplugThread"); - } -} - -EmulatedBaseCamera* EmulatedCameraFactory::getOrCreateFakeCamera( - size_t cameraId) { - ::cvd::LockGuard< ::cvd::Mutex> lock(mEmulatedCamerasMutex); - - if (cameraId >= getEmulatedCameraNum()) { - ALOGE("%s: Invalid camera ID: %zu", __FUNCTION__, cameraId); - return NULL; - } - - if (mEmulatedCameras[cameraId] != NULL) { - return mEmulatedCameras[cameraId]; - } - - const cvd::CameraDefinition& definition = mCameraDefinitions[cameraId]; - bool is_back_facing = - (definition.orientation == cvd::CameraDefinition::kBack); - - EmulatedBaseCamera* camera; - /* Create, and initialize the fake camera */ - switch (definition.hal_version) { - case cvd::CameraDefinition::kHalV1: - camera = new EmulatedFakeCamera(cameraId, is_back_facing, - &HAL_MODULE_INFO_SYM.common); - break; - case cvd::CameraDefinition::kHalV2: - camera = new EmulatedFakeCamera2(cameraId, is_back_facing, - &HAL_MODULE_INFO_SYM.common); - break; - case cvd::CameraDefinition::kHalV3: - camera = new EmulatedFakeCamera3(cameraId, is_back_facing, - &HAL_MODULE_INFO_SYM.common); - break; - default: - ALOGE("%s: Unsupported camera hal version requested: %d", __FUNCTION__, - definition.hal_version); - return NULL; - } - - ALOGI("%s: Camera device %zu hal version is %d", __FUNCTION__, cameraId, - definition.hal_version); - int res = camera->Initialize(definition); - - if (res != NO_ERROR) { - ALOGE("%s: Unable to intialize camera %zu: %s (%d)", __FUNCTION__, cameraId, - strerror(-res), res); - delete camera; - return NULL; - } - - ALOGI("%s: Inserting camera", __FUNCTION__); - mEmulatedCameras.replaceAt(camera, cameraId); - ALOGI("%s: Done", __FUNCTION__); - return camera; -} - -EmulatedCameraFactory::~EmulatedCameraFactory() { - for (size_t n = 0; n < mEmulatedCameras.size(); n++) { - if (mEmulatedCameras[n] != NULL) { - delete mEmulatedCameras[n]; - } - } - - if (mHotplugThread != NULL) { - mHotplugThread->requestExit(); - mHotplugThread->join(); - } -} - -/**************************************************************************** - * Camera HAL API handlers. - * - * Each handler simply verifies existence of an appropriate EmulatedBaseCamera - * instance, and dispatches the call to that instance. - * - ***************************************************************************/ - -int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, - hw_device_t** device) { - ALOGV("%s: id = %d", __FUNCTION__, camera_id); - - *device = NULL; - - EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id); - if (camera == NULL) return -EINVAL; - - return camera->connectCamera(device); -} - -int EmulatedCameraFactory::getCameraInfo(int camera_id, - struct camera_info* info) { - ALOGV("%s: id = %d", __FUNCTION__, camera_id); - - EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id); - if (camera == NULL) return -EINVAL; - - return camera->getCameraInfo(info); -} - -int EmulatedCameraFactory::setCallbacks( - const camera_module_callbacks_t* callbacks) { - ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks); - - mCallbacks = callbacks; - - return OK; -} - -void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) { - ALOGV("%s: ops = %p", __FUNCTION__, ops); - - // No vendor tags defined for emulator yet, so not touching ops -} - -int EmulatedCameraFactory::setTorchMode(const char* camera_id, bool enabled) { - ALOGV("%s: camera_id = %s, enabled =%d", __FUNCTION__, camera_id, enabled); - - EmulatedBaseCamera* camera = getOrCreateFakeCamera(atoi(camera_id)); - if (camera == NULL) return -EINVAL; - - return camera->setTorchMode(enabled); -} - -/**************************************************************************** - * Camera HAL API callbacks. - ***************************************************************************/ - -int EmulatedCameraFactory::device_open(const hw_module_t* module, - const char* name, hw_device_t** device) { - /* - * Simply verify the parameters, and dispatch the call inside the - * EmulatedCameraFactory instance. - */ - - if (module != &HAL_MODULE_INFO_SYM.common) { - ALOGE("%s: Invalid module %p expected %p", __FUNCTION__, module, - &HAL_MODULE_INFO_SYM.common); - return -EINVAL; - } - if (name == NULL) { - ALOGE("%s: NULL name is not expected here", __FUNCTION__); - return -EINVAL; - } - - return EmulatedCameraFactory::Instance().cameraDeviceOpen(atoi(name), device); -} - -int EmulatedCameraFactory::get_number_of_cameras(void) { - return EmulatedCameraFactory::Instance().getEmulatedCameraNum(); -} - -int EmulatedCameraFactory::get_camera_info(int camera_id, - struct camera_info* info) { - return EmulatedCameraFactory::Instance().getCameraInfo(camera_id, info); -} - -int EmulatedCameraFactory::set_callbacks( - const camera_module_callbacks_t* callbacks) { - return EmulatedCameraFactory::Instance().setCallbacks(callbacks); -} - -void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops) { - EmulatedCameraFactory::Instance().getVendorTagOps(ops); -} - -int EmulatedCameraFactory::open_legacy(const struct hw_module_t* /*module*/, - const char* /*id*/, - uint32_t /*halVersion*/, - struct hw_device_t** /*device*/) { - // Not supporting legacy open - return -ENOSYS; -} - -int EmulatedCameraFactory::set_torch_mode(const char* camera_id, bool enabled) { - return EmulatedCameraFactory::Instance().setTorchMode(camera_id, enabled); -} - -/******************************************************************************** - * Internal API - *******************************************************************************/ - -void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) { - EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId); - if (!cam) { - ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId); - return; - } - - /** - * (Order is important) - * Send the callback first to framework, THEN close the camera. - */ - - if (newStatus == cam->getHotplugStatus()) { - ALOGW("%s: Ignoring transition to the same status", __FUNCTION__); - return; - } - - const camera_module_callbacks_t* cb = mCallbacks; - if (cb != NULL && cb->camera_device_status_change != NULL) { - cb->camera_device_status_change(cb, cameraId, newStatus); - } - - if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) { - cam->unplugCamera(); - } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) { - cam->plugCamera(); - } -} - -void EmulatedCameraFactory::onTorchModeStatusChanged(int cameraId, - int newStatus) { - EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId); - if (!cam) { - ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId); - return; - } - - const camera_module_callbacks_t* cb = mCallbacks; - if (cb != NULL && cb->torch_mode_status_change != NULL) { - char id[10]; - sprintf(id, "%d", cameraId); - cb->torch_mode_status_change(cb, id, newStatus); - } -} - -/******************************************************************************** - * Initializer for the static member structure. - *******************************************************************************/ - -/* Entry point for camera HAL API. */ -struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = { - .open = EmulatedCameraFactory::device_open}; - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedCameraFactory.h b/guest/hals/camera/EmulatedCameraFactory.h deleted file mode 100644 index 1c5b9cd4..00000000 --- a/guest/hals/camera/EmulatedCameraFactory.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H - -#include <utils/RefBase.h> - -#include <utils/Vector.h> -#include "CameraConfiguration.h" -#include "EmulatedBaseCamera.h" -#include "common/libs/threads/cuttlefish_thread.h" - -namespace android { - -class EmulatedCameraHotplugThread; - -/* - * Contains declaration of a class EmulatedCameraFactory that manages cameras - * available for the emulation. A global instance of this class is statically - * instantiated and initialized when camera emulation HAL is loaded. - */ - -/* Class EmulatedCameraFactoryManages cameras available for the emulation. - * - * When the global static instance of this class is created on the module load, - * it enumerates cameras available for the emulation by connecting to the - * emulator's 'camera' service. For every camera found out there it creates an - * instance of an appropriate class, and stores it an in array of emulated - * cameras. In addition to the cameras reported by the emulator, a fake camera - * emulator is always created, so there is always at least one camera that is - * available. - * - * Instance of this class is also used as the entry point for the camera HAL - * API, including: - * - hw_module_methods_t::open entry point - * - camera_module_t::get_number_of_cameras entry point - * - camera_module_t::get_camera_info entry point - * - */ -class EmulatedCameraFactory { - public: - /* Constructs EmulatedCameraFactory instance. - * In this constructor the factory will create and initialize a list of - * emulated cameras. All errors that occur on this constructor are reported - * via mConstructedOK data member of this class. - */ - EmulatedCameraFactory(); - - /* Destructs EmulatedCameraFactory instance. */ - ~EmulatedCameraFactory(); - - /**************************************************************************** - * Camera HAL API handlers. - ***************************************************************************/ - - public: - /* Returns a (singleton) instance of the EmulatedCameraFactory. - */ - static EmulatedCameraFactory& Instance(); - - /* Opens (connects to) a camera device. - * This method is called in response to hw_module_methods_t::open callback. - */ - int cameraDeviceOpen(int camera_id, hw_device_t** device); - - /* Gets emulated camera information. - * This method is called in response to camera_module_t::get_camera_info - * callback. - */ - int getCameraInfo(int camera_id, struct camera_info* info); - - /* Sets emulated camera callbacks. - * This method is called in response to camera_module_t::set_callbacks - * callback. - */ - int setCallbacks(const camera_module_callbacks_t* callbacks); - - /* Fill in vendor tags for the module - * This method is called in response to camera_module_t::get_vendor_tag_ops - * callback. - */ - void getVendorTagOps(vendor_tag_ops_t* ops); - - int setTorchMode(const char* camera_id, bool enabled); - - /**************************************************************************** - * Camera HAL API callbacks. - ***************************************************************************/ - - public: - /* camera_module_t::get_number_of_cameras callback entry point. */ - static int get_number_of_cameras(void); - - /* camera_module_t::get_camera_info callback entry point. */ - static int get_camera_info(int camera_id, struct camera_info* info); - - /* camera_module_t::set_callbacks callback entry point. */ - static int set_callbacks(const camera_module_callbacks_t* callbacks); - - /* camera_module_t::get_vendor_tag_ops callback entry point */ - static void get_vendor_tag_ops(vendor_tag_ops_t* ops); - - /* camera_module_t::open_legacy callback entry point */ - static int open_legacy(const struct hw_module_t* module, const char* id, - uint32_t halVersion, struct hw_device_t** device); - - static int set_torch_mode(const char* camera_id, bool enabled); - - private: - /* hw_module_methods_t::open callback entry point. */ - static int device_open(const hw_module_t* module, const char* name, - hw_device_t** device); - - /**************************************************************************** - * Public API. - ***************************************************************************/ - - public: - /* Gets fake camera orientation. */ - int getFakeCameraOrientation() { - /* TODO: Have a boot property that controls that. */ - return 90; - } - - /* Gets number of emulated cameras. - */ - inline size_t getEmulatedCameraNum() const { - return mCameraDefinitions.size(); - } - - void onStatusChanged(int cameraId, int newStatus); - - void onTorchModeStatusChanged(int cameraId, int newStatus); - - /**************************************************************************** - * Private API - ***************************************************************************/ - - private: - /* Create new or return existing fake camera based on camera definition - * found in mCameraDefinitions. - * Returns NULL if cameraId is not valid (= not a valid index of - * mCameraDefinitions) - */ - EmulatedBaseCamera* getOrCreateFakeCamera(size_t cameraId); - - /**************************************************************************** - * Data members. - ***************************************************************************/ - - private: - /* Array of cameras available for the emulation. */ - Vector<EmulatedBaseCamera*> mEmulatedCameras; - - /* Guards access to mEmulatedCameras. */ - cvd::Mutex mEmulatedCamerasMutex; - - /* Camera callbacks (for status changing) */ - const camera_module_callbacks_t* mCallbacks; - - /* Hotplug thread (to call onStatusChanged) */ - sp<EmulatedCameraHotplugThread> mHotplugThread; - - /* Back- and front camera properties accessed from the vsoc device. */ - cvd::CameraConfiguration mCameraConfiguration; - Vector<cvd::CameraDefinition> mCameraDefinitions; - - public: - /* Contains device open entry point, as required by HAL API. */ - static struct hw_module_methods_t mCameraModuleMethods; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_CAMERA_FACTORY_H */ diff --git a/guest/hals/camera/EmulatedCameraHal.cpp b/guest/hals/camera/EmulatedCameraHal.cpp deleted file mode 100644 index 2aba50ae..00000000 --- a/guest/hals/camera/EmulatedCameraHal.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of the camera HAL layer in the system running - * under the emulator. - * - * This file contains only required HAL header, which directs all the API calls - * to the EmulatedCameraFactory class implementation, wich is responsible for - * managing emulated cameras. - */ - -#include "EmulatedCameraFactory.h" - -/* - * Required HAL header. - */ -camera_module_t HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = - CAMERA_MODULE_API_VERSION_2_4, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = CAMERA_HARDWARE_MODULE_ID, - .name = "Emulated Camera Module", - .author = "The Android Open Source Project", - .methods = & - android::EmulatedCameraFactory::mCameraModuleMethods, - .dso = NULL, - .reserved = {0}, - }, - .get_number_of_cameras = - android::EmulatedCameraFactory::get_number_of_cameras, - .get_camera_info = - android::EmulatedCameraFactory::get_camera_info, - .set_callbacks = - android::EmulatedCameraFactory::set_callbacks, - .get_vendor_tag_ops = - android::EmulatedCameraFactory::get_vendor_tag_ops, - .open_legacy = - android::EmulatedCameraFactory::open_legacy, - .set_torch_mode = - android::EmulatedCameraFactory::set_torch_mode, -}; diff --git a/guest/hals/camera/EmulatedCameraHotplugThread.cpp b/guest/hals/camera/EmulatedCameraHotplugThread.cpp deleted file mode 100644 index 34a4c158..00000000 --- a/guest/hals/camera/EmulatedCameraHotplugThread.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_HotplugThread" -#include <log/log.h> - -#include <fcntl.h> -#include <sys/inotify.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "EmulatedCameraFactory.h" -#include "EmulatedCameraHotplugThread.h" - -#define FAKE_HOTPLUG_FILE "/data/misc/media/emulator.camera.hotplug" - -#define EVENT_SIZE (sizeof(struct inotify_event)) -#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) - -#define SubscriberInfo EmulatedCameraHotplugThread::SubscriberInfo - -namespace android { - -EmulatedCameraHotplugThread::EmulatedCameraHotplugThread( - size_t totalCameraCount) - : Thread(/*canCallJava*/ false) { - mRunning = true; - mInotifyFd = 0; - - for (size_t id = 0; id < totalCameraCount; ++id) { - if (createFileIfNotExists(id)) { - mSubscribedCameraIds.push_back(id); - } - } -} - -EmulatedCameraHotplugThread::~EmulatedCameraHotplugThread() {} - -status_t EmulatedCameraHotplugThread::requestExitAndWait() { - ALOGE("%s: Not implemented. Use requestExit + join instead", __FUNCTION__); - return INVALID_OPERATION; -} - -void EmulatedCameraHotplugThread::requestExit() { - Mutex::Autolock al(mMutex); - - ALOGV("%s: Requesting thread exit", __FUNCTION__); - mRunning = false; - - bool rmWatchFailed = false; - Vector<SubscriberInfo>::iterator it; - for (it = mSubscribers.begin(); it != mSubscribers.end(); ++it) { - if (inotify_rm_watch(mInotifyFd, it->WatchID) == -1) { - ALOGE( - "%s: Could not remove watch for camID '%d'," - " error: '%s' (%d)", - __FUNCTION__, it->CameraID, strerror(errno), errno); - - rmWatchFailed = true; - } else { - ALOGV("%s: Removed watch for camID '%d'", __FUNCTION__, it->CameraID); - } - } - - if (rmWatchFailed) { // unlikely - // Give the thread a fighting chance to error out on the next - // read - if (close(mInotifyFd) == -1) { - ALOGE("%s: close failure error: '%s' (%d)", __FUNCTION__, strerror(errno), - errno); - } - } - - ALOGV("%s: Request exit complete.", __FUNCTION__); -} - -status_t EmulatedCameraHotplugThread::readyToRun() { - Mutex::Autolock al(mMutex); - - mInotifyFd = -1; - - do { - ALOGV("%s: Initializing inotify", __FUNCTION__); - - mInotifyFd = inotify_init(); - if (mInotifyFd == -1) { - ALOGE("%s: inotify_init failure error: '%s' (%d)", __FUNCTION__, - strerror(errno), errno); - mRunning = false; - break; - } - - /** - * For each fake camera file, add a watch for when - * the file is closed (if it was written to) - */ - Vector<int>::const_iterator it, end; - it = mSubscribedCameraIds.begin(); - end = mSubscribedCameraIds.end(); - for (; it != end; ++it) { - int cameraId = *it; - if (!addWatch(cameraId)) { - mRunning = false; - break; - } - } - } while (false); - - if (!mRunning) { - status_t err = -errno; - - if (mInotifyFd != -1) { - close(mInotifyFd); - } - - return err; - } - - return OK; -} - -bool EmulatedCameraHotplugThread::threadLoop() { - // If requestExit was already called, mRunning will be false - while (mRunning) { - char buffer[EVENT_BUF_LEN]; - int length = TEMP_FAILURE_RETRY(read(mInotifyFd, buffer, EVENT_BUF_LEN)); - - if (length < 0) { - ALOGE("%s: Error reading from inotify FD, error: '%s' (%d)", __FUNCTION__, - strerror(errno), errno); - mRunning = false; - break; - } - - ALOGV("%s: Read %d bytes from inotify FD", __FUNCTION__, length); - - int i = 0; - while (i < length) { - inotify_event* event = (inotify_event*)&buffer[i]; - - if (event->mask & IN_IGNORED) { - Mutex::Autolock al(mMutex); - if (!mRunning) { - ALOGV("%s: Shutting down thread", __FUNCTION__); - break; - } else { - ALOGE("%s: File was deleted, aborting", __FUNCTION__); - mRunning = false; - break; - } - } else if (event->mask & IN_CLOSE_WRITE) { - int cameraId = getCameraId(event->wd); - - if (cameraId < 0) { - ALOGE("%s: Got bad camera ID from WD '%d", __FUNCTION__, event->wd); - } else { - // Check the file for the new hotplug event - String8 filePath = getFilePath(cameraId); - /** - * NOTE: we carefully avoid getting an inotify - * for the same exact file because it's opened for - * read-only, but our inotify is for write-only - */ - int newStatus = readFile(filePath); - - if (newStatus < 0) { - mRunning = false; - break; - } - - int halStatus = newStatus ? CAMERA_DEVICE_STATUS_PRESENT - : CAMERA_DEVICE_STATUS_NOT_PRESENT; - EmulatedCameraFactory::Instance().onStatusChanged(cameraId, - halStatus); - } - - } else { - ALOGW("%s: Unknown mask 0x%x", __FUNCTION__, event->mask); - } - - i += EVENT_SIZE + event->len; - } - } - - if (!mRunning) { - close(mInotifyFd); - return false; - } - - return true; -} - -String8 EmulatedCameraHotplugThread::getFilePath(int cameraId) const { - return String8::format(FAKE_HOTPLUG_FILE ".%d", cameraId); -} - -bool EmulatedCameraHotplugThread::createFileIfNotExists(int cameraId) const { - String8 filePath = getFilePath(cameraId); - // make sure this file exists and we have access to it - int fd = - TEMP_FAILURE_RETRY(open(filePath.string(), O_WRONLY | O_CREAT | O_TRUNC, - /* mode = ug+rwx */ S_IRWXU | S_IRWXG)); - if (fd == -1) { - ALOGE("%s: Could not create file '%s', error: '%s' (%d)", __FUNCTION__, - filePath.string(), strerror(errno), errno); - return false; - } - - // File has '1' by default since we are plugged in by default - if (TEMP_FAILURE_RETRY(write(fd, "1\n", /*count*/ 2)) == -1) { - ALOGE("%s: Could not write '1' to file '%s', error: '%s' (%d)", - __FUNCTION__, filePath.string(), strerror(errno), errno); - return false; - } - - close(fd); - return true; -} - -int EmulatedCameraHotplugThread::getCameraId(String8 filePath) const { - Vector<int>::const_iterator it, end; - it = mSubscribedCameraIds.begin(); - end = mSubscribedCameraIds.end(); - for (; it != end; ++it) { - String8 camPath = getFilePath(*it); - - if (camPath == filePath) { - return *it; - } - } - - return NAME_NOT_FOUND; -} - -int EmulatedCameraHotplugThread::getCameraId(int wd) const { - for (size_t i = 0; i < mSubscribers.size(); ++i) { - if (mSubscribers[i].WatchID == wd) { - return mSubscribers[i].CameraID; - } - } - - return NAME_NOT_FOUND; -} - -SubscriberInfo* EmulatedCameraHotplugThread::getSubscriberInfo(int cameraId) { - for (size_t i = 0; i < mSubscribers.size(); ++i) { - if (mSubscribers[i].CameraID == cameraId) { - return (SubscriberInfo*)&mSubscribers[i]; - } - } - - return NULL; -} - -bool EmulatedCameraHotplugThread::addWatch(int cameraId) { - String8 camPath = getFilePath(cameraId); - int wd = inotify_add_watch(mInotifyFd, camPath.string(), IN_CLOSE_WRITE); - - if (wd == -1) { - ALOGE("%s: Could not add watch for '%s', error: '%s' (%d)", __FUNCTION__, - camPath.string(), strerror(errno), errno); - - mRunning = false; - return false; - } - - ALOGV("%s: Watch added for camID='%d', wd='%d'", __FUNCTION__, cameraId, wd); - - SubscriberInfo si = {cameraId, wd}; - mSubscribers.push_back(si); - - return true; -} - -bool EmulatedCameraHotplugThread::removeWatch(int cameraId) { - SubscriberInfo* si = getSubscriberInfo(cameraId); - - if (!si) return false; - - if (inotify_rm_watch(mInotifyFd, si->WatchID) == -1) { - ALOGE("%s: Could not remove watch for camID '%d', error: '%s' (%d)", - __FUNCTION__, cameraId, strerror(errno), errno); - - return false; - } - - Vector<SubscriberInfo>::iterator it; - for (it = mSubscribers.begin(); it != mSubscribers.end(); ++it) { - if (it->CameraID == cameraId) { - break; - } - } - - if (it != mSubscribers.end()) { - mSubscribers.erase(it); - } - - return true; -} - -int EmulatedCameraHotplugThread::readFile(String8 filePath) const { - int fd = TEMP_FAILURE_RETRY(open(filePath.string(), O_RDONLY, /*mode*/ 0)); - if (fd == -1) { - ALOGE("%s: Could not open file '%s', error: '%s' (%d)", __FUNCTION__, - filePath.string(), strerror(errno), errno); - return -1; - } - - char buffer[1]; - int length; - - length = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer))); - - int retval; - - ALOGV("%s: Read file '%s', length='%d', buffer='%c'", __FUNCTION__, - filePath.string(), length, buffer[0]); - - if (length == 0) { // EOF - retval = 0; // empty file is the same thing as 0 - } else if (buffer[0] == '0') { - retval = 0; - } else { // anything non-empty that's not beginning with '0' - retval = 1; - } - - close(fd); - - return retval; -} - -} // namespace android diff --git a/guest/hals/camera/EmulatedCameraHotplugThread.h b/guest/hals/camera/EmulatedCameraHotplugThread.h deleted file mode 100644 index bc288895..00000000 --- a/guest/hals/camera/EmulatedCameraHotplugThread.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_CAMERA_HOTPLUG_H -#define HW_EMULATOR_CAMERA_EMULATED_CAMERA_HOTPLUG_H - -/** - * This class emulates hotplug events by inotifying on a file, specific - * to a camera ID. When the file changes between 1/0 the hotplug - * status goes between PRESENT and NOT_PRESENT. - * - * Refer to FAKE_HOTPLUG_FILE in EmulatedCameraHotplugThread.cpp - */ - -#include <utils/String8.h> -#include <utils/Vector.h> -#include "EmulatedCamera2.h" - -namespace android { -class EmulatedCameraHotplugThread : public Thread { - public: - EmulatedCameraHotplugThread(size_t totalCameraCount); - ~EmulatedCameraHotplugThread(); - - virtual void requestExit(); - virtual status_t requestExitAndWait(); - - private: - virtual status_t readyToRun(); - virtual bool threadLoop(); - - struct SubscriberInfo { - int CameraID; - int WatchID; - }; - - bool addWatch(int cameraId); - bool removeWatch(int cameraId); - SubscriberInfo* getSubscriberInfo(int cameraId); - - int getCameraId(String8 filePath) const; - int getCameraId(int wd) const; - - String8 getFilePath(int cameraId) const; - int readFile(String8 filePath) const; - - bool createFileIfNotExists(int cameraId) const; - - Vector<int> mSubscribedCameraIds; - Vector<SubscriberInfo> mSubscribers; - - // variables above are unguarded: - // -- accessed in thread loop or in constructor only - - Mutex mMutex; - - bool mRunning; // guarding only when it's important -}; -} // namespace android - -#endif diff --git a/guest/hals/camera/EmulatedFakeCamera.cpp b/guest/hals/camera/EmulatedFakeCamera.cpp deleted file mode 100644 index 4153fd7a..00000000 --- a/guest/hals/camera/EmulatedFakeCamera.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedFakeCamera that encapsulates - * functionality of a fake camera. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_FakeCamera" -#include "EmulatedFakeCamera.h" -#include <log/log.h> -#include <cutils/properties.h> -#undef min -#undef max -#include <algorithm> -#include <sstream> -#include <string> -#include "EmulatedCameraFactory.h" - -namespace android { - -EmulatedFakeCamera::EmulatedFakeCamera(int cameraId, bool facingBack, - struct hw_module_t* module) - : EmulatedCamera(cameraId, module), - mFacingBack(facingBack), - mFakeCameraDevice(this) {} - -EmulatedFakeCamera::~EmulatedFakeCamera() {} - -/**************************************************************************** - * Public API overrides - ***************************************************************************/ - -status_t EmulatedFakeCamera::Initialize(const cvd::CameraDefinition& params) { - status_t res = mFakeCameraDevice.Initialize(); - if (res != NO_ERROR) { - return res; - } - - const char* facing = - mFacingBack ? EmulatedCamera::FACING_BACK : EmulatedCamera::FACING_FRONT; - - mParameters.set(EmulatedCamera::FACING_KEY, facing); - ALOGD("%s: Fake camera is facing %s", __FUNCTION__, facing); - - mParameters.set(EmulatedCamera::ORIENTATION_KEY, - EmulatedCameraFactory::Instance().getFakeCameraOrientation()); - - res = EmulatedCamera::Initialize(params); - if (res != NO_ERROR) { - return res; - } - - /* - * Parameters provided by the camera device. - */ - - /* 352x288 and 320x240 frame dimensions are required by the framework for - * video mode preview and video recording. */ - std::ostringstream resolutions; - for (size_t index = 0; index < params.resolutions.size(); ++index) { - if (resolutions.str().size()) { - resolutions << ","; - } - resolutions << params.resolutions[index].width << "x" - << params.resolutions[index].height; - } - - mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, - resolutions.str().c_str()); - mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, - resolutions.str().c_str()); - mParameters.setPreviewSize(640, 480); - mParameters.setPictureSize(640, 480); - - mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, - CameraParameters::ANTIBANDING_AUTO); - mParameters.set(CameraParameters::KEY_ANTIBANDING, - CameraParameters::ANTIBANDING_AUTO); - mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, - CameraParameters::EFFECT_NONE); - mParameters.set(CameraParameters::KEY_EFFECT, CameraParameters::EFFECT_NONE); - - return NO_ERROR; -} - -EmulatedCameraDevice* EmulatedFakeCamera::getCameraDevice() { - return &mFakeCameraDevice; -} - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedFakeCamera.h b/guest/hals/camera/EmulatedFakeCamera.h deleted file mode 100644 index 5afba3fa..00000000 --- a/guest/hals/camera/EmulatedFakeCamera.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H -#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H - -/* - * Contains declaration of a class EmulatedFakeCamera that encapsulates - * functionality of a fake camera. This class is nothing more than a placeholder - * for EmulatedFakeCameraDevice instance. - */ - -#include "EmulatedCamera.h" -#include "EmulatedFakeCameraDevice.h" - -namespace android { - -/* Encapsulates functionality of a fake camera. - * This class is nothing more than a placeholder for EmulatedFakeCameraDevice - * instance that emulates a fake camera device. - */ -class EmulatedFakeCamera : public EmulatedCamera { - public: - /* Constructs EmulatedFakeCamera instance. */ - EmulatedFakeCamera(int cameraId, bool facingBack, struct hw_module_t* module); - - /* Destructs EmulatedFakeCamera instance. */ - ~EmulatedFakeCamera(); - - /**************************************************************************** - * EmulatedCamera virtual overrides. - ***************************************************************************/ - - public: - /* Initializes EmulatedFakeCamera instance. */ - status_t Initialize(const cvd::CameraDefinition& params); - - /**************************************************************************** - * EmulatedCamera abstract API implementation. - ***************************************************************************/ - - protected: - /* Gets emulated camera device ised by this instance of the emulated camera. - */ - EmulatedCameraDevice* getCameraDevice(); - - /**************************************************************************** - * Data memebers. - ***************************************************************************/ - - protected: - /* Facing back (true) or front (false) switch. */ - bool mFacingBack; - - /* Contained fake camera device object. */ - EmulatedFakeCameraDevice mFakeCameraDevice; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_H */ diff --git a/guest/hals/camera/EmulatedFakeCamera2.cpp b/guest/hals/camera/EmulatedFakeCamera2.cpp deleted file mode 100644 index 393adf1e..00000000 --- a/guest/hals/camera/EmulatedFakeCamera2.cpp +++ /dev/null @@ -1,2606 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* - * Contains implementation of a class EmulatedFakeCamera2 that encapsulates - * functionality of an advanced fake camera. - */ - -#include <inttypes.h> - -#include <algorithm> -#include <cstdint> -#include <iterator> - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_FakeCamera2" -#include <utils/Log.h> - -#include "EmulatedCameraFactory.h" -#include "EmulatedFakeCamera2.h" -#include "GrallocModule.h" - -#define ERROR_CAMERA_NOT_PRESENT -EPIPE - -#define CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT 0xFFFFFFFF - -template <typename T, size_t N> -char (&ArraySizeHelper(T (&array)[N]))[N]; - -template <typename T, size_t N> -char (&ArraySizeHelper(const T (&array)[N]))[N]; - -#define arraysize(array) (sizeof(ArraySizeHelper(array))) - -namespace android { - -const int64_t USEC = 1000LL; -const int64_t MSEC = USEC * 1000LL; -const int64_t SEC = MSEC * 1000LL; - -const uint32_t EmulatedFakeCamera2::kAvailableFormats[] = { - HAL_PIXEL_FORMAT_RAW16, - HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888, - // HAL_PIXEL_FORMAT_YV12, - HAL_PIXEL_FORMAT_YCrCb_420_SP}; - -const uint32_t EmulatedFakeCamera2::kAvailableRawSizes[2] = { - 640, 480 - // mSensorWidth, mSensorHeight -}; - -const uint64_t EmulatedFakeCamera2::kAvailableRawMinDurations[1] = { - static_cast<uint64_t>(Sensor::kFrameDurationRange[0])}; - -const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesBack[4] = { - 640, 480, 320, 240 - // mSensorWidth, mSensorHeight -}; - -const uint32_t EmulatedFakeCamera2::kAvailableProcessedSizesFront[4] = { - 320, 240, 160, 120 - // mSensorWidth, mSensorHeight -}; - -const uint64_t EmulatedFakeCamera2::kAvailableProcessedMinDurations[1] = { - static_cast<uint64_t>(Sensor::kFrameDurationRange[0])}; - -const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesBack[2] = { - 640, 480 - // mSensorWidth, mSensorHeight -}; - -const uint32_t EmulatedFakeCamera2::kAvailableJpegSizesFront[2] = { - 320, 240 - // mSensorWidth, mSensorHeight -}; - -const uint64_t EmulatedFakeCamera2::kAvailableJpegMinDurations[1] = { - static_cast<uint64_t>(Sensor::kFrameDurationRange[0])}; - -EmulatedFakeCamera2::EmulatedFakeCamera2(int cameraId, bool facingBack, - struct hw_module_t *module) - : EmulatedCamera2(cameraId, module), - mFacingBack(facingBack), - mIsConnected(false) { - ALOGD("Constructing emulated fake camera 2 facing %s", - facingBack ? "back" : "front"); -} - -EmulatedFakeCamera2::~EmulatedFakeCamera2() { - if (mCameraInfo != NULL) { - free_camera_metadata(mCameraInfo); - } -} - -/**************************************************************************** - * Public API overrides - ***************************************************************************/ - -status_t EmulatedFakeCamera2::Initialize(const cvd::CameraDefinition ¶ms) { - status_t res; - - for (size_t index = 0; index < params.resolutions.size(); ++index) { - mAvailableRawSizes.push_back(params.resolutions[index].width); - mAvailableRawSizes.push_back(params.resolutions[index].height); - mAvailableProcessedSizes.push_back(params.resolutions[index].width); - mAvailableProcessedSizes.push_back(params.resolutions[index].height); - mAvailableJpegSizes.push_back(params.resolutions[index].width); - mAvailableJpegSizes.push_back(params.resolutions[index].height); - } - - // Find max width/height - int32_t width = 0, height = 0; - for (size_t index = 0; index < params.resolutions.size(); ++index) { - if (width <= params.resolutions[index].width && - height <= params.resolutions[index].height) { - width = params.resolutions[index].width; - height = params.resolutions[index].height; - } - } - if (width < 640 || height < 480) { - width = 640; - height = 480; - } - mSensorWidth = width; - mSensorHeight = height; - - /* TODO(ender): probably should drop this. */ - std::copy(kAvailableRawSizes, - kAvailableRawSizes + arraysize(kAvailableRawSizes), - std::back_inserter(mAvailableRawSizes)); - - if (params.orientation == cvd::CameraDefinition::kFront) { - std::copy(kAvailableProcessedSizesFront, - kAvailableProcessedSizesFront + - arraysize(kAvailableProcessedSizesFront), - std::back_inserter(mAvailableProcessedSizes)); - std::copy(kAvailableJpegSizesFront, - kAvailableJpegSizesFront + arraysize(kAvailableJpegSizesFront), - std::back_inserter(mAvailableJpegSizes)); - } else { - std::copy( - kAvailableProcessedSizesBack, - kAvailableProcessedSizesBack + arraysize(kAvailableProcessedSizesBack), - mAvailableProcessedSizes.begin()); - std::copy(kAvailableJpegSizesBack, - kAvailableJpegSizesBack + arraysize(kAvailableJpegSizesBack), - mAvailableJpegSizes.begin()); - } - - res = constructStaticInfo(&mCameraInfo, true); - if (res != OK) { - ALOGE("%s: Unable to allocate static info: %s (%d)", __FUNCTION__, - strerror(-res), res); - return res; - } - res = constructStaticInfo(&mCameraInfo, false); - if (res != OK) { - ALOGE("%s: Unable to fill in static info: %s (%d)", __FUNCTION__, - strerror(-res), res); - return res; - } - if (res != OK) return res; - - mNextStreamId = 1; - mNextReprocessStreamId = 1; - mRawStreamCount = 0; - mProcessedStreamCount = 0; - mJpegStreamCount = 0; - mReprocessStreamCount = 0; - - return NO_ERROR; -} - -/**************************************************************************** - * Camera module API overrides - ***************************************************************************/ - -status_t EmulatedFakeCamera2::connectCamera(hw_device_t **device) { - status_t res; - ALOGV("%s", __FUNCTION__); - - { - Mutex::Autolock l(mMutex); - if (!mStatusPresent) { - ALOGE("%s: Camera ID %d is unplugged", __FUNCTION__, mCameraID); - return -ENODEV; - } - } - - mConfigureThread = new ConfigureThread(this); - mReadoutThread = new ReadoutThread(this); - mControlThread = new ControlThread(this); - mSensor = new Sensor(mSensorWidth, mSensorHeight); - mJpegCompressor = new JpegCompressor(); - - mNextStreamId = 1; - mNextReprocessStreamId = 1; - - res = mSensor->startUp(); - if (res != NO_ERROR) return res; - - res = mConfigureThread->run("EmulatedFakeCamera2::configureThread"); - if (res != NO_ERROR) return res; - - res = mReadoutThread->run("EmulatedFakeCamera2::readoutThread"); - if (res != NO_ERROR) return res; - - res = mControlThread->run("EmulatedFakeCamera2::controlThread"); - if (res != NO_ERROR) return res; - - status_t ret = EmulatedCamera2::connectCamera(device); - - if (ret >= 0) { - mIsConnected = true; - } - - return ret; -} - -status_t EmulatedFakeCamera2::plugCamera() { - { - Mutex::Autolock l(mMutex); - - if (!mStatusPresent) { - ALOGI("%s: Plugged back in", __FUNCTION__); - mStatusPresent = true; - } - } - - return NO_ERROR; -} - -status_t EmulatedFakeCamera2::unplugCamera() { - { - Mutex::Autolock l(mMutex); - - if (mStatusPresent) { - ALOGI("%s: Unplugged camera", __FUNCTION__); - mStatusPresent = false; - } - } - - return closeCamera(); -} - -camera_device_status_t EmulatedFakeCamera2::getHotplugStatus() { - Mutex::Autolock l(mMutex); - return mStatusPresent ? CAMERA_DEVICE_STATUS_PRESENT - : CAMERA_DEVICE_STATUS_NOT_PRESENT; -} - -status_t EmulatedFakeCamera2::closeCamera() { - { - Mutex::Autolock l(mMutex); - - status_t res; - ALOGV("%s", __FUNCTION__); - - if (!mIsConnected) { - return NO_ERROR; - } - - res = mSensor->shutDown(); - if (res != NO_ERROR) { - ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res); - return res; - } - - mConfigureThread->requestExit(); - mReadoutThread->requestExit(); - mControlThread->requestExit(); - mJpegCompressor->cancel(); - } - - // give up the lock since we will now block and the threads - // can call back into this object - mConfigureThread->join(); - mReadoutThread->join(); - mControlThread->join(); - - ALOGV("%s exit", __FUNCTION__); - - { - Mutex::Autolock l(mMutex); - mIsConnected = false; - } - - return NO_ERROR; -} - -status_t EmulatedFakeCamera2::getCameraInfo(struct camera_info *info) { - info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT; - info->orientation = - EmulatedCameraFactory::Instance().getFakeCameraOrientation(); - return EmulatedCamera2::getCameraInfo(info); -} - -/**************************************************************************** - * Camera device API overrides - ***************************************************************************/ - -/** Request input queue */ - -int EmulatedFakeCamera2::requestQueueNotify() { - ALOGV("Request queue notification received"); - - ALOG_ASSERT(mRequestQueueSrc != NULL, - "%s: Request queue src not set, but received queue notification!", - __FUNCTION__); - ALOG_ASSERT(mFrameQueueDst != NULL, - "%s: Request queue src not set, but received queue notification!", - __FUNCTION__); - ALOG_ASSERT(mStreams.size() != 0, - "%s: No streams allocated, but received queue notification!", - __FUNCTION__); - return mConfigureThread->newRequestAvailable(); -} - -int EmulatedFakeCamera2::getInProgressCount() { - Mutex::Autolock l(mMutex); - - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - - int requestCount = 0; - requestCount += mConfigureThread->getInProgressCount(); - requestCount += mReadoutThread->getInProgressCount(); - requestCount += mJpegCompressor->isBusy() ? 1 : 0; - - return requestCount; -} - -int EmulatedFakeCamera2::constructDefaultRequest(int request_template, - camera_metadata_t **request) { - if (request == NULL) return BAD_VALUE; - if (request_template < 0 || request_template >= CAMERA2_TEMPLATE_COUNT) { - return BAD_VALUE; - } - - { - Mutex::Autolock l(mMutex); - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - } - - status_t res; - // Pass 1, calculate size and allocate - res = constructDefaultRequest(request_template, request, true); - if (res != OK) { - return res; - } - // Pass 2, build request - res = constructDefaultRequest(request_template, request, false); - if (res != OK) { - ALOGE("Unable to populate new request for template %d", request_template); - } - - return res; -} - -int EmulatedFakeCamera2::allocateStream( - uint32_t width, uint32_t height, int format, - const camera2_stream_ops_t *stream_ops, uint32_t *stream_id, - uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers) { - Mutex::Autolock l(mMutex); - - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - - // Temporary shim until FORMAT_ZSL is removed - if (format == CAMERA2_HAL_PIXEL_FORMAT_ZSL) { - format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; - } - - if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { - unsigned int numFormats = sizeof(kAvailableFormats) / sizeof(uint32_t); - unsigned int formatIdx = 0; - for (; formatIdx < numFormats; formatIdx++) { - if (format == (int)kAvailableFormats[formatIdx]) break; - } - if (formatIdx == numFormats) { - ALOGE("%s: Format 0x%x is not supported", __FUNCTION__, format); - return BAD_VALUE; - } - } - - const uint32_t *availableSizes; - size_t availableSizeCount; - switch (format) { - case HAL_PIXEL_FORMAT_RAW16: - availableSizes = &mAvailableRawSizes.front(); - availableSizeCount = mAvailableRawSizes.size(); - break; - case HAL_PIXEL_FORMAT_BLOB: - availableSizes = &mAvailableJpegSizes.front(); - availableSizeCount = mAvailableJpegSizes.size(); - break; - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_YV12: - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - availableSizes = &mAvailableProcessedSizes.front(); - availableSizeCount = mAvailableProcessedSizes.size(); - break; - default: - ALOGE("%s: Unknown format 0x%x", __FUNCTION__, format); - return BAD_VALUE; - } - - unsigned int resIdx = 0; - for (; resIdx < availableSizeCount; resIdx++) { - if (availableSizes[resIdx * 2] == width && - availableSizes[resIdx * 2 + 1] == height) - break; - } - if (resIdx == availableSizeCount) { - ALOGE("%s: Format 0x%x does not support resolution %d, %d", __FUNCTION__, - format, width, height); - return BAD_VALUE; - } - - switch (format) { - case HAL_PIXEL_FORMAT_RAW16: - if (mRawStreamCount >= kMaxRawStreamCount) { - ALOGE("%s: Cannot allocate another raw stream (%d already allocated)", - __FUNCTION__, mRawStreamCount); - return INVALID_OPERATION; - } - mRawStreamCount++; - break; - case HAL_PIXEL_FORMAT_BLOB: - if (mJpegStreamCount >= kMaxJpegStreamCount) { - ALOGE("%s: Cannot allocate another JPEG stream (%d already allocated)", - __FUNCTION__, mJpegStreamCount); - return INVALID_OPERATION; - } - mJpegStreamCount++; - break; - default: - if (mProcessedStreamCount >= kMaxProcessedStreamCount) { - ALOGE( - "%s: Cannot allocate another processed stream (%d already " - "allocated)", - __FUNCTION__, mProcessedStreamCount); - return INVALID_OPERATION; - } - mProcessedStreamCount++; - } - - Stream newStream; - newStream.ops = stream_ops; - newStream.width = width; - newStream.height = height; - newStream.format = format; - // TODO: Query stride from gralloc - newStream.stride = width; - - mStreams.add(mNextStreamId, newStream); - - *stream_id = mNextStreamId; - if (format_actual) *format_actual = format; - *usage = GRALLOC_USAGE_HW_CAMERA_WRITE; - *max_buffers = kMaxBufferCount; - - ALOGV("Stream allocated: %d, %d x %d, 0x%x. U: %x, B: %d", *stream_id, width, - height, format, *usage, *max_buffers); - - mNextStreamId++; - return NO_ERROR; -} - -int EmulatedFakeCamera2::registerStreamBuffers(uint32_t stream_id, - int num_buffers, - buffer_handle_t * /*buffers*/) { - Mutex::Autolock l(mMutex); - - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - - ALOGV("%s: Stream %d registering %d buffers", __FUNCTION__, stream_id, - num_buffers); - // Need to find out what the final concrete pixel format for our stream is - // Assumes that all buffers have the same format. - if (num_buffers < 1) { - ALOGE("%s: Stream %d only has %d buffers!", __FUNCTION__, stream_id, - num_buffers); - return BAD_VALUE; - } - - ssize_t streamIndex = mStreams.indexOfKey(stream_id); - if (streamIndex < 0) { - ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id); - return BAD_VALUE; - } - - Stream &stream = mStreams.editValueAt(streamIndex); - - int finalFormat = stream.format; - - if (finalFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { - finalFormat = HAL_PIXEL_FORMAT_RGBA_8888; - } - - ALOGV("%s: Stream %d format set to %x, previously %x", __FUNCTION__, - stream_id, finalFormat, stream.format); - - stream.format = finalFormat; - - return NO_ERROR; -} - -int EmulatedFakeCamera2::releaseStream(uint32_t stream_id) { - Mutex::Autolock l(mMutex); - - ssize_t streamIndex = mStreams.indexOfKey(stream_id); - if (streamIndex < 0) { - ALOGE("%s: Unknown stream id %d!", __FUNCTION__, stream_id); - return BAD_VALUE; - } - - if (isStreamInUse(stream_id)) { - ALOGE("%s: Cannot release stream %d; in use!", __FUNCTION__, stream_id); - return BAD_VALUE; - } - - switch (mStreams.valueAt(streamIndex).format) { - case HAL_PIXEL_FORMAT_RAW16: - mRawStreamCount--; - break; - case HAL_PIXEL_FORMAT_BLOB: - mJpegStreamCount--; - break; - default: - mProcessedStreamCount--; - break; - } - - mStreams.removeItemsAt(streamIndex); - - return NO_ERROR; -} - -int EmulatedFakeCamera2::allocateReprocessStreamFromStream( - uint32_t output_stream_id, const camera2_stream_in_ops_t *stream_ops, - uint32_t *stream_id) { - Mutex::Autolock l(mMutex); - - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - - ssize_t baseStreamIndex = mStreams.indexOfKey(output_stream_id); - if (baseStreamIndex < 0) { - ALOGE("%s: Unknown output stream id %d!", __FUNCTION__, output_stream_id); - return BAD_VALUE; - } - - const Stream &baseStream = mStreams[baseStreamIndex]; - - // We'll reprocess anything we produced - - if (mReprocessStreamCount >= kMaxReprocessStreamCount) { - ALOGE("%s: Cannot allocate another reprocess stream (%d already allocated)", - __FUNCTION__, mReprocessStreamCount); - return INVALID_OPERATION; - } - mReprocessStreamCount++; - - ReprocessStream newStream; - newStream.ops = stream_ops; - newStream.width = baseStream.width; - newStream.height = baseStream.height; - newStream.format = baseStream.format; - newStream.stride = baseStream.stride; - newStream.sourceStreamId = output_stream_id; - - *stream_id = mNextReprocessStreamId; - mReprocessStreams.add(mNextReprocessStreamId, newStream); - - ALOGV("Reprocess stream allocated: %d: %d, %d, 0x%x. Parent stream: %d", - *stream_id, newStream.width, newStream.height, newStream.format, - output_stream_id); - - mNextReprocessStreamId++; - return NO_ERROR; -} - -int EmulatedFakeCamera2::releaseReprocessStream(uint32_t stream_id) { - Mutex::Autolock l(mMutex); - - ssize_t streamIndex = mReprocessStreams.indexOfKey(stream_id); - if (streamIndex < 0) { - ALOGE("%s: Unknown reprocess stream id %d!", __FUNCTION__, stream_id); - return BAD_VALUE; - } - - if (isReprocessStreamInUse(stream_id)) { - ALOGE("%s: Cannot release reprocessing stream %d; in use!", __FUNCTION__, - stream_id); - return BAD_VALUE; - } - - mReprocessStreamCount--; - mReprocessStreams.removeItemsAt(streamIndex); - - return NO_ERROR; -} - -int EmulatedFakeCamera2::triggerAction(uint32_t trigger_id, int32_t ext1, - int32_t ext2) { - Mutex::Autolock l(mMutex); - - if (trigger_id == CAMERA2_EXT_TRIGGER_TESTING_DISCONNECT) { - ALOGI("%s: Disconnect trigger - camera must be closed", __FUNCTION__); - mStatusPresent = false; - - EmulatedCameraFactory::Instance().onStatusChanged( - mCameraID, CAMERA_DEVICE_STATUS_NOT_PRESENT); - } - - if (!mStatusPresent) { - ALOGW("%s: Camera was physically disconnected", __FUNCTION__); - return ERROR_CAMERA_NOT_PRESENT; - } - - return mControlThread->triggerAction(trigger_id, ext1, ext2); -} - -/** Shutdown and debug methods */ - -int EmulatedFakeCamera2::dump(int fd) { - String8 result; - - result.appendFormat(" Camera HAL device: EmulatedFakeCamera2\n"); - result.appendFormat(" Streams:\n"); - for (size_t i = 0; i < mStreams.size(); i++) { - int id = mStreams.keyAt(i); - const Stream &s = mStreams.valueAt(i); - result.appendFormat(" Stream %d: %d x %d, format 0x%x, stride %d\n", - id, s.width, s.height, s.format, s.stride); - } - - write(fd, result.string(), result.size()); - - return NO_ERROR; -} - -void EmulatedFakeCamera2::signalError() { - // TODO: Let parent know so we can shut down cleanly - ALOGE("Worker thread is signaling a serious error"); -} - -/** Pipeline control worker thread methods */ - -EmulatedFakeCamera2::ConfigureThread::ConfigureThread( - EmulatedFakeCamera2 *parent) - : Thread(false), mParent(parent), mRequestCount(0), mNextBuffers(NULL) { - mRunning = false; -} - -EmulatedFakeCamera2::ConfigureThread::~ConfigureThread() {} - -status_t EmulatedFakeCamera2::ConfigureThread::readyToRun() { - Mutex::Autolock lock(mInputMutex); - - ALOGV("Starting up ConfigureThread"); - mRequest = NULL; - mActive = false; - mRunning = true; - - mInputSignal.signal(); - return NO_ERROR; -} - -status_t EmulatedFakeCamera2::ConfigureThread::waitUntilRunning() { - Mutex::Autolock lock(mInputMutex); - if (!mRunning) { - ALOGV("Waiting for configure thread to start"); - mInputSignal.wait(mInputMutex); - } - return OK; -} - -status_t EmulatedFakeCamera2::ConfigureThread::newRequestAvailable() { - waitUntilRunning(); - - Mutex::Autolock lock(mInputMutex); - - mActive = true; - mInputSignal.signal(); - - return OK; -} - -bool EmulatedFakeCamera2::ConfigureThread::isStreamInUse(uint32_t id) { - Mutex::Autolock lock(mInternalsMutex); - - if (mNextBuffers == NULL) return false; - for (size_t i = 0; i < mNextBuffers->size(); i++) { - if ((*mNextBuffers)[i].streamId == (int)id) return true; - } - return false; -} - -int EmulatedFakeCamera2::ConfigureThread::getInProgressCount() { - Mutex::Autolock lock(mInputMutex); - return mRequestCount; -} - -bool EmulatedFakeCamera2::ConfigureThread::threadLoop() { - status_t res; - - // Check if we're currently processing or just waiting - { - Mutex::Autolock lock(mInputMutex); - if (!mActive) { - // Inactive, keep waiting until we've been signaled - status_t res; - res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop); - if (res != NO_ERROR && res != TIMED_OUT) { - ALOGE("%s: Error waiting for input requests: %d", __FUNCTION__, res); - return false; - } - if (!mActive) return true; - ALOGV("New request available"); - } - // Active - } - - if (mRequest == NULL) { - Mutex::Autolock il(mInternalsMutex); - - ALOGV("Configure: Getting next request"); - res = mParent->mRequestQueueSrc->dequeue_request(mParent->mRequestQueueSrc, - &mRequest); - if (res != NO_ERROR) { - ALOGE("%s: Error dequeuing next request: %d", __FUNCTION__, res); - mParent->signalError(); - return false; - } - if (mRequest == NULL) { - ALOGV("Configure: Request queue empty, going inactive"); - // No requests available, go into inactive mode - Mutex::Autolock lock(mInputMutex); - mActive = false; - return true; - } else { - Mutex::Autolock lock(mInputMutex); - mRequestCount++; - } - - camera_metadata_entry_t type; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_TYPE, &type); - if (res != NO_ERROR) { - ALOGE("%s: error reading request type", __FUNCTION__); - mParent->signalError(); - return false; - } - bool success = false; - ; - switch (type.data.u8[0]) { - case ANDROID_REQUEST_TYPE_CAPTURE: - success = setupCapture(); - break; - case ANDROID_REQUEST_TYPE_REPROCESS: - success = setupReprocess(); - break; - default: - ALOGE("%s: Unexpected request type %d", __FUNCTION__, type.data.u8[0]); - mParent->signalError(); - break; - } - if (!success) return false; - } - - if (mWaitingForReadout) { - bool readoutDone; - readoutDone = mParent->mReadoutThread->waitForReady(kWaitPerLoop); - if (!readoutDone) return true; - - if (mNextNeedsJpeg) { - ALOGV("Configure: Waiting for JPEG compressor"); - } else { - ALOGV("Configure: Waiting for sensor"); - } - mWaitingForReadout = false; - } - - if (mNextNeedsJpeg) { - bool jpegDone; - jpegDone = mParent->mJpegCompressor->waitForDone(kWaitPerLoop); - if (!jpegDone) return true; - - ALOGV("Configure: Waiting for sensor"); - mNextNeedsJpeg = false; - } - - if (mNextIsCapture) { - return configureNextCapture(); - } else { - return configureNextReprocess(); - } -} - -bool EmulatedFakeCamera2::ConfigureThread::setupCapture() { - status_t res; - - mNextIsCapture = true; - // Get necessary parameters for sensor config - mParent->mControlThread->processRequest(mRequest); - - camera_metadata_entry_t streams; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS, - &streams); - if (res != NO_ERROR) { - ALOGE("%s: error reading output stream tag", __FUNCTION__); - mParent->signalError(); - return false; - } - - mNextBuffers = new Buffers; - mNextNeedsJpeg = false; - ALOGV("Configure: Setting up buffers for capture"); - for (size_t i = 0; i < streams.count; i++) { - int streamId = streams.data.i32[i]; - const Stream &s = mParent->getStreamInfo(streamId); - if (s.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { - ALOGE( - "%s: Stream %d does not have a concrete pixel format, but " - "is included in a request!", - __FUNCTION__, streamId); - mParent->signalError(); - return false; - } - StreamBuffer b; - b.streamId = streamId; // streams.data.u8[i]; - b.width = s.width; - b.height = s.height; - b.format = s.format; - b.stride = s.stride; - mNextBuffers->push_back(b); - ALOGV( - "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, " - "stride %d", - i, b.streamId, b.width, b.height, b.format, b.stride); - if (b.format == HAL_PIXEL_FORMAT_BLOB) { - mNextNeedsJpeg = true; - } - } - - camera_metadata_entry_t e; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e); - if (res != NO_ERROR) { - ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - mNextFrameNumber = *e.data.i32; - - res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_EXPOSURE_TIME, &e); - if (res != NO_ERROR) { - ALOGE("%s: error reading exposure time tag: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - mNextExposureTime = *e.data.i64; - - res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_FRAME_DURATION, &e); - if (res != NO_ERROR) { - ALOGE("%s: error reading frame duration tag", __FUNCTION__); - mParent->signalError(); - return false; - } - mNextFrameDuration = *e.data.i64; - - if (mNextFrameDuration < mNextExposureTime + Sensor::kMinVerticalBlank) { - mNextFrameDuration = mNextExposureTime + Sensor::kMinVerticalBlank; - } - res = find_camera_metadata_entry(mRequest, ANDROID_SENSOR_SENSITIVITY, &e); - if (res != NO_ERROR) { - ALOGE("%s: error reading sensitivity tag", __FUNCTION__); - mParent->signalError(); - return false; - } - mNextSensitivity = *e.data.i32; - - // Start waiting on readout thread - mWaitingForReadout = true; - ALOGV("Configure: Waiting for readout thread"); - - return true; -} - -bool EmulatedFakeCamera2::ConfigureThread::configureNextCapture() { - bool vsync = mParent->mSensor->waitForVSync(kWaitPerLoop); - if (!vsync) return true; - - Mutex::Autolock il(mInternalsMutex); - ALOGV("Configure: Configuring sensor for capture %d", mNextFrameNumber); - mParent->mSensor->setExposureTime(mNextExposureTime); - mParent->mSensor->setFrameDuration(mNextFrameDuration); - mParent->mSensor->setSensitivity(mNextSensitivity); - - getBuffers(); - - ALOGV("Configure: Done configure for capture %d", mNextFrameNumber); - mParent->mReadoutThread->setNextOperation(true, mRequest, mNextBuffers); - mParent->mSensor->setDestinationBuffers(mNextBuffers); - - mRequest = NULL; - mNextBuffers = NULL; - - Mutex::Autolock lock(mInputMutex); - mRequestCount--; - - return true; -} - -bool EmulatedFakeCamera2::ConfigureThread::setupReprocess() { - status_t res; - - mNextNeedsJpeg = true; - mNextIsCapture = false; - - camera_metadata_entry_t reprocessStreams; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_INPUT_STREAMS, - &reprocessStreams); - if (res != NO_ERROR) { - ALOGE("%s: error reading output stream tag", __FUNCTION__); - mParent->signalError(); - return false; - } - - mNextBuffers = new Buffers; - - ALOGV("Configure: Setting up input buffers for reprocess"); - for (size_t i = 0; i < reprocessStreams.count; i++) { - int streamId = reprocessStreams.data.i32[i]; - const ReprocessStream &s = mParent->getReprocessStreamInfo(streamId); - if (s.format != HAL_PIXEL_FORMAT_RGB_888) { - ALOGE("%s: Only ZSL reprocessing supported!", __FUNCTION__); - mParent->signalError(); - return false; - } - StreamBuffer b; - b.streamId = -streamId; - b.width = s.width; - b.height = s.height; - b.format = s.format; - b.stride = s.stride; - mNextBuffers->push_back(b); - } - - camera_metadata_entry_t streams; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_OUTPUT_STREAMS, - &streams); - if (res != NO_ERROR) { - ALOGE("%s: error reading output stream tag", __FUNCTION__); - mParent->signalError(); - return false; - } - - ALOGV("Configure: Setting up output buffers for reprocess"); - for (size_t i = 0; i < streams.count; i++) { - int streamId = streams.data.i32[i]; - const Stream &s = mParent->getStreamInfo(streamId); - if (s.format != HAL_PIXEL_FORMAT_BLOB) { - // TODO: Support reprocess to YUV - ALOGE("%s: Non-JPEG output stream %d for reprocess not supported", - __FUNCTION__, streamId); - mParent->signalError(); - return false; - } - StreamBuffer b; - b.streamId = streams.data.u8[i]; - b.width = s.width; - b.height = s.height; - b.format = s.format; - b.stride = s.stride; - mNextBuffers->push_back(b); - ALOGV( - "Configure: Buffer %zu: Stream %d, %d x %d, format 0x%x, " - "stride %d", - i, b.streamId, b.width, b.height, b.format, b.stride); - } - - camera_metadata_entry_t e; - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &e); - if (res != NO_ERROR) { - ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - mNextFrameNumber = *e.data.i32; - - return true; -} - -bool EmulatedFakeCamera2::ConfigureThread::configureNextReprocess() { - Mutex::Autolock il(mInternalsMutex); - - getBuffers(); - - ALOGV("Configure: Done configure for reprocess %d", mNextFrameNumber); - mParent->mReadoutThread->setNextOperation(false, mRequest, mNextBuffers); - - mRequest = NULL; - mNextBuffers = NULL; - - Mutex::Autolock lock(mInputMutex); - mRequestCount--; - - return true; -} - -bool EmulatedFakeCamera2::ConfigureThread::getBuffers() { - status_t res; - /** Get buffers to fill for this frame */ - for (size_t i = 0; i < mNextBuffers->size(); i++) { - StreamBuffer &b = mNextBuffers->editItemAt(i); - - if (b.streamId > 0) { - ALOGV("Configure: Dequeing buffer from stream %d", b.streamId); - Stream s = mParent->getStreamInfo(b.streamId); - res = s.ops->dequeue_buffer(s.ops, &(b.buffer)); - if (res != NO_ERROR || b.buffer == NULL) { - ALOGE("%s: Unable to dequeue buffer from stream %d: %s (%d)", - __FUNCTION__, b.streamId, strerror(-res), res); - mParent->signalError(); - return false; - } - - /* Lock the buffer from the perspective of the graphics mapper */ - res = GrallocModule::getInstance().lock( - *(b.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0, s.width, s.height, - (void **)&(b.img)); - - if (res != NO_ERROR) { - ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__, - strerror(-res), res); - s.ops->cancel_buffer(s.ops, b.buffer); - mParent->signalError(); - return false; - } - } else { - ALOGV("Configure: Acquiring buffer from reprocess stream %d", - -b.streamId); - ReprocessStream s = mParent->getReprocessStreamInfo(-b.streamId); - res = s.ops->acquire_buffer(s.ops, &(b.buffer)); - if (res != NO_ERROR || b.buffer == NULL) { - ALOGE( - "%s: Unable to acquire buffer from reprocess stream %d: " - "%s (%d)", - __FUNCTION__, -b.streamId, strerror(-res), res); - mParent->signalError(); - return false; - } - - /* Lock the buffer from the perspective of the graphics mapper */ - res = GrallocModule::getInstance().lock( - *(b.buffer), GRALLOC_USAGE_HW_CAMERA_READ, 0, 0, s.width, s.height, - (void **)&(b.img)); - if (res != NO_ERROR) { - ALOGE("%s: grbuffer_mapper.lock failure: %s (%d)", __FUNCTION__, - strerror(-res), res); - s.ops->release_buffer(s.ops, b.buffer); - mParent->signalError(); - return false; - } - } - } - return true; -} - -EmulatedFakeCamera2::ReadoutThread::ReadoutThread(EmulatedFakeCamera2 *parent) - : Thread(false), - mParent(parent), - mRunning(false), - mActive(false), - mRequestCount(0), - mRequest(NULL), - mBuffers(NULL) { - mInFlightQueue = new InFlightQueue[kInFlightQueueSize]; - mInFlightHead = 0; - mInFlightTail = 0; -} - -EmulatedFakeCamera2::ReadoutThread::~ReadoutThread() { - delete[] mInFlightQueue; -} - -status_t EmulatedFakeCamera2::ReadoutThread::readyToRun() { - Mutex::Autolock lock(mInputMutex); - ALOGV("Starting up ReadoutThread"); - mRunning = true; - mInputSignal.signal(); - return NO_ERROR; -} - -status_t EmulatedFakeCamera2::ReadoutThread::waitUntilRunning() { - Mutex::Autolock lock(mInputMutex); - if (!mRunning) { - ALOGV("Waiting for readout thread to start"); - mInputSignal.wait(mInputMutex); - } - return OK; -} - -bool EmulatedFakeCamera2::ReadoutThread::waitForReady(nsecs_t timeout) { - status_t res; - Mutex::Autolock lock(mInputMutex); - while (!readyForNextCapture()) { - res = mReadySignal.waitRelative(mInputMutex, timeout); - if (res == TIMED_OUT) return false; - if (res != OK) { - ALOGE("%s: Error waiting for ready: %s (%d)", __FUNCTION__, - strerror(-res), res); - return false; - } - } - return true; -} - -bool EmulatedFakeCamera2::ReadoutThread::readyForNextCapture() { - return (mInFlightTail + 1) % kInFlightQueueSize != mInFlightHead; -} - -void EmulatedFakeCamera2::ReadoutThread::setNextOperation( - bool isCapture, camera_metadata_t *request, Buffers *buffers) { - Mutex::Autolock lock(mInputMutex); - if (!readyForNextCapture()) { - ALOGE("In flight queue full, dropping captures"); - mParent->signalError(); - return; - } - mInFlightQueue[mInFlightTail].isCapture = isCapture; - mInFlightQueue[mInFlightTail].request = request; - mInFlightQueue[mInFlightTail].buffers = buffers; - mInFlightTail = (mInFlightTail + 1) % kInFlightQueueSize; - mRequestCount++; - - if (!mActive) { - mActive = true; - mInputSignal.signal(); - } -} - -bool EmulatedFakeCamera2::ReadoutThread::isStreamInUse(uint32_t id) { - // acquire in same order as threadLoop - Mutex::Autolock iLock(mInternalsMutex); - Mutex::Autolock lock(mInputMutex); - - size_t i = mInFlightHead; - while (i != mInFlightTail) { - for (size_t j = 0; j < mInFlightQueue[i].buffers->size(); j++) { - if ((*(mInFlightQueue[i].buffers))[j].streamId == (int)id) return true; - } - i = (i + 1) % kInFlightQueueSize; - } - - if (mBuffers != NULL) { - for (i = 0; i < mBuffers->size(); i++) { - if ((*mBuffers)[i].streamId == (int)id) return true; - } - } - - return false; -} - -int EmulatedFakeCamera2::ReadoutThread::getInProgressCount() { - Mutex::Autolock lock(mInputMutex); - - return mRequestCount; -} - -bool EmulatedFakeCamera2::ReadoutThread::threadLoop() { - static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms - status_t res; - int32_t frameNumber; - - // Check if we're currently processing or just waiting - { - Mutex::Autolock lock(mInputMutex); - if (!mActive) { - // Inactive, keep waiting until we've been signaled - res = mInputSignal.waitRelative(mInputMutex, kWaitPerLoop); - if (res != NO_ERROR && res != TIMED_OUT) { - ALOGE("%s: Error waiting for capture requests: %d", __FUNCTION__, res); - mParent->signalError(); - return false; - } - if (!mActive) return true; - } - // Active, see if we need a new request - if (mRequest == NULL) { - if (mInFlightHead == mInFlightTail) { - // Go inactive - ALOGV("Waiting for sensor data"); - mActive = false; - return true; - } else { - Mutex::Autolock iLock(mInternalsMutex); - mReadySignal.signal(); - mIsCapture = mInFlightQueue[mInFlightHead].isCapture; - mRequest = mInFlightQueue[mInFlightHead].request; - mBuffers = mInFlightQueue[mInFlightHead].buffers; - mInFlightQueue[mInFlightHead].request = NULL; - mInFlightQueue[mInFlightHead].buffers = NULL; - mInFlightHead = (mInFlightHead + 1) % kInFlightQueueSize; - ALOGV("Ready to read out request %p, %zu buffers", mRequest, - mBuffers->size()); - } - } - } - - // Active with request, wait on sensor to complete - - nsecs_t captureTime; - - if (mIsCapture) { - bool gotFrame; - gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime); - - if (!gotFrame) return true; - } - - Mutex::Autolock iLock(mInternalsMutex); - - camera_metadata_entry_t entry; - if (!mIsCapture) { - res = - find_camera_metadata_entry(mRequest, ANDROID_SENSOR_TIMESTAMP, &entry); - if (res != NO_ERROR) { - ALOGE("%s: error reading reprocessing timestamp: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - captureTime = entry.data.i64[0]; - } - - res = - find_camera_metadata_entry(mRequest, ANDROID_REQUEST_FRAME_COUNT, &entry); - if (res != NO_ERROR) { - ALOGE("%s: error reading frame count tag: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - frameNumber = *entry.data.i32; - - res = find_camera_metadata_entry(mRequest, ANDROID_REQUEST_METADATA_MODE, - &entry); - if (res != NO_ERROR) { - ALOGE("%s: error reading metadata mode tag: %s (%d)", __FUNCTION__, - strerror(-res), res); - mParent->signalError(); - return false; - } - - // Got sensor data and request, construct frame and send it out - ALOGV("Readout: Constructing metadata and frames for request %d", - frameNumber); - - if (*entry.data.u8 == ANDROID_REQUEST_METADATA_MODE_FULL) { - ALOGV("Readout: Metadata requested, constructing"); - - camera_metadata_t *frame = NULL; - - size_t frame_entries = get_camera_metadata_entry_count(mRequest); - size_t frame_data = get_camera_metadata_data_count(mRequest); - - // TODO: Dynamically calculate based on enabled statistics, etc - frame_entries += 10; - frame_data += 100; - - res = mParent->mFrameQueueDst->dequeue_frame( - mParent->mFrameQueueDst, frame_entries, frame_data, &frame); - - if (res != NO_ERROR || frame == NULL) { - ALOGE("%s: Unable to dequeue frame metadata buffer", __FUNCTION__); - mParent->signalError(); - return false; - } - - res = append_camera_metadata(frame, mRequest); - if (res != NO_ERROR) { - ALOGE("Unable to append request metadata"); - } - - if (mIsCapture) { - add_camera_metadata_entry(frame, ANDROID_SENSOR_TIMESTAMP, &captureTime, - 1); - - collectStatisticsMetadata(frame); - // TODO: Collect all final values used from sensor in addition to - // timestamp - } - - ALOGV("Readout: Enqueue frame %d", frameNumber); - mParent->mFrameQueueDst->enqueue_frame(mParent->mFrameQueueDst, frame); - } - ALOGV("Readout: Free request"); - res = mParent->mRequestQueueSrc->free_request(mParent->mRequestQueueSrc, - mRequest); - if (res != NO_ERROR) { - ALOGE("%s: Unable to return request buffer to queue: %d", __FUNCTION__, - res); - mParent->signalError(); - return false; - } - mRequest = NULL; - - int compressedBufferIndex = -1; - ALOGV("Readout: Processing %zu buffers", mBuffers->size()); - for (size_t i = 0; i < mBuffers->size(); i++) { - const StreamBuffer &b = (*mBuffers)[i]; - ALOGV("Readout: Buffer %zu: Stream %d, %d x %d, format 0x%x, stride %d", - i, b.streamId, b.width, b.height, b.format, b.stride); - if (b.streamId > 0) { - if (b.format == HAL_PIXEL_FORMAT_BLOB) { - // Assumes only one BLOB buffer type per capture - compressedBufferIndex = i; - } else { - ALOGV("Readout: Sending image buffer %zu (%p) to output stream %d", - i, (void *)*(b.buffer), b.streamId); - GrallocModule::getInstance().unlock(*(b.buffer)); - const Stream &s = mParent->getStreamInfo(b.streamId); - res = s.ops->enqueue_buffer(s.ops, captureTime, b.buffer); - if (res != OK) { - ALOGE("Error enqueuing image buffer %p: %s (%d)", b.buffer, - strerror(-res), res); - mParent->signalError(); - } - } - } - } - - if (compressedBufferIndex == -1) { - delete mBuffers; - } else { - ALOGV("Readout: Starting JPEG compression for buffer %d, stream %d", - compressedBufferIndex, (*mBuffers)[compressedBufferIndex].streamId); - mJpegTimestamp = captureTime; - // Takes ownership of mBuffers - mParent->mJpegCompressor->start(mBuffers, this); - } - mBuffers = NULL; - - Mutex::Autolock l(mInputMutex); - mRequestCount--; - ALOGV("Readout: Done with request %d", frameNumber); - return true; -} - -void EmulatedFakeCamera2::ReadoutThread::onJpegDone( - const StreamBuffer &jpegBuffer, bool success) { - if (!success) { - ALOGE("%s: Error queueing compressed image buffer %p", __FUNCTION__, - jpegBuffer.buffer); - mParent->signalError(); - return; - } - - // Write to JPEG output stream - ALOGV("%s: Compression complete, pushing to stream %d", __FUNCTION__, - jpegBuffer.streamId); - - GrallocModule::getInstance().unlock(*(jpegBuffer.buffer)); - const Stream &s = mParent->getStreamInfo(jpegBuffer.streamId); - s.ops->enqueue_buffer(s.ops, mJpegTimestamp, jpegBuffer.buffer); -} - -void EmulatedFakeCamera2::ReadoutThread::onJpegInputDone( - const StreamBuffer &inputBuffer) { - status_t res; - GrallocModule::getInstance().unlock(*(inputBuffer.buffer)); - const ReprocessStream &s = - mParent->getReprocessStreamInfo(-inputBuffer.streamId); - res = s.ops->release_buffer(s.ops, inputBuffer.buffer); - if (res != OK) { - ALOGE("Error releasing reprocess buffer %p: %s (%d)", inputBuffer.buffer, - strerror(-res), res); - mParent->signalError(); - } -} - -status_t EmulatedFakeCamera2::ReadoutThread::collectStatisticsMetadata( - camera_metadata_t *frame) { - // Completely fake face rectangles, don't correspond to real faces in scene - ALOGV("Readout: Collecting statistics metadata"); - - status_t res; - camera_metadata_entry_t entry; - res = find_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_DETECT_MODE, - &entry); - if (res != OK) { - ALOGE("%s: Unable to find face detect mode!", __FUNCTION__); - return BAD_VALUE; - } - - if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) return OK; - - // The coordinate system for the face regions is the raw sensor pixel - // coordinates. Here, we map from the scene coordinates (0-19 in both axis) - // to raw pixels, for the scene defined in fake-pipeline2/Scene.cpp. We - // approximately place two faces on top of the windows of the house. No - // actual faces exist there, but might one day. Note that this doesn't - // account for the offsets used to account for aspect ratio differences, so - // the rectangles don't line up quite right. - const size_t numFaces = 2; - int32_t rects[numFaces * 4] = { - static_cast<int32_t>(mParent->mSensorWidth * 10 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 15 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 12 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 17 / 20), - - static_cast<int32_t>(mParent->mSensorWidth * 16 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 15 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 18 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 17 / 20)}; - // To simulate some kind of real detection going on, we jitter the rectangles - // on each frame by a few pixels in each dimension. - for (size_t i = 0; i < numFaces * 4; i++) { - rects[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 6 - 3); - } - // The confidence scores (0-100) are similarly jittered. - uint8_t scores[numFaces] = {85, 95}; - for (size_t i = 0; i < numFaces; i++) { - scores[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 10 - 5); - } - - res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_RECTANGLES, - rects, numFaces * 4); - if (res != OK) { - ALOGE("%s: Unable to add face rectangles!", __FUNCTION__); - return BAD_VALUE; - } - - res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_SCORES, scores, - numFaces); - if (res != OK) { - ALOGE("%s: Unable to add face scores!", __FUNCTION__); - return BAD_VALUE; - } - - if (entry.data.u8[0] == ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE) return OK; - - // Advanced face detection options - add eye/mouth coordinates. The - // coordinates in order are (leftEyeX, leftEyeY, rightEyeX, rightEyeY, - // mouthX, mouthY). The mapping is the same as the face rectangles. - int32_t features[numFaces * 6] = { - static_cast<int32_t>(mParent->mSensorWidth * 10.5 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 11.5 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 11 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20), - - static_cast<int32_t>(mParent->mSensorWidth * 16.5 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 17.5 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16 / 20), - static_cast<int32_t>(mParent->mSensorWidth * 17 / 20), - static_cast<int32_t>(mParent->mSensorHeight * 16.5 / 20), - }; - // Jitter these a bit less than the rects - for (size_t i = 0; i < numFaces * 6; i++) { - features[i] += (int32_t)(((float)rand() / (float)RAND_MAX) * 4 - 2); - } - // These are unique IDs that are used to identify each face while it's - // visible to the detector (if a face went away and came back, it'd get a - // new ID). - int32_t ids[numFaces] = {100, 200}; - - res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_LANDMARKS, - features, numFaces * 6); - if (res != OK) { - ALOGE("%s: Unable to add face landmarks!", __FUNCTION__); - return BAD_VALUE; - } - - res = add_camera_metadata_entry(frame, ANDROID_STATISTICS_FACE_IDS, ids, - numFaces); - if (res != OK) { - ALOGE("%s: Unable to add face scores!", __FUNCTION__); - return BAD_VALUE; - } - - return OK; -} - -EmulatedFakeCamera2::ControlThread::ControlThread(EmulatedFakeCamera2 *parent) - : Thread(false), mParent(parent) { - mRunning = false; -} - -EmulatedFakeCamera2::ControlThread::~ControlThread() {} - -status_t EmulatedFakeCamera2::ControlThread::readyToRun() { - Mutex::Autolock lock(mInputMutex); - - ALOGV("Starting up ControlThread"); - mRunning = true; - mStartAf = false; - mCancelAf = false; - mStartPrecapture = false; - - mControlMode = ANDROID_CONTROL_MODE_AUTO; - - mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; - mSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; - - mAfMode = ANDROID_CONTROL_AF_MODE_AUTO; - mAfModeChange = false; - - mAeMode = ANDROID_CONTROL_AE_MODE_ON; - mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO; - - mAfTriggerId = 0; - mPrecaptureTriggerId = 0; - - mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; - - mExposureTime = kNormalExposureTime; - - mInputSignal.signal(); - return NO_ERROR; -} - -status_t EmulatedFakeCamera2::ControlThread::waitUntilRunning() { - Mutex::Autolock lock(mInputMutex); - if (!mRunning) { - ALOGV("Waiting for control thread to start"); - mInputSignal.wait(mInputMutex); - } - return OK; -} - -// Override android.control.* fields with 3A values before sending request to -// sensor -status_t EmulatedFakeCamera2::ControlThread::processRequest( - camera_metadata_t *request) { - Mutex::Autolock lock(mInputMutex); - // TODO: Add handling for all android.control.* fields here - camera_metadata_entry_t mode; - status_t res; - -#define READ_IF_OK(res, what, def) (((res) == OK) ? (what) : (uint8_t)(def)) - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_MODE, &mode); - mControlMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_MODE_OFF); - - // disable all 3A - if (mControlMode == ANDROID_CONTROL_MODE_OFF) { - mEffectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; - mSceneMode = ANDROID_CONTROL_SCENE_MODE_DISABLED; - mAfMode = ANDROID_CONTROL_AF_MODE_OFF; - mAeLock = ANDROID_CONTROL_AE_LOCK_ON; - mAeMode = ANDROID_CONTROL_AE_MODE_OFF; - mAfModeChange = true; - mStartAf = false; - mCancelAf = true; - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - mAwbMode = ANDROID_CONTROL_AWB_MODE_OFF; - return res; - } - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_EFFECT_MODE, &mode); - mEffectMode = - READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_EFFECT_MODE_OFF); - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_SCENE_MODE, &mode); - mSceneMode = - READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_SCENE_MODE_DISABLED); - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_AF_MODE, &mode); - if (mAfMode != mode.data.u8[0]) { - ALOGV("AF new mode: %d, old mode %d", mode.data.u8[0], mAfMode); - mAfMode = mode.data.u8[0]; - mAfModeChange = true; - mStartAf = false; - mCancelAf = false; - } - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_MODE, &mode); - mAeMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_MODE_OFF); - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_AE_LOCK, &mode); - uint8_t aeLockVal = - READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AE_LOCK_ON); - bool aeLock = (aeLockVal == ANDROID_CONTROL_AE_LOCK_ON); - if (mAeLock && !aeLock) { - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - } - mAeLock = aeLock; - - res = find_camera_metadata_entry(request, ANDROID_CONTROL_AWB_MODE, &mode); - mAwbMode = READ_IF_OK(res, mode.data.u8[0], ANDROID_CONTROL_AWB_MODE_OFF); - - // TODO: Override more control fields - - if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) { - camera_metadata_entry_t exposureTime; - res = find_camera_metadata_entry(request, ANDROID_SENSOR_EXPOSURE_TIME, - &exposureTime); - if (res == OK) { - exposureTime.data.i64[0] = mExposureTime; - } - } - -#undef READ_IF_OK - - return OK; -} - -status_t EmulatedFakeCamera2::ControlThread::triggerAction(uint32_t msgType, - int32_t ext1, - int32_t ext2) { - ALOGV("%s: Triggering %d (%d, %d)", __FUNCTION__, msgType, ext1, ext2); - Mutex::Autolock lock(mInputMutex); - switch (msgType) { - case CAMERA2_TRIGGER_AUTOFOCUS: - mAfTriggerId = ext1; - mStartAf = true; - mCancelAf = false; - break; - case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS: - mAfTriggerId = ext1; - mStartAf = false; - mCancelAf = true; - break; - case CAMERA2_TRIGGER_PRECAPTURE_METERING: - mPrecaptureTriggerId = ext1; - mStartPrecapture = true; - break; - default: - ALOGE("%s: Unknown action triggered: %d (arguments %d %d)", __FUNCTION__, - msgType, ext1, ext2); - return BAD_VALUE; - } - return OK; -} - -const nsecs_t EmulatedFakeCamera2::ControlThread::kControlCycleDelay = - 100 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAfDuration = 500 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAfDuration = 900 * MSEC; -const float EmulatedFakeCamera2::ControlThread::kAfSuccessRate = 0.9; -// Once every 5 seconds -const float EmulatedFakeCamera2::ControlThread::kContinuousAfStartRate = - kControlCycleDelay / 5.0 * SEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAeDuration = 500 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAeDuration = 2 * SEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMinPrecaptureAeDuration = - 100 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxPrecaptureAeDuration = - 400 * MSEC; -// Once every 3 seconds -const float EmulatedFakeCamera2::ControlThread::kAeScanStartRate = - kControlCycleDelay / 3000000000.0; - -const nsecs_t EmulatedFakeCamera2::ControlThread::kNormalExposureTime = - 10 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kExposureJump = 2 * MSEC; -const nsecs_t EmulatedFakeCamera2::ControlThread::kMinExposureTime = 1 * MSEC; - -bool EmulatedFakeCamera2::ControlThread::threadLoop() { - bool afModeChange = false; - bool afTriggered = false; - bool afCancelled = false; - uint8_t afState; - uint8_t afMode; - int32_t afTriggerId; - bool precaptureTriggered = false; - uint8_t aeState; - uint8_t aeMode; - bool aeLock; - int32_t precaptureTriggerId; - nsecs_t nextSleep = kControlCycleDelay; - - { - Mutex::Autolock lock(mInputMutex); - if (mStartAf) { - ALOGD("Starting AF trigger processing"); - afTriggered = true; - mStartAf = false; - } else if (mCancelAf) { - ALOGD("Starting cancel AF trigger processing"); - afCancelled = true; - mCancelAf = false; - } - afState = mAfState; - afMode = mAfMode; - afModeChange = mAfModeChange; - mAfModeChange = false; - - afTriggerId = mAfTriggerId; - - if (mStartPrecapture) { - ALOGD("Starting precapture trigger processing"); - precaptureTriggered = true; - mStartPrecapture = false; - } - aeState = mAeState; - aeMode = mAeMode; - aeLock = mAeLock; - precaptureTriggerId = mPrecaptureTriggerId; - } - - if (afCancelled || afModeChange) { - ALOGV("Resetting AF state due to cancel/mode change"); - afState = ANDROID_CONTROL_AF_STATE_INACTIVE; - updateAfState(afState, afTriggerId); - mAfScanDuration = 0; - mLockAfterPassiveScan = false; - } - - if (afTriggered) { - afState = processAfTrigger(afMode, afState); - } - - afState = maybeStartAfScan(afMode, afState); - afState = updateAfScan(afMode, afState, &nextSleep); - updateAfState(afState, afTriggerId); - - if (precaptureTriggered) { - aeState = processPrecaptureTrigger(aeMode, aeState); - } - - aeState = maybeStartAeScan(aeMode, aeLock, aeState); - aeState = updateAeScan(aeMode, aeLock, aeState, &nextSleep); - updateAeState(aeState, precaptureTriggerId); - - int ret; - timespec t; - t.tv_sec = 0; - t.tv_nsec = nextSleep; - do { - ret = nanosleep(&t, &t); - } while (ret != 0); - - if (mAfScanDuration > 0) { - mAfScanDuration -= nextSleep; - } - if (mAeScanDuration > 0) { - mAeScanDuration -= nextSleep; - } - - return true; -} - -int EmulatedFakeCamera2::ControlThread::processAfTrigger(uint8_t afMode, - uint8_t afState) { - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_OFF: - case ANDROID_CONTROL_AF_MODE_EDOF: - // Do nothing - break; - case ANDROID_CONTROL_AF_MODE_MACRO: - case ANDROID_CONTROL_AF_MODE_AUTO: - switch (afState) { - case ANDROID_CONTROL_AF_STATE_INACTIVE: - case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: - case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: - // Start new focusing cycle - mAfScanDuration = - ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) + - kMinAfDuration; - afState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; - ALOGV("%s: AF scan start, duration %" PRId64 " ms", __FUNCTION__, - mAfScanDuration / 1000000); - break; - case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN: - // Ignore new request, already scanning - break; - default: - ALOGE("Unexpected AF state in AUTO/MACRO AF mode: %d", afState); - } - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - switch (afState) { - // Picture mode waits for passive scan to complete - case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN: - mLockAfterPassiveScan = true; - break; - case ANDROID_CONTROL_AF_STATE_INACTIVE: - afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - break; - case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED: - afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - break; - case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: - case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: - // Must cancel to get out of these states - break; - default: - ALOGE("Unexpected AF state in CONTINUOUS_PICTURE AF mode: %d", - afState); - } - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - switch (afState) { - // Video mode does not wait for passive scan to complete - case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN: - case ANDROID_CONTROL_AF_STATE_INACTIVE: - afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - break; - case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED: - afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - break; - case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: - case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: - // Must cancel to get out of these states - break; - default: - ALOGE("Unexpected AF state in CONTINUOUS_VIDEO AF mode: %d", afState); - } - break; - default: - break; - } - return afState; -} - -int EmulatedFakeCamera2::ControlThread::maybeStartAfScan(uint8_t afMode, - uint8_t afState) { - if ((afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO || - afMode == ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE) && - (afState == ANDROID_CONTROL_AF_STATE_INACTIVE || - afState == ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED)) { - bool startScan = ((double)rand() / RAND_MAX) < kContinuousAfStartRate; - if (startScan) { - // Start new passive focusing cycle - mAfScanDuration = - ((double)rand() / RAND_MAX) * (kMaxAfDuration - kMinAfDuration) + - kMinAfDuration; - afState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; - ALOGV("%s: AF passive scan start, duration %" PRId64 " ms", __FUNCTION__, - mAfScanDuration / 1000000); - } - } - return afState; -} - -int EmulatedFakeCamera2::ControlThread::updateAfScan(uint8_t afMode, - uint8_t afState, - nsecs_t *maxSleep) { - if (!(afState == ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN || - afState == ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN)) { - return afState; - } - - if (mAfScanDuration <= 0) { - ALOGV("%s: AF scan done", __FUNCTION__); - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_MACRO: - case ANDROID_CONTROL_AF_MODE_AUTO: { - bool success = ((double)rand() / RAND_MAX) < kAfSuccessRate; - if (success) { - afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - } else { - afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - } - break; - } - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - if (mLockAfterPassiveScan) { - afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - mLockAfterPassiveScan = false; - } else { - afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; - } - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; - break; - default: - ALOGE("Unexpected AF mode in scan state"); - } - } else { - if (mAfScanDuration <= *maxSleep) { - *maxSleep = mAfScanDuration; - } - } - return afState; -} - -void EmulatedFakeCamera2::ControlThread::updateAfState(uint8_t newState, - int32_t triggerId) { - Mutex::Autolock lock(mInputMutex); - if (mAfState != newState) { - ALOGV("%s: Autofocus state now %d, id %d", __FUNCTION__, newState, - triggerId); - mAfState = newState; - mParent->sendNotification(CAMERA2_MSG_AUTOFOCUS, newState, triggerId, 0); - } -} - -int EmulatedFakeCamera2::ControlThread::processPrecaptureTrigger( - uint8_t aeMode, uint8_t aeState) { - switch (aeMode) { - case ANDROID_CONTROL_AE_MODE_OFF: - // Don't do anything for these - return aeState; - case ANDROID_CONTROL_AE_MODE_ON: - case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH: - case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH: - case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: - // Trigger a precapture cycle - aeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE; - mAeScanDuration = - ((double)rand() / RAND_MAX) * - (kMaxPrecaptureAeDuration - kMinPrecaptureAeDuration) + - kMinPrecaptureAeDuration; - ALOGD("%s: AE precapture scan start, duration %" PRId64 " ms", - __FUNCTION__, mAeScanDuration / 1000000); - } - return aeState; -} - -int EmulatedFakeCamera2::ControlThread::maybeStartAeScan(uint8_t aeMode, - bool aeLocked, - uint8_t aeState) { - if (aeLocked) return aeState; - switch (aeMode) { - case ANDROID_CONTROL_AE_MODE_OFF: - break; - case ANDROID_CONTROL_AE_MODE_ON: - case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH: - case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH: - case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: { - if (aeState != ANDROID_CONTROL_AE_STATE_INACTIVE && - aeState != ANDROID_CONTROL_AE_STATE_CONVERGED) - break; - - bool startScan = ((double)rand() / RAND_MAX) < kAeScanStartRate; - if (startScan) { - mAeScanDuration = - ((double)rand() / RAND_MAX) * (kMaxAeDuration - kMinAeDuration) + - kMinAeDuration; - aeState = ANDROID_CONTROL_AE_STATE_SEARCHING; - ALOGV("%s: AE scan start, duration %" PRId64 " ms", __FUNCTION__, - mAeScanDuration / 1000000); - } - } - } - - return aeState; -} - -int EmulatedFakeCamera2::ControlThread::updateAeScan(uint8_t /*aeMode*/, - bool aeLock, - uint8_t aeState, - nsecs_t *maxSleep) { - if (aeLock && aeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { - mAeScanDuration = 0; - aeState = ANDROID_CONTROL_AE_STATE_LOCKED; - } else if ((aeState == ANDROID_CONTROL_AE_STATE_SEARCHING) || - (aeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE)) { - if (mAeScanDuration <= 0) { - ALOGV("%s: AE scan done", __FUNCTION__); - aeState = aeLock ? ANDROID_CONTROL_AE_STATE_LOCKED - : ANDROID_CONTROL_AE_STATE_CONVERGED; - - Mutex::Autolock lock(mInputMutex); - mExposureTime = kNormalExposureTime; - } else { - if (mAeScanDuration <= *maxSleep) { - *maxSleep = mAeScanDuration; - } - - int64_t exposureDelta = - ((double)rand() / RAND_MAX) * 2 * kExposureJump - kExposureJump; - Mutex::Autolock lock(mInputMutex); - mExposureTime = mExposureTime + exposureDelta; - if (mExposureTime < kMinExposureTime) mExposureTime = kMinExposureTime; - } - } - - return aeState; -} - -void EmulatedFakeCamera2::ControlThread::updateAeState(uint8_t newState, - int32_t triggerId) { - Mutex::Autolock lock(mInputMutex); - if (mAeState != newState) { - ALOGV("%s: Autoexposure state now %d, id %d", __FUNCTION__, newState, - triggerId); - mAeState = newState; - mParent->sendNotification(CAMERA2_MSG_AUTOEXPOSURE, newState, triggerId, 0); - } -} - -/** Private methods */ - -status_t EmulatedFakeCamera2::constructStaticInfo(camera_metadata_t **info, - bool sizeRequest) const { - size_t entryCount = 0; - size_t dataCount = 0; - status_t ret; - -#define ADD_OR_SIZE(tag, data, count) \ - if ((ret = addOrSize(*info, sizeRequest, &entryCount, &dataCount, tag, data, \ - count)) != OK) \ - return ret - - // android.lens - - // 5 cm min focus distance for back camera, infinity (fixed focus) for front - const float minFocusDistance = mFacingBack ? 1.0 / 0.05 : 0.0; - ADD_OR_SIZE(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &minFocusDistance, 1); - // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front - // const float hyperFocalDistance = mFacingBack ? 1.0 / 5.0 : 0.0; - ADD_OR_SIZE(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &minFocusDistance, 1); - - static const float focalLength = 3.30f; // mm - ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &focalLength, 1); - static const float aperture = 2.8f; - ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &aperture, 1); - static const float filterDensity = 0; - ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, &filterDensity, 1); - static const uint8_t availableOpticalStabilization = - ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; - ADD_OR_SIZE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, - &availableOpticalStabilization, 1); - - static const int32_t lensShadingMapSize[] = {1, 1}; - ADD_OR_SIZE(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize, - sizeof(lensShadingMapSize) / sizeof(int32_t)); - - int32_t lensFacing = - mFacingBack ? ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT; - ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1); - - // android.sensor - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, - Sensor::kExposureTimeRange, 2); - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, - &Sensor::kFrameDurationRange[1], 1); - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, Sensor::kSensitivityRange, - sizeof(Sensor::kSensitivityRange) / sizeof(int32_t)); - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, - &Sensor::kColorFilterArrangement, 1); - - static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm - ADD_OR_SIZE(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2); - - const int32_t pixelArray[] = {mSensorWidth, mSensorHeight}; - ADD_OR_SIZE(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArray, 2); - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, pixelArray, 2); - - ADD_OR_SIZE(ANDROID_SENSOR_INFO_WHITE_LEVEL, &Sensor::kMaxRawValue, 1); - - static const int32_t blackLevelPattern[4] = { - static_cast<int32_t>(Sensor::kBlackLevel), - static_cast<int32_t>(Sensor::kBlackLevel), - static_cast<int32_t>(Sensor::kBlackLevel), - static_cast<int32_t>(Sensor::kBlackLevel)}; - ADD_OR_SIZE(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, blackLevelPattern, - sizeof(blackLevelPattern) / sizeof(int32_t)); - - // TODO: sensor color calibration fields - - // android.flash - static const uint8_t flashAvailable = 0; - ADD_OR_SIZE(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1); - - static const int64_t flashChargeDuration = 0; - ADD_OR_SIZE(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1); - - // android.tonemap - - static const int32_t tonemapCurvePoints = 128; - ADD_OR_SIZE(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1); - - // android.scaler - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_FORMATS, kAvailableFormats, - sizeof(kAvailableFormats) / sizeof(uint32_t)); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_SIZES, &mAvailableRawSizes.front(), - mAvailableRawSizes.size()); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS, - kAvailableRawMinDurations, - sizeof(kAvailableRawMinDurations) / sizeof(uint64_t)); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, - &mAvailableProcessedSizes.front(), - mAvailableProcessedSizes.size()); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS, - kAvailableProcessedMinDurations, - sizeof(kAvailableProcessedMinDurations) / sizeof(uint64_t)); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, &mAvailableJpegSizes.front(), - mAvailableJpegSizes.size()); - - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS, - kAvailableJpegMinDurations, - sizeof(kAvailableJpegMinDurations) / sizeof(uint64_t)); - - static const float maxZoom = 10; - ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1); - - // android.jpeg - - static const int32_t jpegThumbnailSizes[] = {0, 0, 160, 120, 320, 240}; - ADD_OR_SIZE(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes, - sizeof(jpegThumbnailSizes) / sizeof(int32_t)); - - static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize; - ADD_OR_SIZE(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1); - - // android.stats - - static const uint8_t availableFaceDetectModes[] = { - ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, - ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE, - ANDROID_STATISTICS_FACE_DETECT_MODE_FULL}; - - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, - availableFaceDetectModes, sizeof(availableFaceDetectModes)); - - static const int32_t maxFaceCount = 8; - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1); - - static const int32_t histogramSize = 64; - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, &histogramSize, - 1); - - static const int32_t maxHistogramCount = 1000; - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT, &maxHistogramCount, - 1); - - static const int32_t sharpnessMapSize[2] = {64, 64}; - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, sharpnessMapSize, - sizeof(sharpnessMapSize) / sizeof(int32_t)); - - static const int32_t maxSharpnessMapValue = 1000; - ADD_OR_SIZE(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE, - &maxSharpnessMapValue, 1); - - // android.control - - static const uint8_t availableSceneModes[] = { - ANDROID_CONTROL_SCENE_MODE_DISABLED - }; - ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, availableSceneModes, - sizeof(availableSceneModes)); - - static const uint8_t availableEffects[] = {ANDROID_CONTROL_EFFECT_MODE_OFF}; - ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects, - sizeof(availableEffects)); - - static const int32_t max3aRegions[] = {/*AE*/ 0, /*AWB*/ 0, /*AF*/ 0}; - ADD_OR_SIZE(ANDROID_CONTROL_MAX_REGIONS, max3aRegions, - sizeof(max3aRegions) / sizeof(max3aRegions[0])); - - static const uint8_t availableAeModes[] = {ANDROID_CONTROL_AE_MODE_OFF, - ANDROID_CONTROL_AE_MODE_ON}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_MODES, availableAeModes, - sizeof(availableAeModes)); - - static const camera_metadata_rational exposureCompensationStep = {1, 3}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_STEP, &exposureCompensationStep, - 1); - - int32_t exposureCompensationRange[] = {-9, 9}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_COMPENSATION_RANGE, exposureCompensationRange, - sizeof(exposureCompensationRange) / sizeof(int32_t)); - - static const int32_t availableTargetFpsRanges[] = {5, 30, 15, 30}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, - availableTargetFpsRanges, - sizeof(availableTargetFpsRanges) / sizeof(int32_t)); - - static const uint8_t availableAntibandingModes[] = { - ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, - ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, - availableAntibandingModes, sizeof(availableAntibandingModes)); - - static const uint8_t availableAwbModes[] = { - ANDROID_CONTROL_AWB_MODE_OFF, - ANDROID_CONTROL_AWB_MODE_AUTO, - ANDROID_CONTROL_AWB_MODE_INCANDESCENT, - ANDROID_CONTROL_AWB_MODE_FLUORESCENT, - ANDROID_CONTROL_AWB_MODE_DAYLIGHT, - ANDROID_CONTROL_AWB_MODE_SHADE}; - ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes, - sizeof(availableAwbModes)); - - static const uint8_t availableAfModesBack[] = { - ANDROID_CONTROL_AF_MODE_OFF, ANDROID_CONTROL_AF_MODE_AUTO, - ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, - ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE}; - - static const uint8_t availableAfModesFront[] = {ANDROID_CONTROL_AF_MODE_OFF}; - - if (mFacingBack) { - ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesBack, - sizeof(availableAfModesBack)); - } else { - ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesFront, - sizeof(availableAfModesFront)); - } - - static const uint8_t availableVstabModes[] = { - ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF}; - ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, - availableVstabModes, sizeof(availableVstabModes)); - -#undef ADD_OR_SIZE - /** Allocate metadata if sizing */ - if (sizeRequest) { - ALOGV( - "Allocating %zu entries, %zu extra bytes for " - "static camera info", - entryCount, dataCount); - *info = allocate_camera_metadata(entryCount, dataCount); - if (*info == NULL) { - ALOGE( - "Unable to allocate camera static info" - "(%zu entries, %zu bytes extra data)", - entryCount, dataCount); - return NO_MEMORY; - } - } - return OK; -} - -status_t EmulatedFakeCamera2::constructDefaultRequest( - int request_template, camera_metadata_t **request, bool sizeRequest) const { - size_t entryCount = 0; - size_t dataCount = 0; - status_t ret; - -#define ADD_OR_SIZE(tag, data, count) \ - if ((ret = addOrSize(*request, sizeRequest, &entryCount, &dataCount, tag, \ - data, count)) != OK) \ - return ret - - /** android.request */ - - static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE; - ADD_OR_SIZE(ANDROID_REQUEST_TYPE, &requestType, 1); - - static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL; - ADD_OR_SIZE(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1); - - static const int32_t id = 0; - ADD_OR_SIZE(ANDROID_REQUEST_ID, &id, 1); - - static const int32_t frameCount = 0; - ADD_OR_SIZE(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1); - - // OUTPUT_STREAMS set by user - entryCount += 1; - dataCount += 5; // TODO: Should be maximum stream number - - /** android.lens */ - - static const float focusDistance = 0; - ADD_OR_SIZE(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1); - - static const float aperture = 2.8f; - ADD_OR_SIZE(ANDROID_LENS_APERTURE, &aperture, 1); - - static const float focalLength = 5.0f; - ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1); - - static const float filterDensity = 0; - ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1); - - static const uint8_t opticalStabilizationMode = - ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; - ADD_OR_SIZE(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, - &opticalStabilizationMode, 1); - - // FOCUS_RANGE set only in frame - - /** android.sensor */ - - static const int64_t exposureTime = 10 * MSEC; - ADD_OR_SIZE(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1); - - static const int64_t frameDuration = 33333333L; // 1/30 s - ADD_OR_SIZE(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1); - - static const int32_t sensitivity = 100; - ADD_OR_SIZE(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1); - - // TIMESTAMP set only in frame - - /** android.flash */ - - static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF; - ADD_OR_SIZE(ANDROID_FLASH_MODE, &flashMode, 1); - - static const uint8_t flashPower = 10; - ADD_OR_SIZE(ANDROID_FLASH_FIRING_POWER, &flashPower, 1); - - static const int64_t firingTime = 0; - ADD_OR_SIZE(ANDROID_FLASH_FIRING_TIME, &firingTime, 1); - - /** Processing block modes */ - uint8_t hotPixelMode = 0; - uint8_t demosaicMode = 0; - uint8_t noiseMode = 0; - uint8_t shadingMode = 0; - uint8_t colorMode = 0; - uint8_t tonemapMode = 0; - uint8_t edgeMode = 0; - switch (request_template) { - case CAMERA2_TEMPLATE_STILL_CAPTURE: - // fall-through - case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - // fall-through - case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; - demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY; - noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; - shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY; - colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY; - tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; - edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY; - break; - case CAMERA2_TEMPLATE_PREVIEW: - // fall-through - case CAMERA2_TEMPLATE_VIDEO_RECORD: - // fall-through - default: - hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST; - demosaicMode = ANDROID_DEMOSAIC_MODE_FAST; - noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST; - shadingMode = ANDROID_SHADING_MODE_FAST; - colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST; - tonemapMode = ANDROID_TONEMAP_MODE_FAST; - edgeMode = ANDROID_EDGE_MODE_FAST; - break; - } - ADD_OR_SIZE(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1); - ADD_OR_SIZE(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1); - ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1); - ADD_OR_SIZE(ANDROID_SHADING_MODE, &shadingMode, 1); - ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1); - ADD_OR_SIZE(ANDROID_TONEMAP_MODE, &tonemapMode, 1); - ADD_OR_SIZE(ANDROID_EDGE_MODE, &edgeMode, 1); - - /** android.noise */ - static const uint8_t noiseStrength = 5; - ADD_OR_SIZE(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1); - - /** android.color */ - static const float colorTransform[9] = {1.0f, 0.f, 0.f, 0.f, 1.f, - 0.f, 0.f, 0.f, 1.f}; - ADD_OR_SIZE(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9); - - /** android.tonemap */ - static const float tonemapCurve[4] = {0.f, 0.f, 1.f, 1.f}; - ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4); - ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4); - ADD_OR_SIZE(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4); - - /** android.edge */ - static const uint8_t edgeStrength = 5; - ADD_OR_SIZE(ANDROID_EDGE_STRENGTH, &edgeStrength, 1); - - /** android.scaler */ - static const int32_t cropRegion[3] = {0, 0, - static_cast<int32_t>(mSensorWidth)}; - ADD_OR_SIZE(ANDROID_SCALER_CROP_REGION, cropRegion, 3); - - /** android.jpeg */ - static const int32_t jpegQuality = 80; - ADD_OR_SIZE(ANDROID_JPEG_QUALITY, &jpegQuality, 1); - - static const int32_t thumbnailSize[2] = {640, 480}; - ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2); - - static const int32_t thumbnailQuality = 80; - ADD_OR_SIZE(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1); - - static const double gpsCoordinates[2] = {0, 0}; - ADD_OR_SIZE(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2); - - static const uint8_t gpsProcessingMethod[32] = "None"; - ADD_OR_SIZE(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, 32); - - static const int64_t gpsTimestamp = 0; - ADD_OR_SIZE(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1); - - static const int32_t jpegOrientation = 0; - ADD_OR_SIZE(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1); - - /** android.stats */ - - static const uint8_t faceDetectMode = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - ADD_OR_SIZE(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); - - static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF; - ADD_OR_SIZE(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1); - - static const uint8_t sharpnessMapMode = - ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF; - ADD_OR_SIZE(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1); - - // faceRectangles, faceScores, faceLandmarks, faceIds, histogram, - // sharpnessMap only in frames - - /** android.control */ - - uint8_t controlIntent = 0; - switch (request_template) { - case CAMERA2_TEMPLATE_PREVIEW: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; - break; - case CAMERA2_TEMPLATE_STILL_CAPTURE: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; - break; - case CAMERA2_TEMPLATE_VIDEO_RECORD: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; - break; - case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; - break; - case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; - break; - default: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; - break; - } - ADD_OR_SIZE(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1); - - static const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO; - ADD_OR_SIZE(ANDROID_CONTROL_MODE, &controlMode, 1); - - static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; - ADD_OR_SIZE(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1); - - static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; - ADD_OR_SIZE(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1); - - static const uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; - ADD_OR_SIZE(ANDROID_CONTROL_AE_MODE, &aeMode, 1); - - static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF; - ADD_OR_SIZE(ANDROID_CONTROL_AE_LOCK, &aeLock, 1); - - static const int32_t controlRegions[5] = { - 0, 0, static_cast<int32_t>(mSensorWidth), - static_cast<int32_t>(mSensorHeight), 1000}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5); - - static const int32_t aeExpCompensation = 0; - ADD_OR_SIZE(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1); - - static const int32_t aeTargetFpsRange[2] = {10, 30}; - ADD_OR_SIZE(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2); - - static const uint8_t aeAntibandingMode = - ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; - ADD_OR_SIZE(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1); - - static const uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO; - ADD_OR_SIZE(ANDROID_CONTROL_AWB_MODE, &awbMode, 1); - - static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF; - ADD_OR_SIZE(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1); - - ADD_OR_SIZE(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5); - - uint8_t afMode = 0; - switch (request_template) { - case CAMERA2_TEMPLATE_PREVIEW: - afMode = ANDROID_CONTROL_AF_MODE_AUTO; - break; - case CAMERA2_TEMPLATE_STILL_CAPTURE: - afMode = ANDROID_CONTROL_AF_MODE_AUTO; - break; - case CAMERA2_TEMPLATE_VIDEO_RECORD: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - break; - case CAMERA2_TEMPLATE_VIDEO_SNAPSHOT: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - break; - case CAMERA2_TEMPLATE_ZERO_SHUTTER_LAG: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - break; - default: - afMode = ANDROID_CONTROL_AF_MODE_AUTO; - break; - } - ADD_OR_SIZE(ANDROID_CONTROL_AF_MODE, &afMode, 1); - - ADD_OR_SIZE(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5); - - static const uint8_t vstabMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; - ADD_OR_SIZE(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1); - - // aeState, awbState, afState only in frame - - /** Allocate metadata if sizing */ - if (sizeRequest) { - ALOGV( - "Allocating %zu entries, %zu extra bytes for " - "request template type %d", - entryCount, dataCount, request_template); - *request = allocate_camera_metadata(entryCount, dataCount); - if (*request == NULL) { - ALOGE( - "Unable to allocate new request template type %d " - "(%zu entries, %zu bytes extra data)", - request_template, entryCount, dataCount); - return NO_MEMORY; - } - } - return OK; -#undef ADD_OR_SIZE -} - -status_t EmulatedFakeCamera2::addOrSize(camera_metadata_t *request, - bool sizeRequest, size_t *entryCount, - size_t *dataCount, uint32_t tag, - const void *entryData, - size_t entryDataCount) { - if (!sizeRequest) { - return add_camera_metadata_entry(request, tag, entryData, entryDataCount); - } else { - int type = get_camera_metadata_tag_type(tag); - if (type < 0) return BAD_VALUE; - (*entryCount)++; - (*dataCount) += - calculate_camera_metadata_entry_data_size(type, entryDataCount); - return OK; - } -} - -bool EmulatedFakeCamera2::isStreamInUse(uint32_t id) { - // Assumes mMutex is locked; otherwise new requests could enter - // configureThread while readoutThread is being checked - - // Order of isStreamInUse calls matters - if (mConfigureThread->isStreamInUse(id) || - mReadoutThread->isStreamInUse(id) || mJpegCompressor->isStreamInUse(id)) { - ALOGE("%s: Stream %d is in use in active requests!", __FUNCTION__, id); - return true; - } - return false; -} - -bool EmulatedFakeCamera2::isReprocessStreamInUse(uint32_t /*id*/) { - // TODO: implement - return false; -} - -const Stream &EmulatedFakeCamera2::getStreamInfo(uint32_t streamId) { - Mutex::Autolock lock(mMutex); - - return mStreams.valueFor(streamId); -} - -const ReprocessStream &EmulatedFakeCamera2::getReprocessStreamInfo( - uint32_t streamId) { - Mutex::Autolock lock(mMutex); - - return mReprocessStreams.valueFor(streamId); -} - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedFakeCamera2.h b/guest/hals/camera/EmulatedFakeCamera2.h deleted file mode 100644 index b55d0126..00000000 --- a/guest/hals/camera/EmulatedFakeCamera2.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H -#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H - -/* - * Contains declaration of a class EmulatedFakeCamera2 that encapsulates - * functionality of a fake camera that implements version 2 of the camera device - * interface. - */ - -#include <vector> - -#include <utils/Condition.h> -#include <utils/KeyedVector.h> -#include <utils/String16.h> -#include <utils/String8.h> -#include "EmulatedCamera2.h" -#include "fake-pipeline2/Base.h" -#include "fake-pipeline2/JpegCompressor.h" -#include "fake-pipeline2/Sensor.h" - -namespace android { - -/* Encapsulates functionality of an advanced fake camera. This camera contains - * a simple simulation of a scene, sensor, and image processing pipeline. - */ -class EmulatedFakeCamera2 : public EmulatedCamera2 { - public: - /* Constructs EmulatedFakeCamera instance. */ - EmulatedFakeCamera2(int cameraId, bool facingBack, - struct hw_module_t *module); - - /* Destructs EmulatedFakeCamera instance. */ - ~EmulatedFakeCamera2(); - - /**************************************************************************** - * EmulatedCamera2 virtual overrides. - ***************************************************************************/ - - public: - /* Initializes EmulatedFakeCamera2 instance. */ - status_t Initialize(const cvd::CameraDefinition &props); - - /**************************************************************************** - * Camera Module API and generic hardware device API implementation - ***************************************************************************/ - public: - virtual status_t connectCamera(hw_device_t **device); - - virtual status_t plugCamera(); - virtual status_t unplugCamera(); - virtual camera_device_status_t getHotplugStatus(); - - virtual status_t closeCamera(); - - virtual status_t getCameraInfo(struct camera_info *info); - - /**************************************************************************** - * EmulatedCamera2 abstract API implementation. - ***************************************************************************/ - protected: - /** Request input queue */ - - virtual int requestQueueNotify(); - - /** Count of requests in flight */ - virtual int getInProgressCount(); - - /** Cancel all captures in flight */ - // virtual int flushCapturesInProgress(); - - /** Construct default request */ - virtual int constructDefaultRequest(int request_template, - camera_metadata_t **request); - - virtual int allocateStream(uint32_t width, uint32_t height, int format, - const camera2_stream_ops_t *stream_ops, - uint32_t *stream_id, uint32_t *format_actual, - uint32_t *usage, uint32_t *max_buffers); - - virtual int registerStreamBuffers(uint32_t stream_id, int num_buffers, - buffer_handle_t *buffers); - - virtual int releaseStream(uint32_t stream_id); - - // virtual int allocateReprocessStream( - // uint32_t width, - // uint32_t height, - // uint32_t format, - // const camera2_stream_ops_t *stream_ops, - // uint32_t *stream_id, - // uint32_t *format_actual, - // uint32_t *usage, - // uint32_t *max_buffers); - - virtual int allocateReprocessStreamFromStream( - uint32_t output_stream_id, const camera2_stream_in_ops_t *stream_ops, - uint32_t *stream_id); - - virtual int releaseReprocessStream(uint32_t stream_id); - - virtual int triggerAction(uint32_t trigger_id, int32_t ext1, int32_t ext2); - - /** Debug methods */ - - virtual int dump(int fd); - - public: - /**************************************************************************** - * Utility methods called by configure/readout threads and pipeline - ***************************************************************************/ - - // Get information about a given stream. Will lock mMutex - const Stream &getStreamInfo(uint32_t streamId); - const ReprocessStream &getReprocessStreamInfo(uint32_t streamId); - - // Notifies rest of camera subsystem of serious error - void signalError(); - - private: - /**************************************************************************** - * Utility methods - ***************************************************************************/ - /** Construct static camera metadata, two-pass */ - status_t constructStaticInfo(camera_metadata_t **info, - bool sizeRequest) const; - - /** Two-pass implementation of constructDefaultRequest */ - status_t constructDefaultRequest(int request_template, - camera_metadata_t **request, - bool sizeRequest) const; - /** Helper function for constructDefaultRequest */ - static status_t addOrSize(camera_metadata_t *request, bool sizeRequest, - size_t *entryCount, size_t *dataCount, uint32_t tag, - const void *entry_data, size_t entry_count); - - /** Determine if the stream id is listed in any currently-in-flight - * requests. Assumes mMutex is locked */ - bool isStreamInUse(uint32_t streamId); - - /** Determine if the reprocess stream id is listed in any - * currently-in-flight requests. Assumes mMutex is locked */ - bool isReprocessStreamInUse(uint32_t streamId); - - /**************************************************************************** - * Pipeline controller threads - ***************************************************************************/ - - class ConfigureThread : public Thread { - public: - ConfigureThread(EmulatedFakeCamera2 *parent); - ~ConfigureThread(); - - status_t waitUntilRunning(); - status_t newRequestAvailable(); - status_t readyToRun(); - - bool isStreamInUse(uint32_t id); - int getInProgressCount(); - - private: - EmulatedFakeCamera2 *mParent; - static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms - - bool mRunning; - bool threadLoop(); - - bool setupCapture(); - bool setupReprocess(); - - bool configureNextCapture(); - bool configureNextReprocess(); - - bool getBuffers(); - - Mutex mInputMutex; // Protects mActive, mRequestCount - Condition mInputSignal; - bool mActive; // Whether we're waiting for input requests or actively - // working on them - size_t mRequestCount; - - camera_metadata_t *mRequest; - - Mutex mInternalsMutex; // Lock before accessing below members. - bool mWaitingForReadout; - bool mNextNeedsJpeg; - bool mNextIsCapture; - int32_t mNextFrameNumber; - int64_t mNextExposureTime; - int64_t mNextFrameDuration; - int32_t mNextSensitivity; - Buffers *mNextBuffers; - }; - - class ReadoutThread : public Thread, private JpegCompressor::JpegListener { - public: - ReadoutThread(EmulatedFakeCamera2 *parent); - ~ReadoutThread(); - - status_t readyToRun(); - - // Input - status_t waitUntilRunning(); - bool waitForReady(nsecs_t timeout); - void setNextOperation(bool isCapture, camera_metadata_t *request, - Buffers *buffers); - bool isStreamInUse(uint32_t id); - int getInProgressCount(); - - private: - EmulatedFakeCamera2 *mParent; - - bool mRunning; - bool threadLoop(); - - bool readyForNextCapture(); - status_t collectStatisticsMetadata(camera_metadata_t *frame); - - // Inputs - Mutex mInputMutex; // Protects mActive, mInFlightQueue, mRequestCount - Condition mInputSignal; - Condition mReadySignal; - - bool mActive; - - static const int kInFlightQueueSize = 4; - struct InFlightQueue { - bool isCapture; - camera_metadata_t *request; - Buffers *buffers; - } * mInFlightQueue; - - size_t mInFlightHead; - size_t mInFlightTail; - - size_t mRequestCount; - - // Internals - Mutex mInternalsMutex; - - bool mIsCapture; - camera_metadata_t *mRequest; - Buffers *mBuffers; - - // Jpeg completion listeners - void onJpegDone(const StreamBuffer &jpegBuffer, bool success); - void onJpegInputDone(const StreamBuffer &inputBuffer); - nsecs_t mJpegTimestamp; - }; - - // 3A management thread (auto-exposure, focus, white balance) - class ControlThread : public Thread { - public: - ControlThread(EmulatedFakeCamera2 *parent); - ~ControlThread(); - - status_t readyToRun(); - - status_t waitUntilRunning(); - - // Interpret request's control parameters and override - // capture settings as needed - status_t processRequest(camera_metadata_t *request); - - status_t triggerAction(uint32_t msgType, int32_t ext1, int32_t ext2); - - private: - ControlThread(const ControlThread &t); - ControlThread &operator=(const ControlThread &t); - - // Constants controlling fake 3A behavior - static const nsecs_t kControlCycleDelay; - static const nsecs_t kMinAfDuration; - static const nsecs_t kMaxAfDuration; - static const float kAfSuccessRate; - static const float kContinuousAfStartRate; - - static const float kAeScanStartRate; - static const nsecs_t kMinAeDuration; - static const nsecs_t kMaxAeDuration; - static const nsecs_t kMinPrecaptureAeDuration; - static const nsecs_t kMaxPrecaptureAeDuration; - - static const nsecs_t kNormalExposureTime; - static const nsecs_t kExposureJump; - static const nsecs_t kMinExposureTime; - - EmulatedFakeCamera2 *mParent; - - bool mRunning; - bool threadLoop(); - - Mutex mInputMutex; // Protects input methods - Condition mInputSignal; - - // Trigger notifications - bool mStartAf; - bool mCancelAf; - bool mStartPrecapture; - - // Latest state for 3A request fields - uint8_t mControlMode; - - uint8_t mEffectMode; - uint8_t mSceneMode; - - uint8_t mAfMode; - bool mAfModeChange; - - uint8_t mAwbMode; - uint8_t mAeMode; - - // Latest trigger IDs - int32_t mAfTriggerId; - int32_t mPrecaptureTriggerId; - - // Current state for 3A algorithms - uint8_t mAfState; - uint8_t mAeState; - uint8_t mAwbState; - bool mAeLock; - - // Current control parameters - nsecs_t mExposureTime; - - // Private to threadLoop and its utility methods - - nsecs_t mAfScanDuration; - nsecs_t mAeScanDuration; - bool mLockAfterPassiveScan; - - // Utility methods for AF - int processAfTrigger(uint8_t afMode, uint8_t afState); - int maybeStartAfScan(uint8_t afMode, uint8_t afState); - int updateAfScan(uint8_t afMode, uint8_t afState, nsecs_t *maxSleep); - void updateAfState(uint8_t newState, int32_t triggerId); - - // Utility methods for precapture trigger - int processPrecaptureTrigger(uint8_t aeMode, uint8_t aeState); - int maybeStartAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState); - int updateAeScan(uint8_t aeMode, bool aeLock, uint8_t aeState, - nsecs_t *maxSleep); - void updateAeState(uint8_t newState, int32_t triggerId); - }; - - /**************************************************************************** - * Static configuration information - ***************************************************************************/ - private: - static const uint32_t kMaxRawStreamCount = 1; - static const uint32_t kMaxProcessedStreamCount = 3; - static const uint32_t kMaxJpegStreamCount = 1; - static const uint32_t kMaxReprocessStreamCount = 2; - static const uint32_t kMaxBufferCount = 4; - static const uint32_t kAvailableFormats[]; - static const uint32_t kAvailableRawSizes[]; - static const uint64_t kAvailableRawMinDurations[]; - static const uint32_t kAvailableProcessedSizesBack[]; - static const uint32_t kAvailableProcessedSizesFront[]; - static const uint64_t kAvailableProcessedMinDurations[]; - static const uint32_t kAvailableJpegSizesBack[]; - static const uint32_t kAvailableJpegSizesFront[]; - static const uint64_t kAvailableJpegMinDurations[]; - - /**************************************************************************** - * Data members. - ***************************************************************************/ - - protected: - /* Facing back (true) or front (false) switch. */ - bool mFacingBack; - - private: - bool mIsConnected; - - int32_t mSensorWidth, mSensorHeight; - - /** Stream manipulation */ - uint32_t mNextStreamId; - uint32_t mRawStreamCount; - uint32_t mProcessedStreamCount; - uint32_t mJpegStreamCount; - - std::vector<uint32_t> mAvailableRawSizes; - std::vector<uint32_t> mAvailableProcessedSizes; - std::vector<uint32_t> mAvailableJpegSizes; - - uint32_t mNextReprocessStreamId; - uint32_t mReprocessStreamCount; - - KeyedVector<uint32_t, Stream> mStreams; - KeyedVector<uint32_t, ReprocessStream> mReprocessStreams; - - /** Simulated hardware interfaces */ - sp<Sensor> mSensor; - sp<JpegCompressor> mJpegCompressor; - - /** Pipeline control threads */ - sp<ConfigureThread> mConfigureThread; - sp<ReadoutThread> mReadoutThread; - sp<ControlThread> mControlThread; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA2_H */ diff --git a/guest/hals/camera/EmulatedFakeCamera3.cpp b/guest/hals/camera/EmulatedFakeCamera3.cpp deleted file mode 100644 index f9d96283..00000000 --- a/guest/hals/camera/EmulatedFakeCamera3.cpp +++ /dev/null @@ -1,2661 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -/* - * Contains implementation of a class EmulatedFakeCamera3 that encapsulates - * functionality of an advanced fake camera. - */ - -#include <cstdint> -#include <inttypes.h> - -//#define LOG_NDEBUG 0 -//#define LOG_NNDEBUG 0 -#define LOG_TAG "EmulatedCamera_FakeCamera3" -#include <cutils/properties.h> -#include <utils/Log.h> - -#include <ui/Fence.h> -#include "EmulatedCameraFactory.h" -#include "EmulatedFakeCamera3.h" -#include "GrallocModule.h" - -#include <cmath> -#include "fake-pipeline2/JpegCompressor.h" -#include "fake-pipeline2/Sensor.h" - -#include <vector> - -#if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0 -#define ALOGVV ALOGV -#else -#define ALOGVV(...) ((void)0) -#endif - -namespace android { - -/** - * Constants for camera capabilities - */ - -const int64_t USEC = 1000LL; -const int64_t MSEC = USEC * 1000LL; -// const int64_t SEC = MSEC * 1000LL; - -const int32_t EmulatedFakeCamera3::kAvailableFormats[] = { - HAL_PIXEL_FORMAT_RAW16, HAL_PIXEL_FORMAT_BLOB, HAL_PIXEL_FORMAT_RGBA_8888, - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - // These are handled by YCbCr_420_888 - // HAL_PIXEL_FORMAT_YV12, - // HAL_PIXEL_FORMAT_YCrCb_420_SP, - HAL_PIXEL_FORMAT_YCbCr_420_888, HAL_PIXEL_FORMAT_Y16}; - -/** - * 3A constants - */ - -// Default exposure and gain targets for different scenarios -const nsecs_t EmulatedFakeCamera3::kNormalExposureTime = 10 * MSEC; -const nsecs_t EmulatedFakeCamera3::kFacePriorityExposureTime = 30 * MSEC; -const int EmulatedFakeCamera3::kNormalSensitivity = 100; -const int EmulatedFakeCamera3::kFacePrioritySensitivity = 400; -const float EmulatedFakeCamera3::kExposureTrackRate = 0.1; -const int EmulatedFakeCamera3::kPrecaptureMinFrames = 10; -const int EmulatedFakeCamera3::kStableAeMaxFrames = 100; -const float EmulatedFakeCamera3::kExposureWanderMin = -2; -const float EmulatedFakeCamera3::kExposureWanderMax = 1; - -/** - * Camera device lifecycle methods - */ - -EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, bool facingBack, - struct hw_module_t *module) - : EmulatedCamera3(cameraId, module), mFacingBack(facingBack) { - ALOGI("Constructing emulated fake camera 3: ID %d, facing %s", mCameraID, - facingBack ? "back" : "front"); - - for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) { - mDefaultTemplates[i] = NULL; - } -} - -EmulatedFakeCamera3::~EmulatedFakeCamera3() { - for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) { - if (mDefaultTemplates[i] != NULL) { - free_camera_metadata(mDefaultTemplates[i]); - } - } -} - -status_t EmulatedFakeCamera3::Initialize(const cvd::CameraDefinition ¶ms) { - ALOGV("%s: E", __FUNCTION__); - status_t res; - - if (mStatus != STATUS_ERROR) { - ALOGE("%s: Already initialized!", __FUNCTION__); - return INVALID_OPERATION; - } - - res = getCameraCapabilities(); - if (res != OK) { - ALOGE("%s: Unable to get camera capabilities: %s (%d)", __FUNCTION__, - strerror(-res), res); - return res; - } - - res = constructStaticInfo(params); - if (res != OK) { - ALOGE("%s: Unable to allocate static info: %s (%d)", __FUNCTION__, - strerror(-res), res); - return res; - } - - return EmulatedCamera3::Initialize(params); -} - -status_t EmulatedFakeCamera3::connectCamera(hw_device_t **device) { - ALOGV("%s: E", __FUNCTION__); - Mutex::Autolock l(mLock); - status_t res; - - if (mStatus != STATUS_CLOSED) { - ALOGE("%s: Can't connect in state %d", __FUNCTION__, mStatus); - return INVALID_OPERATION; - } - - mSensor = new Sensor(mSensorWidth, mSensorHeight); - mSensor->setSensorListener(this); - - res = mSensor->startUp(); - if (res != NO_ERROR) return res; - - mReadoutThread = new ReadoutThread(this); - mJpegCompressor = new JpegCompressor(); - - res = mReadoutThread->run("EmuCam3::readoutThread"); - if (res != NO_ERROR) return res; - - // Initialize fake 3A - - mControlMode = ANDROID_CONTROL_MODE_AUTO; - mFacePriority = false; - mAeMode = ANDROID_CONTROL_AE_MODE_ON; - mAfMode = ANDROID_CONTROL_AF_MODE_AUTO; - mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO; - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; - mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; - mAeCounter = 0; - mAeTargetExposureTime = kNormalExposureTime; - mAeCurrentExposureTime = kNormalExposureTime; - mAeCurrentSensitivity = kNormalSensitivity; - - return EmulatedCamera3::connectCamera(device); -} - -status_t EmulatedFakeCamera3::closeCamera() { - ALOGV("%s: E", __FUNCTION__); - status_t res; - { - Mutex::Autolock l(mLock); - if (mStatus == STATUS_CLOSED) return OK; - - res = mSensor->shutDown(); - if (res != NO_ERROR) { - ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res); - return res; - } - mSensor.clear(); - - mReadoutThread->requestExit(); - } - - mReadoutThread->join(); - - { - Mutex::Autolock l(mLock); - // Clear out private stream information - for (StreamIterator s = mStreams.begin(); s != mStreams.end(); s++) { - PrivateStreamInfo *privStream = - static_cast<PrivateStreamInfo *>((*s)->priv); - delete privStream; - (*s)->priv = NULL; - } - mStreams.clear(); - mReadoutThread.clear(); - } - - return EmulatedCamera3::closeCamera(); -} - -status_t EmulatedFakeCamera3::getCameraInfo(struct camera_info *info) { - info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT; - info->orientation = - EmulatedCameraFactory::Instance().getFakeCameraOrientation(); - info->resource_cost = 100; - info->conflicting_devices = NULL; - info->conflicting_devices_length = 0; - return EmulatedCamera3::getCameraInfo(info); -} - -status_t EmulatedFakeCamera3::setTorchMode(bool enabled) { - if (!mFacingBack) { - ALOGE("%s: Front camera does not have flash unit", __FUNCTION__); - return INVALID_OPERATION; - } - EmulatedCameraFactory::Instance().onTorchModeStatusChanged( - mCameraID, enabled ? TORCH_MODE_STATUS_AVAILABLE_ON - : TORCH_MODE_STATUS_AVAILABLE_OFF); - return NO_ERROR; -} - -/** - * Camera3 interface methods - */ - -status_t EmulatedFakeCamera3::configureStreams( - camera3_stream_configuration *streamList) { - Mutex::Autolock l(mLock); - ALOGV("%s: %d streams", __FUNCTION__, streamList->num_streams); - - if (mStatus != STATUS_OPEN && mStatus != STATUS_READY) { - ALOGE("%s: Cannot configure streams in state %d", __FUNCTION__, mStatus); - return NO_INIT; - } - - /** - * Sanity-check input list. - */ - if (streamList == NULL) { - ALOGE("%s: NULL stream configuration", __FUNCTION__); - return BAD_VALUE; - } - - if (streamList->streams == NULL) { - ALOGE("%s: NULL stream list", __FUNCTION__); - return BAD_VALUE; - } - - if (streamList->num_streams < 1) { - ALOGE("%s: Bad number of streams requested: %d", __FUNCTION__, - streamList->num_streams); - return BAD_VALUE; - } - - camera3_stream_t *inputStream = NULL; - for (size_t i = 0; i < streamList->num_streams; i++) { - camera3_stream_t *newStream = streamList->streams[i]; - - if (newStream == NULL) { - ALOGE("%s: Stream index %zu was NULL", __FUNCTION__, i); - return BAD_VALUE; - } - - ALOGV("%s: Stream %p (id %zu), type %d, usage 0x%x, format 0x%x", - __FUNCTION__, newStream, i, newStream->stream_type, newStream->usage, - newStream->format); - - if (newStream->stream_type == CAMERA3_STREAM_INPUT || - newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) { - if (inputStream != NULL) { - ALOGE("%s: Multiple input streams requested!", __FUNCTION__); - return BAD_VALUE; - } - inputStream = newStream; - } - - bool validFormat = false; - for (size_t f = 0; - f < sizeof(kAvailableFormats) / sizeof(kAvailableFormats[0]); f++) { - if (newStream->format == kAvailableFormats[f]) { - validFormat = true; - break; - } - } - if (!validFormat) { - ALOGE("%s: Unsupported stream format 0x%x requested", __FUNCTION__, - newStream->format); - return BAD_VALUE; - } - } - mInputStream = inputStream; - - /** - * Initially mark all existing streams as not alive - */ - for (StreamIterator s = mStreams.begin(); s != mStreams.end(); ++s) { - PrivateStreamInfo *privStream = - static_cast<PrivateStreamInfo *>((*s)->priv); - privStream->alive = false; - } - - /** - * Find new streams and mark still-alive ones - */ - for (size_t i = 0; i < streamList->num_streams; i++) { - camera3_stream_t *newStream = streamList->streams[i]; - if (newStream->priv == NULL) { - // New stream, construct info - PrivateStreamInfo *privStream = new PrivateStreamInfo(); - privStream->alive = true; - - newStream->max_buffers = kMaxBufferCount; - newStream->priv = privStream; - mStreams.push_back(newStream); - } else { - // Existing stream, mark as still alive. - PrivateStreamInfo *privStream = - static_cast<PrivateStreamInfo *>(newStream->priv); - privStream->alive = true; - } - // Always update usage and max buffers - newStream->max_buffers = kMaxBufferCount; - switch (newStream->stream_type) { - case CAMERA3_STREAM_OUTPUT: - newStream->usage = GRALLOC_USAGE_HW_CAMERA_WRITE; - break; - case CAMERA3_STREAM_INPUT: - newStream->usage = GRALLOC_USAGE_HW_CAMERA_READ; - break; - case CAMERA3_STREAM_BIDIRECTIONAL: - newStream->usage = - GRALLOC_USAGE_HW_CAMERA_READ | GRALLOC_USAGE_HW_CAMERA_WRITE; - break; - } - } - - /** - * Reap the dead streams - */ - for (StreamIterator s = mStreams.begin(); s != mStreams.end();) { - PrivateStreamInfo *privStream = - static_cast<PrivateStreamInfo *>((*s)->priv); - if (!privStream->alive) { - (*s)->priv = NULL; - delete privStream; - s = mStreams.erase(s); - } else { - ++s; - } - } - - /** - * Can't reuse settings across configure call - */ - mPrevSettings.clear(); - - return OK; -} - -status_t EmulatedFakeCamera3::registerStreamBuffers( - const camera3_stream_buffer_set * /*bufferSet*/) { - ALOGV("%s: E", __FUNCTION__); - Mutex::Autolock l(mLock); - - // Should not be called in HAL versions >= 3.2 - - ALOGE("%s: Should not be invoked on new HALs!", __FUNCTION__); - return NO_INIT; -} - -const camera_metadata_t *EmulatedFakeCamera3::constructDefaultRequestSettings( - int type) { - ALOGV("%s: E", __FUNCTION__); - Mutex::Autolock l(mLock); - - if (type < 0 || type >= CAMERA3_TEMPLATE_COUNT) { - ALOGE("%s: Unknown request settings template: %d", __FUNCTION__, type); - return NULL; - } - - if (!hasCapability(BACKWARD_COMPATIBLE) && type != CAMERA3_TEMPLATE_PREVIEW) { - ALOGE("%s: Template %d not supported w/o BACKWARD_COMPATIBLE capability", - __FUNCTION__, type); - return NULL; - } - - /** - * Cache is not just an optimization - pointer returned has to live at - * least as long as the camera device instance does. - */ - if (mDefaultTemplates[type] != NULL) { - return mDefaultTemplates[type]; - } - - CameraMetadata settings; - - /** android.request */ - - static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL; - settings.update(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1); - - static const int32_t id = 0; - settings.update(ANDROID_REQUEST_ID, &id, 1); - - static const int32_t frameCount = 0; - settings.update(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1); - - /** android.lens */ - - static const float focalLength = 5.0f; - settings.update(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const float focusDistance = 0; - settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1); - - static const float aperture = 2.8f; - settings.update(ANDROID_LENS_APERTURE, &aperture, 1); - - static const float filterDensity = 0; - settings.update(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1); - - static const uint8_t opticalStabilizationMode = - ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; - settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, - &opticalStabilizationMode, 1); - - // FOCUS_RANGE set only in frame - } - - /** android.sensor */ - - if (hasCapability(MANUAL_SENSOR)) { - static const int64_t exposureTime = 10 * MSEC; - settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1); - - static const int64_t frameDuration = 33333333L; // 1/30 s - settings.update(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1); - - static const int32_t sensitivity = 100; - settings.update(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1); - } - - // TIMESTAMP set only in frame - - /** android.flash */ - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF; - settings.update(ANDROID_FLASH_MODE, &flashMode, 1); - - static const uint8_t flashPower = 10; - settings.update(ANDROID_FLASH_FIRING_POWER, &flashPower, 1); - - static const int64_t firingTime = 0; - settings.update(ANDROID_FLASH_FIRING_TIME, &firingTime, 1); - } - - /** Processing block modes */ - if (hasCapability(MANUAL_POST_PROCESSING)) { - uint8_t hotPixelMode = 0; - uint8_t demosaicMode = 0; - uint8_t noiseMode = 0; - uint8_t shadingMode = 0; - uint8_t colorMode = 0; - uint8_t tonemapMode = 0; - uint8_t edgeMode = 0; - switch (type) { - case CAMERA3_TEMPLATE_STILL_CAPTURE: - // fall-through - case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: - // fall-through - case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: - hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; - demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY; - noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; - shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY; - colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY; - tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; - edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY; - break; - case CAMERA3_TEMPLATE_PREVIEW: - // fall-through - case CAMERA3_TEMPLATE_VIDEO_RECORD: - // fall-through - default: - hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST; - demosaicMode = ANDROID_DEMOSAIC_MODE_FAST; - noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST; - shadingMode = ANDROID_SHADING_MODE_FAST; - colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST; - tonemapMode = ANDROID_TONEMAP_MODE_FAST; - edgeMode = ANDROID_EDGE_MODE_FAST; - break; - } - settings.update(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1); - settings.update(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1); - settings.update(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1); - settings.update(ANDROID_SHADING_MODE, &shadingMode, 1); - settings.update(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1); - settings.update(ANDROID_TONEMAP_MODE, &tonemapMode, 1); - settings.update(ANDROID_EDGE_MODE, &edgeMode, 1); - } - - /** android.colorCorrection */ - - if (hasCapability(MANUAL_POST_PROCESSING)) { - static const camera_metadata_rational colorTransform[9] = { - {1, 1}, {0, 1}, {0, 1}, {0, 1}, {1, 1}, {0, 1}, {0, 1}, {0, 1}, {1, 1}}; - settings.update(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9); - - static const float colorGains[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - settings.update(ANDROID_COLOR_CORRECTION_GAINS, colorGains, 4); - } - - /** android.tonemap */ - - if (hasCapability(MANUAL_POST_PROCESSING)) { - static const float tonemapCurve[4] = {0.f, 0.f, 1.f, 1.f}; - settings.update(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4); - settings.update(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4); - settings.update(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4); - } - - /** android.scaler */ - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const int32_t cropRegion[4] = {0, 0, mSensorWidth, mSensorHeight}; - settings.update(ANDROID_SCALER_CROP_REGION, cropRegion, 4); - } - - /** android.jpeg */ - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t jpegQuality = 80; - settings.update(ANDROID_JPEG_QUALITY, &jpegQuality, 1); - - static const int32_t thumbnailSize[2] = {640, 480}; - settings.update(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2); - - static const uint8_t thumbnailQuality = 80; - settings.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1); - - static const double gpsCoordinates[2] = {0, 0}; - settings.update(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 2); - - static const uint8_t gpsProcessingMethod[32] = "None"; - settings.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, - 32); - - static const int64_t gpsTimestamp = 0; - settings.update(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1); - - static const int32_t jpegOrientation = 0; - settings.update(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1); - } - - /** android.stats */ - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t faceDetectMode = - ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; - settings.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); - - static const uint8_t hotPixelMapMode = - ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF; - settings.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE, &hotPixelMapMode, 1); - } - - // faceRectangles, faceScores, faceLandmarks, faceIds, histogram, - // sharpnessMap only in frames - - /** android.control */ - - uint8_t controlIntent = 0; - switch (type) { - case CAMERA3_TEMPLATE_PREVIEW: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; - break; - case CAMERA3_TEMPLATE_STILL_CAPTURE: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; - break; - case CAMERA3_TEMPLATE_VIDEO_RECORD: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; - break; - case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; - break; - case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; - break; - case CAMERA3_TEMPLATE_MANUAL: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL; - break; - default: - controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; - break; - } - settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1); - - const uint8_t controlMode = (type == CAMERA3_TEMPLATE_MANUAL) - ? ANDROID_CONTROL_MODE_OFF - : ANDROID_CONTROL_MODE_AUTO; - settings.update(ANDROID_CONTROL_MODE, &controlMode, 1); - - int32_t aeTargetFpsRange[2] = {5, 30}; - if (type == CAMERA3_TEMPLATE_VIDEO_RECORD || - type == CAMERA3_TEMPLATE_VIDEO_SNAPSHOT) { - aeTargetFpsRange[0] = 30; - } - settings.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; - settings.update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1); - - static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; - settings.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1); - - const uint8_t aeMode = (type == CAMERA3_TEMPLATE_MANUAL) - ? ANDROID_CONTROL_AE_MODE_OFF - : ANDROID_CONTROL_AE_MODE_ON; - settings.update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); - - static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF; - settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1); - - static const int32_t controlRegions[5] = {0, 0, 0, 0, 0}; - settings.update(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5); - - static const int32_t aeExpCompensation = 0; - settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, - &aeExpCompensation, 1); - - static const uint8_t aeAntibandingMode = - ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; - settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1); - - static const uint8_t aePrecaptureTrigger = - ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; - settings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, - 1); - - const uint8_t awbMode = (type == CAMERA3_TEMPLATE_MANUAL) - ? ANDROID_CONTROL_AWB_MODE_OFF - : ANDROID_CONTROL_AWB_MODE_AUTO; - settings.update(ANDROID_CONTROL_AWB_MODE, &awbMode, 1); - - static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF; - settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1); - - uint8_t afMode = 0; - - if (mFacingBack) { - switch (type) { - case CAMERA3_TEMPLATE_PREVIEW: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - break; - case CAMERA3_TEMPLATE_STILL_CAPTURE: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - break; - case CAMERA3_TEMPLATE_VIDEO_RECORD: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - break; - case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; - break; - case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: - afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; - break; - case CAMERA3_TEMPLATE_MANUAL: - afMode = ANDROID_CONTROL_AF_MODE_OFF; - break; - default: - afMode = ANDROID_CONTROL_AF_MODE_AUTO; - break; - } - } else { - afMode = ANDROID_CONTROL_AF_MODE_OFF; - } - settings.update(ANDROID_CONTROL_AF_MODE, &afMode, 1); - - settings.update(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5); - - static const uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; - settings.update(ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1); - - static const uint8_t vstabMode = - ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; - settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1); - - static const uint8_t blackLevelLock = ANDROID_BLACK_LEVEL_LOCK_OFF; - settings.update(ANDROID_BLACK_LEVEL_LOCK, &blackLevelLock, 1); - - static const uint8_t lensShadingMapMode = - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; - settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, - &lensShadingMapMode, 1); - - static const uint8_t aberrationMode = - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST; - settings.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, &aberrationMode, - 1); - - static const int32_t testPatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; - settings.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPatternMode, 1); - } - - mDefaultTemplates[type] = settings.release(); - - return mDefaultTemplates[type]; -} - -status_t EmulatedFakeCamera3::processCaptureRequest( - camera3_capture_request *request) { - Mutex::Autolock l(mLock); - status_t res; - - /** Validation */ - - if (mStatus < STATUS_READY) { - ALOGE("%s: Can't submit capture requests in state %d", __FUNCTION__, - mStatus); - return INVALID_OPERATION; - } - - if (request == NULL) { - ALOGE("%s: NULL request!", __FUNCTION__); - return BAD_VALUE; - } - - uint32_t frameNumber = request->frame_number; - - if (request->settings == NULL && mPrevSettings.isEmpty()) { - ALOGE( - "%s: Request %d: NULL settings for first request after" - "configureStreams()", - __FUNCTION__, frameNumber); - return BAD_VALUE; - } - - if (request->input_buffer != NULL && - request->input_buffer->stream != mInputStream) { - ALOGE("%s: Request %d: Input buffer not from input stream!", __FUNCTION__, - frameNumber); - ALOGV("%s: Bad stream %p, expected: %p", __FUNCTION__, - request->input_buffer->stream, mInputStream); - ALOGV("%s: Bad stream type %d, expected stream type %d", __FUNCTION__, - request->input_buffer->stream->stream_type, - mInputStream ? mInputStream->stream_type : -1); - - return BAD_VALUE; - } - - if (request->num_output_buffers < 1 || request->output_buffers == NULL) { - ALOGE("%s: Request %d: No output buffers provided!", __FUNCTION__, - frameNumber); - return BAD_VALUE; - } - - // Validate all buffers, starting with input buffer if it's given - - ssize_t idx; - const camera3_stream_buffer_t *b; - if (request->input_buffer != NULL) { - idx = -1; - b = request->input_buffer; - } else { - idx = 0; - b = request->output_buffers; - } - do { - PrivateStreamInfo *priv = static_cast<PrivateStreamInfo *>(b->stream->priv); - if (priv == NULL) { - ALOGE("%s: Request %d: Buffer %zu: Unconfigured stream!", __FUNCTION__, - frameNumber, idx); - return BAD_VALUE; - } - if (!priv->alive) { - ALOGE("%s: Request %d: Buffer %zu: Dead stream!", __FUNCTION__, - frameNumber, idx); - return BAD_VALUE; - } - if (b->status != CAMERA3_BUFFER_STATUS_OK) { - ALOGE("%s: Request %d: Buffer %zu: Status not OK!", __FUNCTION__, - frameNumber, idx); - return BAD_VALUE; - } - if (b->release_fence != -1) { - ALOGE("%s: Request %d: Buffer %zu: Has a release fence!", __FUNCTION__, - frameNumber, idx); - return BAD_VALUE; - } - if (b->buffer == NULL) { - ALOGE("%s: Request %d: Buffer %zu: NULL buffer handle!", __FUNCTION__, - frameNumber, idx); - return BAD_VALUE; - } - idx++; - b = &(request->output_buffers[idx]); - } while (idx < (ssize_t)request->num_output_buffers); - - // TODO: Validate settings parameters - - /** - * Start processing this request - */ - - mStatus = STATUS_ACTIVE; - - CameraMetadata settings; - - if (request->settings == NULL) { - settings.acquire(mPrevSettings); - } else { - settings = request->settings; - } - - res = process3A(settings); - if (res != OK) { - return res; - } - - // TODO: Handle reprocessing - - /** - * Get ready for sensor config - */ - - nsecs_t exposureTime; - nsecs_t frameDuration; - uint32_t sensitivity; - bool needJpeg = false; - camera_metadata_entry_t entry; - - entry = settings.find(ANDROID_SENSOR_EXPOSURE_TIME); - exposureTime = - (entry.count > 0) ? entry.data.i64[0] : Sensor::kExposureTimeRange[0]; - entry = settings.find(ANDROID_SENSOR_FRAME_DURATION); - frameDuration = - (entry.count > 0) ? entry.data.i64[0] : Sensor::kFrameDurationRange[0]; - entry = settings.find(ANDROID_SENSOR_SENSITIVITY); - sensitivity = - (entry.count > 0) ? entry.data.i32[0] : Sensor::kSensitivityRange[0]; - - if (exposureTime > frameDuration) { - frameDuration = exposureTime + Sensor::kMinVerticalBlank; - settings.update(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1); - } - - Buffers *sensorBuffers = new Buffers(); - HalBufferVector *buffers = new HalBufferVector(); - - sensorBuffers->setCapacity(request->num_output_buffers); - buffers->setCapacity(request->num_output_buffers); - - // Process all the buffers we got for output, constructing internal buffer - // structures for them, and lock them for writing. - for (size_t i = 0; i < request->num_output_buffers; i++) { - const camera3_stream_buffer &srcBuf = request->output_buffers[i]; - StreamBuffer destBuf; - destBuf.streamId = kGenericStreamId; - destBuf.width = srcBuf.stream->width; - destBuf.height = srcBuf.stream->height; - // For GCE, IMPLEMENTATION_DEFINED is always RGBx_8888 - destBuf.format = - (srcBuf.stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) - ? HAL_PIXEL_FORMAT_RGBA_8888 - : srcBuf.stream->format; - destBuf.stride = srcBuf.stream->width; - destBuf.dataSpace = srcBuf.stream->data_space; - destBuf.buffer = srcBuf.buffer; - - if (destBuf.format == HAL_PIXEL_FORMAT_BLOB) { - needJpeg = true; - } - - // Wait on fence - sp<Fence> bufferAcquireFence = new Fence(srcBuf.acquire_fence); - res = bufferAcquireFence->wait(kFenceTimeoutMs); - if (res == TIMED_OUT) { - ALOGE("%s: Request %d: Buffer %zu: Fence timed out after %d ms", - __FUNCTION__, frameNumber, i, kFenceTimeoutMs); - } - if (res == OK) { - // Lock buffer for writing - if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { - if (destBuf.format == HAL_PIXEL_FORMAT_YCbCr_420_888) { - android_ycbcr ycbcr = android_ycbcr(); - res = GrallocModule::getInstance().lock_ycbcr( - *(destBuf.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0, - destBuf.width, destBuf.height, &ycbcr); - // This is only valid because we know that emulator's - // YCbCr_420_888 is really contiguous NV21 under the hood - destBuf.img = static_cast<uint8_t *>(ycbcr.y); - } else { - ALOGE("Unexpected private format for flexible YUV: 0x%x", - destBuf.format); - res = INVALID_OPERATION; - } - } else { - res = GrallocModule::getInstance().lock( - *(destBuf.buffer), GRALLOC_USAGE_HW_CAMERA_WRITE, 0, 0, - destBuf.width, destBuf.height, (void **)&(destBuf.img)); - } - if (res != OK) { - ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer", __FUNCTION__, - frameNumber, i); - } - } - - if (res != OK) { - // Either waiting or locking failed. Unlock locked buffers and bail - // out. - for (size_t j = 0; j < i; j++) { - GrallocModule::getInstance().unlock( - *(request->output_buffers[i].buffer)); - } - delete sensorBuffers; - delete buffers; - return NO_INIT; - } - - sensorBuffers->push_back(destBuf); - buffers->push_back(srcBuf); - } - - /** - * Wait for JPEG compressor to not be busy, if needed - */ - if (needJpeg) { - bool ready = mJpegCompressor->waitForDone(kJpegTimeoutNs); - if (!ready) { - ALOGE("%s: Timeout waiting for JPEG compression to complete!", - __FUNCTION__); - return NO_INIT; - } - res = mJpegCompressor->reserve(); - if (res != OK) { - ALOGE("%s: Error managing JPEG compressor resources, can't reserve it!", - __FUNCTION__); - return NO_INIT; - } - } - - /** - * Wait until the in-flight queue has room - */ - res = mReadoutThread->waitForReadout(); - if (res != OK) { - ALOGE("%s: Timeout waiting for previous requests to complete!", - __FUNCTION__); - return NO_INIT; - } - - /** - * Wait until sensor's ready. This waits for lengthy amounts of time with - * mLock held, but the interface spec is that no other calls may by done to - * the HAL by the framework while process_capture_request is happening. - */ - int syncTimeoutCount = 0; - while (!mSensor->waitForVSync(kSyncWaitTimeout)) { - if (mStatus == STATUS_ERROR) { - return NO_INIT; - } - if (syncTimeoutCount == kMaxSyncTimeoutCount) { - ALOGE("%s: Request %d: Sensor sync timed out after %" PRId64 " ms", - __FUNCTION__, frameNumber, - kSyncWaitTimeout * kMaxSyncTimeoutCount / 1000000); - return NO_INIT; - } - syncTimeoutCount++; - } - - /** - * Configure sensor and queue up the request to the readout thread - */ - mSensor->setExposureTime(exposureTime); - mSensor->setFrameDuration(frameDuration); - mSensor->setSensitivity(sensitivity); - mSensor->setDestinationBuffers(sensorBuffers); - mSensor->setFrameNumber(request->frame_number); - - ReadoutThread::Request r; - r.frameNumber = request->frame_number; - r.settings = settings; - r.sensorBuffers = sensorBuffers; - r.buffers = buffers; - - mReadoutThread->queueCaptureRequest(r); - ALOGVV("%s: Queued frame %d", __FUNCTION__, request->frame_number); - - // Cache the settings for next time - mPrevSettings.acquire(settings); - - return OK; -} - -status_t EmulatedFakeCamera3::flush() { - ALOGW("%s: Not implemented; ignored", __FUNCTION__); - return OK; -} - -/** Debug methods */ - -void EmulatedFakeCamera3::dump(int /*fd*/) {} - -/** - * Private methods - */ - -status_t EmulatedFakeCamera3::getCameraCapabilities() { - const char *key = - mFacingBack ? "qemu.sf.back_camera_caps" : "qemu.sf.front_camera_caps"; - - /* Defined by 'qemu.sf.*_camera_caps' boot property: if the - * property doesn't exist, it is assumed to list FULL. */ - char prop[PROPERTY_VALUE_MAX]; - if (property_get(key, prop, NULL) > 0) { - char *saveptr = nullptr; - char *cap = strtok_r(prop, " ,", &saveptr); - while (cap != NULL) { - for (int i = 0; i < NUM_CAPABILITIES; i++) { - if (!strcasecmp(cap, sAvailableCapabilitiesStrings[i])) { - mCapabilities.add(static_cast<AvailableCapabilities>(i)); - break; - } - } - cap = strtok_r(NULL, " ,", &saveptr); - } - if (mCapabilities.size() == 0) { - ALOGE("qemu.sf.back_camera_caps had no valid capabilities: %s", prop); - } - } - // Default to FULL_LEVEL plus RAW if nothing is defined - if (mCapabilities.size() == 0) { - mCapabilities.add(FULL_LEVEL); - mCapabilities.add(RAW); - } - - // Add level-based caps - if (hasCapability(FULL_LEVEL)) { - mCapabilities.add(BURST_CAPTURE); - mCapabilities.add(READ_SENSOR_SETTINGS); - mCapabilities.add(MANUAL_SENSOR); - mCapabilities.add(MANUAL_POST_PROCESSING); - }; - - // Backwards-compatible is required for most other caps - // Not required for DEPTH_OUTPUT, though. - if (hasCapability(BURST_CAPTURE) || hasCapability(READ_SENSOR_SETTINGS) || - hasCapability(RAW) || hasCapability(MANUAL_SENSOR) || - hasCapability(MANUAL_POST_PROCESSING) || - hasCapability(PRIVATE_REPROCESSING) || hasCapability(YUV_REPROCESSING) || - hasCapability(CONSTRAINED_HIGH_SPEED_VIDEO)) { - mCapabilities.add(BACKWARD_COMPATIBLE); - } - - ALOGI("Camera %d capabilities:", mCameraID); - for (size_t i = 0; i < mCapabilities.size(); i++) { - ALOGI(" %s", sAvailableCapabilitiesStrings[mCapabilities[i]]); - } - - return OK; -} - -bool EmulatedFakeCamera3::hasCapability(AvailableCapabilities cap) { - ssize_t idx = mCapabilities.indexOf(cap); - return idx >= 0; -} - -status_t EmulatedFakeCamera3::constructStaticInfo( - const cvd::CameraDefinition ¶ms) { - CameraMetadata info; - Vector<int32_t> availableCharacteristicsKeys; - status_t res; - - int32_t width = 0, height = 0; - - /* TODO(ender): this currently supports only maximum resolution. */ - for (size_t index = 0; index < params.resolutions.size(); ++index) { - if (width <= params.resolutions[index].width && - height <= params.resolutions[index].height) { - width = params.resolutions[index].width; - height = params.resolutions[index].height; - } - } - - if (width < 640 || height < 480) { - width = 640; - height = 480; - } - - mSensorWidth = width; - mSensorHeight = height; - -#define ADD_STATIC_ENTRY(name, varptr, count) \ - availableCharacteristicsKeys.add(name); \ - res = info.update(name, varptr, count); \ - if (res != OK) return res - - // android.sensor - - if (hasCapability(MANUAL_SENSOR)) { - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, - Sensor::kExposureTimeRange, 2); - - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, - &Sensor::kFrameDurationRange[1], 1); - - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, - Sensor::kSensitivityRange, - sizeof(Sensor::kSensitivityRange) / sizeof(int32_t)); - - ADD_STATIC_ENTRY(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY, - &Sensor::kSensitivityRange[1], 1); - } - - static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, sensorPhysicalSize, 2); - - const int32_t pixelArray[] = {mSensorWidth, mSensorHeight}; - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixelArray, 2); - const int32_t activeArray[] = {0, 0, mSensorWidth, mSensorHeight}; - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArray, 4); - - static const int32_t orientation = 90; // Aligned with 'long edge' - ADD_STATIC_ENTRY(ANDROID_SENSOR_ORIENTATION, &orientation, 1); - - static const uint8_t timestampSource = - ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME; - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1); - - if (hasCapability(RAW)) { - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, - &Sensor::kColorFilterArrangement, 1); - - ADD_STATIC_ENTRY(ANDROID_SENSOR_INFO_WHITE_LEVEL, - (int32_t *)&Sensor::kMaxRawValue, 1); - - static const int32_t blackLevelPattern[4] = { - (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel, - (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel}; - ADD_STATIC_ENTRY(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, blackLevelPattern, - sizeof(blackLevelPattern) / sizeof(int32_t)); - } - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const int32_t availableTestPatternModes[] = { - ANDROID_SENSOR_TEST_PATTERN_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, - availableTestPatternModes, - sizeof(availableTestPatternModes) / sizeof(int32_t)); - } - - // android.lens - - static const float focalLength = 3.30f; // mm - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, &focalLength, 1); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - // 5 cm min focus distance for back camera, infinity (fixed focus) for front - const float minFocusDistance = mFacingBack ? 1.0 / 0.05 : 0.0; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, - &minFocusDistance, 1); - - // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front - const float hyperFocalDistance = mFacingBack ? 1.0 / 5.0 : 0.0; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, &hyperFocalDistance, - 1); - - static const float aperture = 2.8f; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_APERTURES, &aperture, 1); - static const float filterDensity = 0; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, - &filterDensity, 1); - static const uint8_t availableOpticalStabilization = - ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, - &availableOpticalStabilization, 1); - - static const int32_t lensShadingMapSize[] = {1, 1}; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize, - sizeof(lensShadingMapSize) / sizeof(int32_t)); - - static const uint8_t lensFocusCalibration = - ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE; - ADD_STATIC_ENTRY(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION, - &lensFocusCalibration, 1); - } - - if (hasCapability(DEPTH_OUTPUT)) { - // These could be included for non-DEPTH capability as well, but making this - // variable for testing coverage - - // 90 degree rotation to align with long edge of a phone device that's by - // default portrait - static const float qO[] = {0.707107f, 0.f, 0.f, 0.707107f}; - - // Either a 180-degree rotation for back-facing, or no rotation for - // front-facing - const float qF[] = {0, (mFacingBack ? 1.f : 0.f), 0, - (mFacingBack ? 0.f : 1.f)}; - - // Quarternion product, orientation change then facing - const float lensPoseRotation[] = { - qO[0] * qF[0] - qO[1] * qF[1] - qO[2] * qF[2] - qO[3] * qF[3], - qO[0] * qF[1] + qO[1] * qF[0] + qO[2] * qF[3] - qO[3] * qF[2], - qO[0] * qF[2] + qO[2] * qF[0] + qO[1] * qF[3] - qO[3] * qF[1], - qO[0] * qF[3] + qO[3] * qF[0] + qO[1] * qF[2] - qO[2] * qF[1]}; - - ADD_STATIC_ENTRY(ANDROID_LENS_POSE_ROTATION, lensPoseRotation, - sizeof(lensPoseRotation) / sizeof(float)); - - // Only one camera facing each way, so 0 translation needed to the center of - // the 'main' camera - static const float lensPoseTranslation[] = {0.f, 0.f, 0.f}; - - ADD_STATIC_ENTRY(ANDROID_LENS_POSE_TRANSLATION, lensPoseTranslation, - sizeof(lensPoseTranslation) / sizeof(float)); - - // Intrinsics are 'ideal' (f_x, f_y, c_x, c_y, s) match focal length and - // active array size - float f_x = focalLength * mSensorWidth / sensorPhysicalSize[0]; - float f_y = focalLength * mSensorHeight / sensorPhysicalSize[1]; - float c_x = mSensorWidth / 2.f; - float c_y = mSensorHeight / 2.f; - float s = 0.f; - const float lensIntrinsics[] = {f_x, f_y, c_x, c_y, s}; - - ADD_STATIC_ENTRY(ANDROID_LENS_INTRINSIC_CALIBRATION, lensIntrinsics, - sizeof(lensIntrinsics) / sizeof(float)); - - // No radial or tangential distortion - - float lensRadialDistortion[] = {1.0f, 0.f, 0.f, 0.f, 0.f, 0.f}; - - ADD_STATIC_ENTRY(ANDROID_LENS_RADIAL_DISTORTION, lensRadialDistortion, - sizeof(lensRadialDistortion) / sizeof(float)); - } - - const uint8_t lensFacing = - mFacingBack ? ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT; - ADD_STATIC_ENTRY(ANDROID_LENS_FACING, &lensFacing, 1); - - // android.flash - - const uint8_t flashAvailable = mFacingBack; - ADD_STATIC_ENTRY(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1); - - // android.tonemap - - if (hasCapability(MANUAL_POST_PROCESSING)) { - static const int32_t tonemapCurvePoints = 128; - ADD_STATIC_ENTRY(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1); - - static const uint8_t availableToneMapModes[] = { - ANDROID_TONEMAP_MODE_CONTRAST_CURVE, ANDROID_TONEMAP_MODE_FAST, - ANDROID_TONEMAP_MODE_HIGH_QUALITY}; - ADD_STATIC_ENTRY(ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES, - availableToneMapModes, sizeof(availableToneMapModes)); - } - - // android.scaler - - const std::vector<int32_t> availableStreamConfigurationsBasic = { - HAL_PIXEL_FORMAT_BLOB, - width, - height, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 320, - 240, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_YCbCr_420_888, - 320, - 240, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_BLOB, - 320, - 240, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - }; - - // Always need to include 640x480 in basic formats - const std::vector<int32_t> availableStreamConfigurationsBasic640 = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 640, - 480, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_YCbCr_420_888, - 640, - 480, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_BLOB, - 640, - 480, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}; - - const std::vector<int32_t> availableStreamConfigurationsRaw = { - HAL_PIXEL_FORMAT_RAW16, - width, - height, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - }; - - const std::vector<int32_t> availableStreamConfigurationsBurst = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - width, - height, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_YCbCr_420_888, - width, - height, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_RGBA_8888, - width, - height, - ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT, - }; - - std::vector<int32_t> availableStreamConfigurations; - - if (hasCapability(BACKWARD_COMPATIBLE)) { - availableStreamConfigurations.insert( - availableStreamConfigurations.end(), - availableStreamConfigurationsBasic.begin(), - availableStreamConfigurationsBasic.end()); - if (width > 640) { - availableStreamConfigurations.insert( - availableStreamConfigurations.end(), - availableStreamConfigurationsBasic640.begin(), - availableStreamConfigurationsBasic640.end()); - } - } - if (hasCapability(RAW)) { - availableStreamConfigurations.insert( - availableStreamConfigurations.end(), - availableStreamConfigurationsRaw.begin(), - availableStreamConfigurationsRaw.end()); - } - if (hasCapability(BURST_CAPTURE)) { - availableStreamConfigurations.insert( - availableStreamConfigurations.end(), - availableStreamConfigurationsBurst.begin(), - availableStreamConfigurationsBurst.end()); - } - - if (availableStreamConfigurations.size() > 0) { - ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, - &availableStreamConfigurations[0], - availableStreamConfigurations.size()); - } - - const std::vector<int64_t> availableMinFrameDurationsBasic = { - HAL_PIXEL_FORMAT_BLOB, - width, - height, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 320, - 240, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_YCbCr_420_888, - 320, - 240, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_BLOB, - 320, - 240, - Sensor::kFrameDurationRange[0], - }; - - // Always need to include 640x480 in basic formats - const std::vector<int64_t> availableMinFrameDurationsBasic640 = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 640, - 480, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_YCbCr_420_888, - 640, - 480, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_BLOB, - 640, - 480, - Sensor::kFrameDurationRange[0]}; - - const std::vector<int64_t> availableMinFrameDurationsRaw = { - HAL_PIXEL_FORMAT_RAW16, - width, - height, - Sensor::kFrameDurationRange[0], - }; - - const std::vector<int64_t> availableMinFrameDurationsBurst = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - width, - height, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_YCbCr_420_888, - width, - height, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_RGBA_8888, - width, - height, - Sensor::kFrameDurationRange[0], - }; - - std::vector<int64_t> availableMinFrameDurations; - - if (hasCapability(BACKWARD_COMPATIBLE)) { - availableMinFrameDurations.insert(availableMinFrameDurations.end(), - availableMinFrameDurationsBasic.begin(), - availableMinFrameDurationsBasic.end()); - if (width > 640) { - availableMinFrameDurations.insert( - availableMinFrameDurations.end(), - availableMinFrameDurationsBasic640.begin(), - availableMinFrameDurationsBasic640.end()); - } - } - if (hasCapability(RAW)) { - availableMinFrameDurations.insert(availableMinFrameDurations.end(), - availableMinFrameDurationsRaw.begin(), - availableMinFrameDurationsRaw.end()); - } - if (hasCapability(BURST_CAPTURE)) { - availableMinFrameDurations.insert(availableMinFrameDurations.end(), - availableMinFrameDurationsBurst.begin(), - availableMinFrameDurationsBurst.end()); - } - - if (availableMinFrameDurations.size() > 0) { - ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, - &availableMinFrameDurations[0], - availableMinFrameDurations.size()); - } - - const std::vector<int64_t> availableStallDurationsBasic = { - HAL_PIXEL_FORMAT_BLOB, - width, - height, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 320, - 240, - 0, - HAL_PIXEL_FORMAT_YCbCr_420_888, - 320, - 240, - 0, - HAL_PIXEL_FORMAT_RGBA_8888, - 320, - 240, - 0, - }; - - // Always need to include 640x480 in basic formats - const std::vector<int64_t> availableStallDurationsBasic640 = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - 640, - 480, - 0, - HAL_PIXEL_FORMAT_YCbCr_420_888, - 640, - 480, - 0, - HAL_PIXEL_FORMAT_BLOB, - 640, - 480, - Sensor::kFrameDurationRange[0]}; - - const std::vector<int64_t> availableStallDurationsRaw = { - HAL_PIXEL_FORMAT_RAW16, width, height, Sensor::kFrameDurationRange[0]}; - const std::vector<int64_t> availableStallDurationsBurst = { - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - width, - height, - 0, - HAL_PIXEL_FORMAT_YCbCr_420_888, - width, - height, - 0, - HAL_PIXEL_FORMAT_RGBA_8888, - width, - height, - 0}; - - std::vector<int64_t> availableStallDurations; - - if (hasCapability(BACKWARD_COMPATIBLE)) { - availableStallDurations.insert(availableStallDurations.end(), - availableStallDurationsBasic.begin(), - availableStallDurationsBasic.end()); - if (width > 640) { - availableStallDurations.insert(availableStallDurations.end(), - availableStallDurationsBasic640.begin(), - availableStallDurationsBasic640.end()); - } - } - if (hasCapability(RAW)) { - availableStallDurations.insert(availableStallDurations.end(), - availableStallDurationsRaw.begin(), - availableStallDurationsRaw.end()); - } - if (hasCapability(BURST_CAPTURE)) { - availableStallDurations.insert(availableStallDurations.end(), - availableStallDurationsBurst.begin(), - availableStallDurationsBurst.end()); - } - - if (availableStallDurations.size() > 0) { - ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, - &availableStallDurations[0], - availableStallDurations.size()); - } - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_FREEFORM; - ADD_STATIC_ENTRY(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1); - - static const float maxZoom = 10; - ADD_STATIC_ENTRY(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, &maxZoom, 1); - } - - // android.jpeg - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const int32_t jpegThumbnailSizes[] = {0, 0, 160, 120, 320, 240}; - ADD_STATIC_ENTRY(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, jpegThumbnailSizes, - sizeof(jpegThumbnailSizes) / sizeof(int32_t)); - - static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize; - ADD_STATIC_ENTRY(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1); - } - - // android.stats - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableFaceDetectModes[] = { - ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, - ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE, - ANDROID_STATISTICS_FACE_DETECT_MODE_FULL}; - ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, - availableFaceDetectModes, - sizeof(availableFaceDetectModes)); - - static const int32_t maxFaceCount = 8; - ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, &maxFaceCount, 1); - - static const uint8_t availableShadingMapModes[] = { - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, - availableShadingMapModes, - sizeof(availableShadingMapModes)); - } - - // android.sync - - static const int32_t maxLatency = - hasCapability(FULL_LEVEL) ? ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL - : 3; - ADD_STATIC_ENTRY(ANDROID_SYNC_MAX_LATENCY, &maxLatency, 1); - - // android.control - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableControlModes[] = { - ANDROID_CONTROL_MODE_OFF, ANDROID_CONTROL_MODE_AUTO, - ANDROID_CONTROL_MODE_USE_SCENE_MODE}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_MODES, availableControlModes, - sizeof(availableControlModes)); - } else { - static const uint8_t availableControlModes[] = {ANDROID_CONTROL_MODE_AUTO}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_MODES, availableControlModes, - sizeof(availableControlModes)); - } - - static const uint8_t availableSceneModes[] = { - static_cast<uint8_t>(hasCapability(BACKWARD_COMPATIBLE) - ? ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY - : ANDROID_CONTROL_SCENE_MODE_DISABLED)}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, availableSceneModes, - sizeof(availableSceneModes)); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableEffects[] = {ANDROID_CONTROL_EFFECT_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_EFFECTS, availableEffects, - sizeof(availableEffects)); - } - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const int32_t max3aRegions[] = {/*AE*/ 1, /*AWB*/ 0, /*AF*/ 1}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_MAX_REGIONS, max3aRegions, - sizeof(max3aRegions) / sizeof(max3aRegions[0])); - - static const uint8_t availableAeModes[] = {ANDROID_CONTROL_AE_MODE_OFF, - ANDROID_CONTROL_AE_MODE_ON}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_MODES, availableAeModes, - sizeof(availableAeModes)); - - static const camera_metadata_rational exposureCompensationStep = {1, 3}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_COMPENSATION_STEP, - &exposureCompensationStep, 1); - - int32_t exposureCompensationRange[] = {-9, 9}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_COMPENSATION_RANGE, - exposureCompensationRange, - sizeof(exposureCompensationRange) / sizeof(int32_t)); - } - - static const int32_t availableTargetFpsRanges[] = {5, 30, 15, 30, - 15, 15, 30, 30}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, - availableTargetFpsRanges, - sizeof(availableTargetFpsRanges) / sizeof(int32_t)); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableAntibandingModes[] = { - ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, - ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, - availableAntibandingModes, - sizeof(availableAntibandingModes)); - } - - static const uint8_t aeLockAvailable = - hasCapability(BACKWARD_COMPATIBLE) - ? ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE - : ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE; - - ADD_STATIC_ENTRY(ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailable, 1); - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableAwbModes[] = { - ANDROID_CONTROL_AWB_MODE_OFF, - ANDROID_CONTROL_AWB_MODE_AUTO, - ANDROID_CONTROL_AWB_MODE_INCANDESCENT, - ANDROID_CONTROL_AWB_MODE_FLUORESCENT, - ANDROID_CONTROL_AWB_MODE_DAYLIGHT, - ANDROID_CONTROL_AWB_MODE_SHADE}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes, - sizeof(availableAwbModes)); - } - - static const uint8_t awbLockAvailable = - hasCapability(BACKWARD_COMPATIBLE) - ? ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE - : ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE; - - ADD_STATIC_ENTRY(ANDROID_CONTROL_AWB_LOCK_AVAILABLE, &awbLockAvailable, 1); - - static const uint8_t availableAfModesBack[] = { - ANDROID_CONTROL_AF_MODE_OFF, ANDROID_CONTROL_AF_MODE_AUTO, - ANDROID_CONTROL_AF_MODE_MACRO, ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, - ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE}; - - static const uint8_t availableAfModesFront[] = {ANDROID_CONTROL_AF_MODE_OFF}; - - if (mFacingBack && hasCapability(BACKWARD_COMPATIBLE)) { - ADD_STATIC_ENTRY(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesBack, - sizeof(availableAfModesBack)); - } else { - ADD_STATIC_ENTRY(ANDROID_CONTROL_AF_AVAILABLE_MODES, availableAfModesFront, - sizeof(availableAfModesFront)); - } - - static const uint8_t availableVstabModes[] = { - ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, - availableVstabModes, sizeof(availableVstabModes)); - - // android.colorCorrection - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableAberrationModes[] = { - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF, - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST, - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY}; - ADD_STATIC_ENTRY(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, - availableAberrationModes, - sizeof(availableAberrationModes)); - } else { - static const uint8_t availableAberrationModes[] = { - ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF, - }; - ADD_STATIC_ENTRY(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, - availableAberrationModes, - sizeof(availableAberrationModes)); - } - // android.edge - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableEdgeModes[] = { - ANDROID_EDGE_MODE_OFF, ANDROID_EDGE_MODE_FAST, - ANDROID_EDGE_MODE_HIGH_QUALITY}; - ADD_STATIC_ENTRY(ANDROID_EDGE_AVAILABLE_EDGE_MODES, availableEdgeModes, - sizeof(availableEdgeModes)); - } else { - static const uint8_t availableEdgeModes[] = {ANDROID_EDGE_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_EDGE_AVAILABLE_EDGE_MODES, availableEdgeModes, - sizeof(availableEdgeModes)); - } - - // android.info - - static const uint8_t supportedHardwareLevel = - hasCapability(FULL_LEVEL) ? ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL - : ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; - ADD_STATIC_ENTRY(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, - &supportedHardwareLevel, - /*count*/ 1); - - // android.noiseReduction - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableNoiseReductionModes[] = { - ANDROID_NOISE_REDUCTION_MODE_OFF, ANDROID_NOISE_REDUCTION_MODE_FAST, - ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY}; - ADD_STATIC_ENTRY(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, - availableNoiseReductionModes, - sizeof(availableNoiseReductionModes)); - } else { - static const uint8_t availableNoiseReductionModes[] = { - ANDROID_NOISE_REDUCTION_MODE_OFF, - }; - ADD_STATIC_ENTRY(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, - availableNoiseReductionModes, - sizeof(availableNoiseReductionModes)); - } - - // android.depth - - if (hasCapability(DEPTH_OUTPUT)) { - static const int32_t maxDepthSamples = 100; - ADD_STATIC_ENTRY(ANDROID_DEPTH_MAX_DEPTH_SAMPLES, &maxDepthSamples, 1); - - static const int32_t availableDepthStreamConfigurations[] = { - HAL_PIXEL_FORMAT_Y16, - 160, - 120, - ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT, - HAL_PIXEL_FORMAT_BLOB, - maxDepthSamples, - 1, - ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT}; - ADD_STATIC_ENTRY( - ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, - availableDepthStreamConfigurations, - sizeof(availableDepthStreamConfigurations) / sizeof(int32_t)); - - static const int64_t availableDepthMinFrameDurations[] = { - HAL_PIXEL_FORMAT_Y16, - 160, - 120, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_BLOB, - maxDepthSamples, - 1, - Sensor::kFrameDurationRange[0]}; - ADD_STATIC_ENTRY(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS, - availableDepthMinFrameDurations, - sizeof(availableDepthMinFrameDurations) / sizeof(int64_t)); - - static const int64_t availableDepthStallDurations[] = { - HAL_PIXEL_FORMAT_Y16, - 160, - 120, - Sensor::kFrameDurationRange[0], - HAL_PIXEL_FORMAT_BLOB, - maxDepthSamples, - 1, - Sensor::kFrameDurationRange[0]}; - ADD_STATIC_ENTRY(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS, - availableDepthStallDurations, - sizeof(availableDepthStallDurations) / sizeof(int64_t)); - - uint8_t depthIsExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE; - ADD_STATIC_ENTRY(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthIsExclusive, 1); - } - - // android.shading - - if (hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t availableShadingModes[] = { - ANDROID_SHADING_MODE_OFF, ANDROID_SHADING_MODE_FAST, - ANDROID_SHADING_MODE_HIGH_QUALITY}; - ADD_STATIC_ENTRY(ANDROID_SHADING_AVAILABLE_MODES, availableShadingModes, - sizeof(availableShadingModes)); - } else { - static const uint8_t availableShadingModes[] = {ANDROID_SHADING_MODE_OFF}; - ADD_STATIC_ENTRY(ANDROID_SHADING_AVAILABLE_MODES, availableShadingModes, - sizeof(availableShadingModes)); - } - - // android.request - - static const int32_t maxNumOutputStreams[] = { - kMaxRawStreamCount, kMaxProcessedStreamCount, kMaxJpegStreamCount}; - ADD_STATIC_ENTRY(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, maxNumOutputStreams, - 3); - - static const uint8_t maxPipelineDepth = kMaxBufferCount; - ADD_STATIC_ENTRY(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, &maxPipelineDepth, 1); - - static const int32_t partialResultCount = 1; - ADD_STATIC_ENTRY(ANDROID_REQUEST_PARTIAL_RESULT_COUNT, &partialResultCount, - /*count*/ 1); - - SortedVector<uint8_t> caps; - for (size_t i = 0; i < mCapabilities.size(); i++) { - switch (mCapabilities[i]) { - case BACKWARD_COMPATIBLE: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE); - break; - case MANUAL_SENSOR: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR); - break; - case MANUAL_POST_PROCESSING: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING); - break; - case RAW: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW); - break; - case PRIVATE_REPROCESSING: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING); - break; - case READ_SENSOR_SETTINGS: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS); - break; - case BURST_CAPTURE: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE); - break; - case YUV_REPROCESSING: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING); - break; - case DEPTH_OUTPUT: - caps.add(ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT); - break; - case CONSTRAINED_HIGH_SPEED_VIDEO: - caps.add( - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO); - break; - default: - // Ignore LEVELs - break; - } - } - ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, caps.array(), - caps.size()); - - // Scan a default request template for included request keys - Vector<int32_t> availableRequestKeys; - const camera_metadata_t *previewRequest = - constructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW); - for (size_t i = 0; i < get_camera_metadata_entry_count(previewRequest); i++) { - camera_metadata_ro_entry_t entry; - get_camera_metadata_ro_entry(previewRequest, i, &entry); - availableRequestKeys.add(entry.tag); - } - ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS, - availableRequestKeys.array(), availableRequestKeys.size()); - - // Add a few more result keys. Must be kept up to date with the various places - // that add these - - Vector<int32_t> availableResultKeys(availableRequestKeys); - if (hasCapability(BACKWARD_COMPATIBLE)) { - availableResultKeys.add(ANDROID_CONTROL_AE_STATE); - availableResultKeys.add(ANDROID_CONTROL_AF_STATE); - availableResultKeys.add(ANDROID_CONTROL_AWB_STATE); - availableResultKeys.add(ANDROID_FLASH_STATE); - availableResultKeys.add(ANDROID_LENS_STATE); - availableResultKeys.add(ANDROID_LENS_FOCUS_RANGE); - availableResultKeys.add(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW); - availableResultKeys.add(ANDROID_STATISTICS_SCENE_FLICKER); - } - - if (hasCapability(DEPTH_OUTPUT)) { - availableResultKeys.add(ANDROID_LENS_POSE_ROTATION); - availableResultKeys.add(ANDROID_LENS_POSE_TRANSLATION); - availableResultKeys.add(ANDROID_LENS_INTRINSIC_CALIBRATION); - availableResultKeys.add(ANDROID_LENS_RADIAL_DISTORTION); - } - - availableResultKeys.add(ANDROID_REQUEST_PIPELINE_DEPTH); - availableResultKeys.add(ANDROID_SENSOR_TIMESTAMP); - - ADD_STATIC_ENTRY(ANDROID_REQUEST_AVAILABLE_RESULT_KEYS, - availableResultKeys.array(), availableResultKeys.size()); - - // Needs to be last, to collect all the keys set - - availableCharacteristicsKeys.add( - ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS); - info.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, - availableCharacteristicsKeys); - - mCameraInfo = info.release(); - -#undef ADD_STATIC_ENTRY - return OK; -} - -status_t EmulatedFakeCamera3::process3A(CameraMetadata &settings) { - /** - * Extract top-level 3A controls - */ - status_t res; - - camera_metadata_entry e; - - e = settings.find(ANDROID_CONTROL_MODE); - if (e.count == 0) { - ALOGE("%s: No control mode entry!", __FUNCTION__); - return BAD_VALUE; - } - uint8_t controlMode = e.data.u8[0]; - - if (controlMode == ANDROID_CONTROL_MODE_OFF) { - mAeMode = ANDROID_CONTROL_AE_MODE_OFF; - mAfMode = ANDROID_CONTROL_AF_MODE_OFF; - mAwbMode = ANDROID_CONTROL_AWB_MODE_OFF; - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; - mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; - update3A(settings); - return OK; - } else if (controlMode == ANDROID_CONTROL_MODE_USE_SCENE_MODE) { - if (!hasCapability(BACKWARD_COMPATIBLE)) { - ALOGE("%s: Can't use scene mode when BACKWARD_COMPATIBLE not supported!", - __FUNCTION__); - return BAD_VALUE; - } - - e = settings.find(ANDROID_CONTROL_SCENE_MODE); - if (e.count == 0) { - ALOGE("%s: No scene mode entry!", __FUNCTION__); - return BAD_VALUE; - } - uint8_t sceneMode = e.data.u8[0]; - - switch (sceneMode) { - case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY: - mFacePriority = true; - break; - default: - ALOGE("%s: Emulator doesn't support scene mode %d", __FUNCTION__, - sceneMode); - return BAD_VALUE; - } - } else { - mFacePriority = false; - } - - // controlMode == AUTO or sceneMode = FACE_PRIORITY - // Process individual 3A controls - - res = doFakeAE(settings); - if (res != OK) return res; - - res = doFakeAF(settings); - if (res != OK) return res; - - res = doFakeAWB(settings); - if (res != OK) return res; - - update3A(settings); - return OK; -} - -status_t EmulatedFakeCamera3::doFakeAE(CameraMetadata &settings) { - camera_metadata_entry e; - - e = settings.find(ANDROID_CONTROL_AE_MODE); - if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) { - ALOGE("%s: No AE mode entry!", __FUNCTION__); - return BAD_VALUE; - } - uint8_t aeMode = - (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AE_MODE_ON; - mAeMode = aeMode; - - switch (aeMode) { - case ANDROID_CONTROL_AE_MODE_OFF: - // AE is OFF - mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; - return OK; - case ANDROID_CONTROL_AE_MODE_ON: - // OK for AUTO modes - break; - default: - // Mostly silently ignore unsupported modes - ALOGV("%s: Emulator doesn't support AE mode %d, assuming ON", - __FUNCTION__, aeMode); - break; - } - - e = settings.find(ANDROID_CONTROL_AE_LOCK); - bool aeLocked = - (e.count > 0) ? (e.data.u8[0] == ANDROID_CONTROL_AE_LOCK_ON) : false; - - e = settings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER); - bool precaptureTrigger = false; - if (e.count != 0) { - precaptureTrigger = - (e.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START); - } - - if (precaptureTrigger) { - ALOGV("%s: Pre capture trigger = %d", __FUNCTION__, precaptureTrigger); - } else if (e.count > 0) { - ALOGV("%s: Pre capture trigger was present? %zu", __FUNCTION__, e.count); - } - - if (precaptureTrigger || mAeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { - // Run precapture sequence - if (mAeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { - mAeCounter = 0; - } - - if (mFacePriority) { - mAeTargetExposureTime = kFacePriorityExposureTime; - } else { - mAeTargetExposureTime = kNormalExposureTime; - } - - if (mAeCounter > kPrecaptureMinFrames && - (mAeTargetExposureTime - mAeCurrentExposureTime) < - mAeTargetExposureTime / 10) { - // Done with precapture - mAeCounter = 0; - mAeState = aeLocked ? ANDROID_CONTROL_AE_STATE_LOCKED - : ANDROID_CONTROL_AE_STATE_CONVERGED; - } else { - // Converge some more - mAeCurrentExposureTime += - (mAeTargetExposureTime - mAeCurrentExposureTime) * kExposureTrackRate; - mAeCounter++; - mAeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE; - } - - } else if (!aeLocked) { - // Run standard occasional AE scan - switch (mAeState) { - case ANDROID_CONTROL_AE_STATE_CONVERGED: - case ANDROID_CONTROL_AE_STATE_INACTIVE: - mAeCounter++; - if (mAeCounter > kStableAeMaxFrames) { - mAeTargetExposureTime = - mFacePriority ? kFacePriorityExposureTime : kNormalExposureTime; - float exposureStep = ((double)rand() / RAND_MAX) * - (kExposureWanderMax - kExposureWanderMin) + - kExposureWanderMin; - mAeTargetExposureTime *= std::pow(2, exposureStep); - mAeState = ANDROID_CONTROL_AE_STATE_SEARCHING; - } - break; - case ANDROID_CONTROL_AE_STATE_SEARCHING: - mAeCurrentExposureTime += - (mAeTargetExposureTime - mAeCurrentExposureTime) * - kExposureTrackRate; - if (llabs(mAeTargetExposureTime - mAeCurrentExposureTime) < - mAeTargetExposureTime / 10) { - // Close enough - mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED; - mAeCounter = 0; - } - break; - case ANDROID_CONTROL_AE_STATE_LOCKED: - mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED; - mAeCounter = 0; - break; - default: - ALOGE("%s: Emulator in unexpected AE state %d", __FUNCTION__, mAeState); - return INVALID_OPERATION; - } - } else { - // AE is locked - mAeState = ANDROID_CONTROL_AE_STATE_LOCKED; - } - - return OK; -} - -status_t EmulatedFakeCamera3::doFakeAF(CameraMetadata &settings) { - camera_metadata_entry e; - - e = settings.find(ANDROID_CONTROL_AF_MODE); - if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) { - ALOGE("%s: No AF mode entry!", __FUNCTION__); - return BAD_VALUE; - } - uint8_t afMode = - (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AF_MODE_OFF; - - e = settings.find(ANDROID_CONTROL_AF_TRIGGER); - typedef camera_metadata_enum_android_control_af_trigger af_trigger_t; - af_trigger_t afTrigger; - if (e.count != 0) { - afTrigger = static_cast<af_trigger_t>(e.data.u8[0]); - - ALOGV("%s: AF trigger set to 0x%x", __FUNCTION__, afTrigger); - ALOGV("%s: AF mode is 0x%x", __FUNCTION__, afMode); - } else { - afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; - } - - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_OFF: - mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; - return OK; - case ANDROID_CONTROL_AF_MODE_AUTO: - case ANDROID_CONTROL_AF_MODE_MACRO: - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - if (!mFacingBack) { - ALOGE("%s: Front camera doesn't support AF mode %d", __FUNCTION__, - afMode); - return BAD_VALUE; - } - // OK, handle transitions lower on - break; - default: - ALOGE("%s: Emulator doesn't support AF mode %d", __FUNCTION__, afMode); - return BAD_VALUE; - } - - bool afModeChanged = mAfMode != afMode; - mAfMode = afMode; - - /** - * Simulate AF triggers. Transition at most 1 state per frame. - * - Focusing always succeeds (goes into locked, or PASSIVE_SCAN). - */ - - bool afTriggerStart = false; - bool afTriggerCancel = false; - switch (afTrigger) { - case ANDROID_CONTROL_AF_TRIGGER_IDLE: - break; - case ANDROID_CONTROL_AF_TRIGGER_START: - afTriggerStart = true; - break; - case ANDROID_CONTROL_AF_TRIGGER_CANCEL: - afTriggerCancel = true; - // Cancel trigger always transitions into INACTIVE - mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; - - ALOGV("%s: AF State transition to STATE_INACTIVE", __FUNCTION__); - - // Stay in 'inactive' until at least next frame - return OK; - default: - ALOGE("%s: Unknown af trigger value %d", __FUNCTION__, afTrigger); - return BAD_VALUE; - } - - // If we get down here, we're either in an autofocus mode - // or in a continuous focus mode (and no other modes) - - int oldAfState = mAfState; - switch (mAfState) { - case ANDROID_CONTROL_AF_STATE_INACTIVE: - if (afTriggerStart) { - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_AUTO: - // fall-through - case ANDROID_CONTROL_AF_MODE_MACRO: - mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - // fall-through - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - break; - } - } else { - // At least one frame stays in INACTIVE - if (!afModeChanged) { - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - // fall-through - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; - break; - } - } - } - break; - case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN: - /** - * When the AF trigger is activated, the algorithm should finish - * its PASSIVE_SCAN if active, and then transition into AF_FOCUSED - * or AF_NOT_FOCUSED as appropriate - */ - if (afTriggerStart) { - // Randomly transition to focused or not focused - if (rand() % 3) { - mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - } else { - mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - } - } - /** - * When the AF trigger is not involved, the AF algorithm should - * start in INACTIVE state, and then transition into PASSIVE_SCAN - * and PASSIVE_FOCUSED states - */ - else if (!afTriggerCancel) { - // Randomly transition to passive focus - if (rand() % 3 == 0) { - mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; - } - } - - break; - case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED: - if (afTriggerStart) { - // Randomly transition to focused or not focused - if (rand() % 3) { - mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - } else { - mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - } - } - // TODO: initiate passive scan (PASSIVE_SCAN) - break; - case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN: - // Simulate AF sweep completing instantaneously - - // Randomly transition to focused or not focused - if (rand() % 3) { - mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; - } else { - mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; - } - break; - case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: - if (afTriggerStart) { - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_AUTO: - // fall-through - case ANDROID_CONTROL_AF_MODE_MACRO: - mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - // fall-through - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - // continuous autofocus => trigger start has no effect - break; - } - } - break; - case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: - if (afTriggerStart) { - switch (afMode) { - case ANDROID_CONTROL_AF_MODE_AUTO: - // fall-through - case ANDROID_CONTROL_AF_MODE_MACRO: - mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; - break; - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: - // fall-through - case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: - // continuous autofocus => trigger start has no effect - break; - } - } - break; - default: - ALOGE("%s: Bad af state %d", __FUNCTION__, mAfState); - } - - { - char afStateString[100] = { - 0, - }; - camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, oldAfState, - afStateString, sizeof(afStateString)); - - char afNewStateString[100] = { - 0, - }; - camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, mAfState, - afNewStateString, sizeof(afNewStateString)); - ALOGVV("%s: AF state transitioned from %s to %s", __FUNCTION__, - afStateString, afNewStateString); - } - - return OK; -} - -status_t EmulatedFakeCamera3::doFakeAWB(CameraMetadata &settings) { - camera_metadata_entry e; - - e = settings.find(ANDROID_CONTROL_AWB_MODE); - if (e.count == 0 && hasCapability(BACKWARD_COMPATIBLE)) { - ALOGE("%s: No AWB mode entry!", __FUNCTION__); - return BAD_VALUE; - } - uint8_t awbMode = - (e.count > 0) ? e.data.u8[0] : (uint8_t)ANDROID_CONTROL_AWB_MODE_AUTO; - - // TODO: Add white balance simulation - - e = settings.find(ANDROID_CONTROL_AWB_LOCK); - bool awbLocked = - (e.count > 0) ? (e.data.u8[0] == ANDROID_CONTROL_AWB_LOCK_ON) : false; - - switch (awbMode) { - case ANDROID_CONTROL_AWB_MODE_OFF: - mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; - break; - case ANDROID_CONTROL_AWB_MODE_AUTO: - case ANDROID_CONTROL_AWB_MODE_INCANDESCENT: - case ANDROID_CONTROL_AWB_MODE_FLUORESCENT: - case ANDROID_CONTROL_AWB_MODE_DAYLIGHT: - case ANDROID_CONTROL_AWB_MODE_SHADE: - // Always magically right, or locked - mAwbState = awbLocked ? ANDROID_CONTROL_AWB_STATE_LOCKED - : ANDROID_CONTROL_AWB_STATE_CONVERGED; - break; - default: - ALOGE("%s: Emulator doesn't support AWB mode %d", __FUNCTION__, awbMode); - return BAD_VALUE; - } - - return OK; -} - -void EmulatedFakeCamera3::update3A(CameraMetadata &settings) { - if (mAeMode != ANDROID_CONTROL_AE_MODE_OFF) { - settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &mAeCurrentExposureTime, 1); - settings.update(ANDROID_SENSOR_SENSITIVITY, &mAeCurrentSensitivity, 1); - } - - settings.update(ANDROID_CONTROL_AE_STATE, &mAeState, 1); - settings.update(ANDROID_CONTROL_AF_STATE, &mAfState, 1); - settings.update(ANDROID_CONTROL_AWB_STATE, &mAwbState, 1); - - uint8_t lensState; - switch (mAfState) { - case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN: - case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN: - lensState = ANDROID_LENS_STATE_MOVING; - break; - case ANDROID_CONTROL_AF_STATE_INACTIVE: - case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED: - case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: - case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: - case ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED: - default: - lensState = ANDROID_LENS_STATE_STATIONARY; - break; - } - settings.update(ANDROID_LENS_STATE, &lensState, 1); -} - -void EmulatedFakeCamera3::signalReadoutIdle() { - Mutex::Autolock l(mLock); - // Need to chek isIdle again because waiting on mLock may have allowed - // something to be placed in the in-flight queue. - if (mStatus == STATUS_ACTIVE && mReadoutThread->isIdle()) { - ALOGV("Now idle"); - mStatus = STATUS_READY; - } -} - -void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e, - nsecs_t timestamp) { - switch (e) { - case Sensor::SensorListener::EXPOSURE_START: { - ALOGVV("%s: Frame %d: Sensor started exposure at %lld", __FUNCTION__, - frameNumber, timestamp); - // Trigger shutter notify to framework - camera3_notify_msg_t msg; - msg.type = CAMERA3_MSG_SHUTTER; - msg.message.shutter.frame_number = frameNumber; - msg.message.shutter.timestamp = timestamp; - sendNotify(&msg); - break; - } - default: - ALOGW("%s: Unexpected sensor event %d at %" PRId64, __FUNCTION__, e, - timestamp); - break; - } -} - -EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent) - : mParent(parent), mJpegWaiting(false) {} - -EmulatedFakeCamera3::ReadoutThread::~ReadoutThread() { - for (List<Request>::iterator i = mInFlightQueue.begin(); - i != mInFlightQueue.end(); i++) { - delete i->buffers; - delete i->sensorBuffers; - } -} - -void EmulatedFakeCamera3::ReadoutThread::queueCaptureRequest(const Request &r) { - Mutex::Autolock l(mLock); - - mInFlightQueue.push_back(r); - mInFlightSignal.signal(); -} - -bool EmulatedFakeCamera3::ReadoutThread::isIdle() { - Mutex::Autolock l(mLock); - return mInFlightQueue.empty() && !mThreadActive; -} - -status_t EmulatedFakeCamera3::ReadoutThread::waitForReadout() { - status_t res; - Mutex::Autolock l(mLock); - int loopCount = 0; - while (mInFlightQueue.size() >= kMaxQueueSize) { - res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop); - if (res != OK && res != TIMED_OUT) { - ALOGE("%s: Error waiting for in-flight queue to shrink", __FUNCTION__); - return INVALID_OPERATION; - } - if (loopCount == kMaxWaitLoops) { - ALOGE("%s: Timed out waiting for in-flight queue to shrink", - __FUNCTION__); - return TIMED_OUT; - } - loopCount++; - } - return OK; -} - -bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { - status_t res; - - ALOGVV("%s: ReadoutThread waiting for request", __FUNCTION__); - - // First wait for a request from the in-flight queue - - if (mCurrentRequest.settings.isEmpty()) { - Mutex::Autolock l(mLock); - if (mInFlightQueue.empty()) { - res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop); - if (res == TIMED_OUT) { - ALOGVV("%s: ReadoutThread: Timed out waiting for request", - __FUNCTION__); - return true; - } else if (res != NO_ERROR) { - ALOGE("%s: Error waiting for capture requests: %d", __FUNCTION__, res); - return false; - } - } - mCurrentRequest.frameNumber = mInFlightQueue.begin()->frameNumber; - mCurrentRequest.settings.acquire(mInFlightQueue.begin()->settings); - mCurrentRequest.buffers = mInFlightQueue.begin()->buffers; - mCurrentRequest.sensorBuffers = mInFlightQueue.begin()->sensorBuffers; - mInFlightQueue.erase(mInFlightQueue.begin()); - mInFlightSignal.signal(); - mThreadActive = true; - ALOGVV("%s: Beginning readout of frame %d", __FUNCTION__, - mCurrentRequest.frameNumber); - } - - // Then wait for it to be delivered from the sensor - ALOGVV("%s: ReadoutThread: Wait for frame to be delivered from sensor", - __FUNCTION__); - - nsecs_t captureTime; - bool gotFrame = mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime); - if (!gotFrame) { - ALOGVV("%s: ReadoutThread: Timed out waiting for sensor frame", - __FUNCTION__); - return true; - } - - ALOGVV("Sensor done with readout for frame %d, captured at %lld ", - mCurrentRequest.frameNumber, captureTime); - - // Check if we need to JPEG encode a buffer, and send it for async - // compression if so. Otherwise prepare the buffer for return. - bool needJpeg = false; - HalBufferVector::iterator buf = mCurrentRequest.buffers->begin(); - while (buf != mCurrentRequest.buffers->end()) { - bool goodBuffer = true; - if (buf->stream->format == HAL_PIXEL_FORMAT_BLOB && - buf->stream->data_space != HAL_DATASPACE_DEPTH) { - Mutex::Autolock jl(mJpegLock); - if (mJpegWaiting) { - // This shouldn't happen, because processCaptureRequest should - // be stalling until JPEG compressor is free. - ALOGE("%s: Already processing a JPEG!", __FUNCTION__); - goodBuffer = false; - } - if (goodBuffer) { - // Compressor takes ownership of sensorBuffers here - res = mParent->mJpegCompressor->start(mCurrentRequest.sensorBuffers, - this); - goodBuffer = (res == OK); - } - if (goodBuffer) { - needJpeg = true; - - mJpegHalBuffer = *buf; - mJpegFrameNumber = mCurrentRequest.frameNumber; - mJpegWaiting = true; - - mCurrentRequest.sensorBuffers = NULL; - buf = mCurrentRequest.buffers->erase(buf); - - continue; - } - ALOGE("%s: Error compressing output buffer: %s (%d)", __FUNCTION__, - strerror(-res), res); - // fallthrough for cleanup - } - GrallocModule::getInstance().unlock(*(buf->buffer)); - - buf->status = - goodBuffer ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR; - buf->acquire_fence = -1; - buf->release_fence = -1; - - ++buf; - } // end while - - // Construct result for all completed buffers and results - - camera3_capture_result result; - - if (mParent->hasCapability(BACKWARD_COMPATIBLE)) { - static const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE; - mCurrentRequest.settings.update(ANDROID_STATISTICS_SCENE_FLICKER, - &sceneFlicker, 1); - - static const uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE; - mCurrentRequest.settings.update(ANDROID_FLASH_STATE, &flashState, 1); - - nsecs_t rollingShutterSkew = Sensor::kFrameDurationRange[0]; - mCurrentRequest.settings.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, - &rollingShutterSkew, 1); - - float focusRange[] = {1.0f / 5.0f, 0}; // 5 m to infinity in focus - mCurrentRequest.settings.update(ANDROID_LENS_FOCUS_RANGE, focusRange, - sizeof(focusRange) / sizeof(float)); - } - - if (mParent->hasCapability(DEPTH_OUTPUT)) { - camera_metadata_entry_t entry; - - find_camera_metadata_entry(mParent->mCameraInfo, - ANDROID_LENS_POSE_TRANSLATION, &entry); - mCurrentRequest.settings.update(ANDROID_LENS_POSE_TRANSLATION, entry.data.f, - entry.count); - - find_camera_metadata_entry(mParent->mCameraInfo, ANDROID_LENS_POSE_ROTATION, - &entry); - mCurrentRequest.settings.update(ANDROID_LENS_POSE_ROTATION, entry.data.f, - entry.count); - - find_camera_metadata_entry(mParent->mCameraInfo, - ANDROID_LENS_INTRINSIC_CALIBRATION, &entry); - mCurrentRequest.settings.update(ANDROID_LENS_INTRINSIC_CALIBRATION, - entry.data.f, entry.count); - - find_camera_metadata_entry(mParent->mCameraInfo, - ANDROID_LENS_RADIAL_DISTORTION, &entry); - mCurrentRequest.settings.update(ANDROID_LENS_RADIAL_DISTORTION, - entry.data.f, entry.count); - } - - mCurrentRequest.settings.update(ANDROID_SENSOR_TIMESTAMP, &captureTime, 1); - - // JPEGs take a stage longer - const uint8_t pipelineDepth = - needJpeg ? kMaxBufferCount : kMaxBufferCount - 1; - mCurrentRequest.settings.update(ANDROID_REQUEST_PIPELINE_DEPTH, - &pipelineDepth, 1); - - result.frame_number = mCurrentRequest.frameNumber; - result.result = mCurrentRequest.settings.getAndLock(); - result.num_output_buffers = mCurrentRequest.buffers->size(); - result.output_buffers = mCurrentRequest.buffers->array(); - result.input_buffer = nullptr; - result.partial_result = 1; - - // Go idle if queue is empty, before sending result - bool signalIdle = false; - { - Mutex::Autolock l(mLock); - if (mInFlightQueue.empty()) { - mThreadActive = false; - signalIdle = true; - } - } - if (signalIdle) mParent->signalReadoutIdle(); - - // Send it off to the framework - ALOGVV("%s: ReadoutThread: Send result to framework", __FUNCTION__); - mParent->sendCaptureResult(&result); - - // Clean up - mCurrentRequest.settings.unlock(result.result); - - delete mCurrentRequest.buffers; - mCurrentRequest.buffers = NULL; - if (!needJpeg) { - delete mCurrentRequest.sensorBuffers; - mCurrentRequest.sensorBuffers = NULL; - } - mCurrentRequest.settings.clear(); - - return true; -} - -void EmulatedFakeCamera3::ReadoutThread::onJpegDone( - const StreamBuffer &jpegBuffer, bool success) { - Mutex::Autolock jl(mJpegLock); - - GrallocModule::getInstance().unlock(*(jpegBuffer.buffer)); - - mJpegHalBuffer.status = - success ? CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR; - mJpegHalBuffer.acquire_fence = -1; - mJpegHalBuffer.release_fence = -1; - mJpegWaiting = false; - - camera3_capture_result result; - - result.frame_number = mJpegFrameNumber; - result.result = NULL; - result.num_output_buffers = 1; - result.output_buffers = &mJpegHalBuffer; - result.input_buffer = nullptr; - result.partial_result = 0; - - if (!success) { - ALOGE( - "%s: Compression failure, returning error state buffer to" - " framework", - __FUNCTION__); - } else { - ALOGV("%s: Compression complete, returning buffer to framework", - __FUNCTION__); - } - - mParent->sendCaptureResult(&result); -} - -void EmulatedFakeCamera3::ReadoutThread::onJpegInputDone( - const StreamBuffer & /*inputBuffer*/) { - // Should never get here, since the input buffer has to be returned - // by end of processCaptureRequest - ALOGE("%s: Unexpected input buffer from JPEG compressor!", __FUNCTION__); -} - -}; // namespace android diff --git a/guest/hals/camera/EmulatedFakeCamera3.h b/guest/hals/camera/EmulatedFakeCamera3.h deleted file mode 100644 index d67662ae..00000000 --- a/guest/hals/camera/EmulatedFakeCamera3.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA3_H -#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA3_H - -/** - * Contains declaration of a class EmulatedCamera that encapsulates - * functionality of a fake camera that implements version 3 of the camera device - * interace. - */ - -#include <CameraMetadata.h> -using ::android::hardware::camera::common::V1_0::helper::CameraMetadata; - -#include <utils/List.h> -#include <utils/Mutex.h> -#include <utils/SortedVector.h> -#include "EmulatedCamera3.h" -#include "fake-pipeline2/Base.h" -#include "fake-pipeline2/JpegCompressor.h" -#include "fake-pipeline2/Sensor.h" - -namespace android { - -/** - * Encapsulates functionality for a v3 HAL camera which produces synthetic data. - * - * Note that EmulatedCameraFactory instantiates an object of this class just - * once, when EmulatedCameraFactory instance gets constructed. Connection to / - * disconnection from the actual camera device is handled by calls to - * connectDevice(), and closeCamera() methods of this class that are invoked in - * response to hw_module_methods_t::open, and camera_device::close callbacks. - */ -class EmulatedFakeCamera3 : public EmulatedCamera3, - private Sensor::SensorListener { - public: - EmulatedFakeCamera3(int cameraId, bool facingBack, - struct hw_module_t *module); - - virtual ~EmulatedFakeCamera3(); - - /**************************************************************************** - * EmulatedCamera3 virtual overrides - ***************************************************************************/ - - public: - virtual status_t Initialize(const cvd::CameraDefinition ¶ms); - - /**************************************************************************** - * Camera module API and generic hardware device API implementation - ***************************************************************************/ - - public: - virtual status_t connectCamera(hw_device_t **device); - - virtual status_t closeCamera(); - - virtual status_t getCameraInfo(struct camera_info *info); - - virtual status_t setTorchMode(bool enabled); - - /**************************************************************************** - * EmulatedCamera3 abstract API implementation - ***************************************************************************/ - - protected: - virtual status_t configureStreams(camera3_stream_configuration *streamList); - - virtual status_t registerStreamBuffers( - const camera3_stream_buffer_set *bufferSet); - - virtual const camera_metadata_t *constructDefaultRequestSettings(int type); - - virtual status_t processCaptureRequest(camera3_capture_request *request); - - virtual status_t flush(); - - /** Debug methods */ - - virtual void dump(int fd); - - private: - /** - * Get the requested capability set for this camera - */ - status_t getCameraCapabilities(); - - bool hasCapability(AvailableCapabilities cap); - - /** - * Build the static info metadata buffer for this device - */ - status_t constructStaticInfo(const cvd::CameraDefinition ¶ms); - - /** - * Run the fake 3A algorithms as needed. May override/modify settings - * values. - */ - status_t process3A(CameraMetadata &settings); - - status_t doFakeAE(CameraMetadata &settings); - status_t doFakeAF(CameraMetadata &settings); - status_t doFakeAWB(CameraMetadata &settings); - void update3A(CameraMetadata &settings); - - /** Signal from readout thread that it doesn't have anything to do */ - void signalReadoutIdle(); - - /** Handle interrupt events from the sensor */ - void onSensorEvent(uint32_t frameNumber, Event e, nsecs_t timestamp); - - /**************************************************************************** - * Static configuration information - ***************************************************************************/ - private: - static const uint32_t kMaxRawStreamCount = 1; - static const uint32_t kMaxProcessedStreamCount = 3; - static const uint32_t kMaxJpegStreamCount = 1; - static const uint32_t kMaxReprocessStreamCount = 2; - static const uint32_t kMaxBufferCount = 4; - // We need a positive stream ID to distinguish external buffers from - // sensor-generated buffers which use a nonpositive ID. Otherwise, HAL3 has - // no concept of a stream id. - static const uint32_t kGenericStreamId = 1; - static const int32_t kAvailableFormats[]; - - static const int64_t kSyncWaitTimeout = 10000000; // 10 ms - static const int32_t kMaxSyncTimeoutCount = 1000; // 1000 kSyncWaitTimeouts - static const uint32_t kFenceTimeoutMs = 2000; // 2 s - static const nsecs_t kJpegTimeoutNs = 5000000000l; // 5 s - - /**************************************************************************** - * Data members. - ***************************************************************************/ - - /* HAL interface serialization lock. */ - Mutex mLock; - - /* Facing back (true) or front (false) switch. */ - bool mFacingBack; - int32_t mSensorWidth; - int32_t mSensorHeight; - - SortedVector<AvailableCapabilities> mCapabilities; - - /** - * Cache for default templates. Once one is requested, the pointer must be - * valid at least until close() is called on the device - */ - camera_metadata_t *mDefaultTemplates[CAMERA3_TEMPLATE_COUNT]; - - /** - * Private stream information, stored in camera3_stream_t->priv. - */ - struct PrivateStreamInfo { - bool alive; - }; - - // Shortcut to the input stream - camera3_stream_t *mInputStream; - - typedef List<camera3_stream_t *> StreamList; - typedef List<camera3_stream_t *>::iterator StreamIterator; - typedef Vector<camera3_stream_buffer> HalBufferVector; - - // All streams, including input stream - StreamList mStreams; - - // Cached settings from latest submitted request - CameraMetadata mPrevSettings; - - /** Fake hardware interfaces */ - sp<Sensor> mSensor; - sp<JpegCompressor> mJpegCompressor; - friend class JpegCompressor; - - /** Processing thread for sending out results */ - - class ReadoutThread : public Thread, private JpegCompressor::JpegListener { - public: - ReadoutThread(EmulatedFakeCamera3 *parent); - ~ReadoutThread(); - - struct Request { - uint32_t frameNumber; - CameraMetadata settings; - HalBufferVector *buffers; - Buffers *sensorBuffers; - }; - - /** - * Interface to parent class - */ - - // Place request in the in-flight queue to wait for sensor capture - void queueCaptureRequest(const Request &r); - - // Test if the readout thread is idle (no in-flight requests, not - // currently reading out anything - bool isIdle(); - - // Wait until isIdle is true - status_t waitForReadout(); - - private: - static const nsecs_t kWaitPerLoop = 10000000L; // 10 ms - static const nsecs_t kMaxWaitLoops = 1000; - static const size_t kMaxQueueSize = 2; - - EmulatedFakeCamera3 *mParent; - Mutex mLock; - - List<Request> mInFlightQueue; - Condition mInFlightSignal; - bool mThreadActive; - - virtual bool threadLoop(); - - // Only accessed by threadLoop - - Request mCurrentRequest; - - // Jpeg completion callbacks - - Mutex mJpegLock; - bool mJpegWaiting; - camera3_stream_buffer mJpegHalBuffer; - uint32_t mJpegFrameNumber; - virtual void onJpegDone(const StreamBuffer &jpegBuffer, bool success); - virtual void onJpegInputDone(const StreamBuffer &inputBuffer); - }; - - sp<ReadoutThread> mReadoutThread; - - /** Fake 3A constants */ - - static const nsecs_t kNormalExposureTime; - static const nsecs_t kFacePriorityExposureTime; - static const int kNormalSensitivity; - static const int kFacePrioritySensitivity; - // Rate of converging AE to new target value, as fraction of difference - // between current and target value. - static const float kExposureTrackRate; - // Minimum duration for precapture state. May be longer if slow to converge - // to target exposure - static const int kPrecaptureMinFrames; - // How often to restart AE 'scanning' - static const int kStableAeMaxFrames; - // Maximum stop below 'normal' exposure time that we'll wander to while - // pretending to converge AE. In powers of 2. (-2 == 1/4 as bright) - static const float kExposureWanderMin; - // Maximum stop above 'normal' exposure time that we'll wander to while - // pretending to converge AE. In powers of 2. (2 == 4x as bright) - static const float kExposureWanderMax; - - /** Fake 3A state */ - - uint8_t mControlMode; - bool mFacePriority; - uint8_t mAeState; - uint8_t mAfState; - uint8_t mAwbState; - uint8_t mAeMode; - uint8_t mAfMode; - uint8_t mAwbMode; - - int mAeCounter; - nsecs_t mAeCurrentExposureTime; - nsecs_t mAeTargetExposureTime; - int mAeCurrentSensitivity; -}; - -} // namespace android - -#endif // HW_EMULATOR_CAMERA_EMULATED_CAMERA3_H diff --git a/guest/hals/camera/EmulatedFakeCameraDevice.cpp b/guest/hals/camera/EmulatedFakeCameraDevice.cpp deleted file mode 100644 index a354e690..00000000 --- a/guest/hals/camera/EmulatedFakeCameraDevice.cpp +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedFakeCameraDevice that encapsulates - * fake camera device. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_FakeDevice" -#include "EmulatedFakeCameraDevice.h" -#include <log/log.h> -#include "EmulatedFakeCamera.h" - -namespace android { - -EmulatedFakeCameraDevice::EmulatedFakeCameraDevice( - EmulatedFakeCamera* camera_hal) - : EmulatedCameraDevice(camera_hal), - mBlackYUV(kBlack32), - mWhiteYUV(kWhite32), - mRedYUV(kRed8), - mGreenYUV(kGreen8), - mBlueYUV(kBlue8), - mLastRedrawn(0), - mCheckX(0), - mCheckY(0), - mCcounter(0) -#if EFCD_ROTATE_FRAME - , - mLastRotatedAt(0), - mCurrentFrameType(0), - mCurrentColor(&mWhiteYUV) -#endif // EFCD_ROTATE_FRAME -{ - // Makes the image with the original exposure compensation darker. - // So the effects of changing the exposure compensation can be seen. - mBlackYUV.Y = mBlackYUV.Y / 2; - mWhiteYUV.Y = mWhiteYUV.Y / 2; - mRedYUV.Y = mRedYUV.Y / 2; - mGreenYUV.Y = mGreenYUV.Y / 2; - mBlueYUV.Y = mBlueYUV.Y / 2; -} - -EmulatedFakeCameraDevice::~EmulatedFakeCameraDevice() {} - -/**************************************************************************** - * Emulated camera device abstract interface implementation. - ***************************************************************************/ - -status_t EmulatedFakeCameraDevice::connectDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isInitialized()) { - ALOGE("%s: Fake camera device is not initialized.", __FUNCTION__); - return EINVAL; - } - if (isConnected()) { - ALOGW("%s: Fake camera device is already connected.", __FUNCTION__); - return NO_ERROR; - } - - /* There is no device to connect to. */ - mState = ECDS_CONNECTED; - - return NO_ERROR; -} - -status_t EmulatedFakeCameraDevice::disconnectDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isConnected()) { - ALOGW("%s: Fake camera device is already disconnected.", __FUNCTION__); - return NO_ERROR; - } - if (isStarted()) { - ALOGE("%s: Cannot disconnect from the started device.", __FUNCTION__); - return EINVAL; - } - - /* There is no device to disconnect from. */ - mState = ECDS_INITIALIZED; - - return NO_ERROR; -} - -status_t EmulatedFakeCameraDevice::startDevice(int width, int height, - uint32_t pix_fmt, int fps) { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isConnected()) { - ALOGE("%s: Fake camera device is not connected.", __FUNCTION__); - return EINVAL; - } - if (isStarted()) { - ALOGE("%s: Fake camera device is already started.", __FUNCTION__); - return EINVAL; - } - - /* Initialize the base class. */ - const status_t res = - EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt, fps); - if (res == NO_ERROR) { - /* Calculate U/V panes inside the framebuffer. */ - switch (mPixelFormat) { - case V4L2_PIX_FMT_YVU420: - mFrameV = mCurrentFrame + mTotalPixels; - mFrameU = mFrameU + mTotalPixels / 4; - mUVStep = 1; - mUVTotalNum = mTotalPixels / 4; - break; - - case V4L2_PIX_FMT_YUV420: - mFrameU = mCurrentFrame + mTotalPixels; - mFrameV = mFrameU + mTotalPixels / 4; - mUVStep = 1; - mUVTotalNum = mTotalPixels / 4; - break; - - case V4L2_PIX_FMT_NV21: - /* Interleaved UV pane, V first. */ - mFrameV = mCurrentFrame + mTotalPixels; - mFrameU = mFrameV + 1; - mUVStep = 2; - mUVTotalNum = mTotalPixels / 4; - break; - - case V4L2_PIX_FMT_NV12: - /* Interleaved UV pane, U first. */ - mFrameU = mCurrentFrame + mTotalPixels; - mFrameV = mFrameU + 1; - mUVStep = 2; - mUVTotalNum = mTotalPixels / 4; - break; - - default: - ALOGE("%s: Unknown pixel format %.4s", __FUNCTION__, - reinterpret_cast<const char*>(&mPixelFormat)); - return EINVAL; - } - /* Number of items in a single row inside U/V panes. */ - mUVInRow = (width / 2) * mUVStep; - mState = ECDS_STARTED; - mCurFrameTimestamp = 0; - } else { - ALOGE("%s: commonStartDevice failed", __FUNCTION__); - } - - return res; -} - -status_t EmulatedFakeCameraDevice::stopDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isStarted()) { - ALOGW("%s: Fake camera device is not started.", __FUNCTION__); - return NO_ERROR; - } - - mFrameU = mFrameV = NULL; - EmulatedCameraDevice::commonStopDevice(); - mState = ECDS_CONNECTED; - - return NO_ERROR; -} - -/**************************************************************************** - * Worker thread management overrides. - ***************************************************************************/ - -bool EmulatedFakeCameraDevice::inWorkerThread() { - /* Wait till FPS timeout expires, or thread exit message is received. */ - WorkerThread::SelectRes res = - getWorkerThread()->Select(-1, 1000000 / (mTargetFps / 1000)); - if (res == WorkerThread::EXIT_THREAD) { - ALOGV("%s: Worker thread has been terminated.", __FUNCTION__); - return false; - } - - /* Lets see if we need to generate a new frame. */ - if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRedrawn) >= mRedrawAfter) { - /* - * Time to generate a new frame. - */ - -#if EFCD_ROTATE_FRAME - const int frame_type = rotateFrame(); - switch (frame_type) { - case 0: - drawCheckerboard(); - break; - case 1: - drawStripes(); - break; - case 2: - drawSolid(mCurrentColor); - break; - } -#else - /* Draw the checker board. */ - drawCheckerboard(); - -#endif // EFCD_ROTATE_FRAME - - // mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); - mCurFrameTimestamp += (1000000000 / (mTargetFps / 1000)); - /* Timestamp the current frame, and notify the camera HAL about new frame. - */ - mLastRedrawn = systemTime(SYSTEM_TIME_MONOTONIC); - mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this); - } - - return true; -} - -/**************************************************************************** - * Fake camera device private API - ***************************************************************************/ - -void EmulatedFakeCameraDevice::drawCheckerboard() { - const int size = mFrameWidth / 10; - bool black = true; - - if (size == 0) { - // When this happens, it happens at a very high rate, - // so don't log any messages and just return. - return; - } - - if ((mCheckX / size) & 1) black = false; - if ((mCheckY / size) & 1) black = !black; - - int county = mCheckY % size; - int checkxremainder = mCheckX % size; - uint8_t* Y = mCurrentFrame; - uint8_t* U_pos = mFrameU; - uint8_t* V_pos = mFrameV; - uint8_t* U = U_pos; - uint8_t* V = V_pos; - - YUVPixel adjustedWhite = YUVPixel(mWhiteYUV); - changeWhiteBalance(adjustedWhite.Y, adjustedWhite.U, adjustedWhite.V); - - for (int y = 0; y < mFrameHeight; y++) { - int countx = checkxremainder; - bool current = black; - for (int x = 0; x < mFrameWidth; x += 2) { - if (current) { - mBlackYUV.get(Y, U, V); - } else { - adjustedWhite.get(Y, U, V); - } - *Y = changeExposure(*Y); - Y[1] = *Y; - Y += 2; - U += mUVStep; - V += mUVStep; - countx += 2; - if (countx >= size) { - countx = 0; - current = !current; - } - } - if (y & 0x1) { - U_pos = U; - V_pos = V; - } else { - U = U_pos; - V = V_pos; - } - if (county++ >= size) { - county = 0; - black = !black; - } - } - mCheckX += 3; - mCheckY++; - - /* Run the square. */ - int sqx = ((mCcounter * 3) & 255); - if (sqx > 128) sqx = 255 - sqx; - int sqy = ((mCcounter * 5) & 255); - if (sqy > 128) sqy = 255 - sqy; - const int sqsize = mFrameWidth / 10; - drawSquare(sqx * sqsize / 32, sqy * sqsize / 32, (sqsize * 5) >> 1, - (mCcounter & 0x100) ? &mRedYUV : &mGreenYUV); - mCcounter++; -} - -void EmulatedFakeCameraDevice::drawSquare(int x, int y, int size, - const YUVPixel* color) { - const int square_xstop = std::min(mFrameWidth, x + size); - const int square_ystop = std::min(mFrameHeight, y + size); - uint8_t* Y_pos = mCurrentFrame + y * mFrameWidth + x; - - YUVPixel adjustedColor = *color; - changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); - - // Draw the square. - for (; y < square_ystop; y++) { - const int iUV = (y / 2) * mUVInRow + (x / 2) * mUVStep; - uint8_t* sqU = mFrameU + iUV; - uint8_t* sqV = mFrameV + iUV; - uint8_t* sqY = Y_pos; - for (int i = x; i < square_xstop; i += 2) { - adjustedColor.get(sqY, sqU, sqV); - *sqY = changeExposure(*sqY); - sqY[1] = *sqY; - sqY += 2; - sqU += mUVStep; - sqV += mUVStep; - } - Y_pos += mFrameWidth; - } -} - -#if EFCD_ROTATE_FRAME - -void EmulatedFakeCameraDevice::drawSolid(YUVPixel* color) { - YUVPixel adjustedColor = *color; - changeWhiteBalance(adjustedColor.Y, adjustedColor.U, adjustedColor.V); - - /* All Ys are the same. */ - memset(mCurrentFrame, changeExposure(adjustedColor.Y), mTotalPixels); - - /* Fill U, and V panes. */ - uint8_t* U = mFrameU; - uint8_t* V = mFrameV; - for (int k = 0; k < mUVTotalNum; k++, U += mUVStep, V += mUVStep) { - *U = color->U; - *V = color->V; - } -} - -void EmulatedFakeCameraDevice::drawStripes() { - /* Divide frame into 4 stripes. */ - const int change_color_at = mFrameHeight / 4; - const int each_in_row = mUVInRow / mUVStep; - uint8_t* pY = mCurrentFrame; - for (int y = 0; y < mFrameHeight; y++, pY += mFrameWidth) { - /* Select the color. */ - YUVPixel* color; - const int color_index = y / change_color_at; - if (color_index == 0) { - /* White stripe on top. */ - color = &mWhiteYUV; - } else if (color_index == 1) { - /* Then the red stripe. */ - color = &mRedYUV; - } else if (color_index == 2) { - /* Then the green stripe. */ - color = &mGreenYUV; - } else { - /* And the blue stripe at the bottom. */ - color = &mBlueYUV; - } - changeWhiteBalance(color->Y, color->U, color->V); - - /* All Ys at the row are the same. */ - memset(pY, changeExposure(color->Y), mFrameWidth); - - /* Offset of the current row inside U/V panes. */ - const int uv_off = (y / 2) * mUVInRow; - /* Fill U, and V panes. */ - uint8_t* U = mFrameU + uv_off; - uint8_t* V = mFrameV + uv_off; - for (int k = 0; k < each_in_row; k++, U += mUVStep, V += mUVStep) { - *U = color->U; - *V = color->V; - } - } -} - -int EmulatedFakeCameraDevice::rotateFrame() { - if ((systemTime(SYSTEM_TIME_MONOTONIC) - mLastRotatedAt) >= mRotateFreq) { - mLastRotatedAt = systemTime(SYSTEM_TIME_MONOTONIC); - mCurrentFrameType++; - if (mCurrentFrameType > 2) { - mCurrentFrameType = 0; - } - if (mCurrentFrameType == 2) { - ALOGD("********** Rotated to the SOLID COLOR frame **********"); - /* Solid color: lets rotate color too. */ - if (mCurrentColor == &mWhiteYUV) { - ALOGD("----- Painting a solid RED frame -----"); - mCurrentColor = &mRedYUV; - } else if (mCurrentColor == &mRedYUV) { - ALOGD("----- Painting a solid GREEN frame -----"); - mCurrentColor = &mGreenYUV; - } else if (mCurrentColor == &mGreenYUV) { - ALOGD("----- Painting a solid BLUE frame -----"); - mCurrentColor = &mBlueYUV; - } else { - /* Back to white. */ - ALOGD("----- Painting a solid WHITE frame -----"); - mCurrentColor = &mWhiteYUV; - } - } else if (mCurrentFrameType == 0) { - ALOGD("********** Rotated to the CHECKERBOARD frame **********"); - } else if (mCurrentFrameType == 1) { - ALOGD("********** Rotated to the STRIPED frame **********"); - } - } - - return mCurrentFrameType; -} - -#endif // EFCD_ROTATE_FRAME - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedFakeCameraDevice.h b/guest/hals/camera/EmulatedFakeCameraDevice.h deleted file mode 100644 index 096d1bc5..00000000 --- a/guest/hals/camera/EmulatedFakeCameraDevice.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H -#define HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H - -/* - * Contains declaration of a class EmulatedFakeCameraDevice that encapsulates - * a fake camera device. - */ - -#include "Converters.h" -#include "EmulatedCameraDevice.h" - -/* This is used for debugging format / conversion issues. If EFCD_ROTATE_FRAME - * is set to 0, the frame content will be always the "checkerboard". Otherwise, - * if EFCD_ROTATE_FRAME is set to a non-zero value, the frame content will - * "rotate" from a "checkerboard" frame to a "white/red/green/blue stripes" - * frame, to a "white/red/green/blue" frame. Frame content rotation helps - * finding bugs in format conversions. - */ -#define EFCD_ROTATE_FRAME 0 - -namespace android { - -class EmulatedFakeCamera; - -/* Encapsulates a fake camera device. - * Fake camera device emulates a camera device by providing frames containing - * a black and white checker board, moving diagonally towards the 0,0 corner. - * There is also a green, or red square that bounces inside the frame, changing - * its color when bouncing off the 0,0 corner. - */ -class EmulatedFakeCameraDevice : public EmulatedCameraDevice { - public: - /* Constructs EmulatedFakeCameraDevice instance. */ - explicit EmulatedFakeCameraDevice(EmulatedFakeCamera* camera_hal); - - /* Destructs EmulatedFakeCameraDevice instance. */ - ~EmulatedFakeCameraDevice(); - - /*************************************************************************** - * Emulated camera device abstract interface implementation. - * See declarations of these methods in EmulatedCameraDevice class for - * information on each of these methods. - **************************************************************************/ - - public: - /* Connects to the camera device. - * Since there is no real device to connect to, this method does nothing, - * but changes the state. - */ - status_t connectDevice(); - - /* Disconnects from the camera device. - * Since there is no real device to disconnect from, this method does - * nothing, but changes the state. - */ - status_t disconnectDevice(); - - /* Starts the camera device. */ - status_t startDevice(int width, int height, uint32_t pix_fmt, int fps); - - /* Stops the camera device. */ - status_t stopDevice(); - - /* Gets current preview fame into provided buffer. */ - status_t getPreviewFrame(void* /*buffer*/) { return OK; } - - /*************************************************************************** - * Worker thread management overrides. - * See declarations of these methods in EmulatedCameraDevice class for - * information on each of these methods. - **************************************************************************/ - - protected: - /* Implementation of the worker thread routine. - * This method simply sleeps for a period of time defined by the FPS property - * of the fake camera (simulating frame frequency), and then calls emulated - * camera's onNextFrameAvailable method. - */ - bool inWorkerThread(); - - /**************************************************************************** - * Fake camera device private API - ***************************************************************************/ - - private: - /* Draws a black and white checker board in the current frame buffer. */ - void drawCheckerboard(); - - /* Draws a square of the given color in the current frame buffer. - * Param: - * x, y - Coordinates of the top left corner of the square in the buffer. - * size - Size of the square's side. - * color - Square's color. - */ - void drawSquare(int x, int y, int size, const YUVPixel* color); - -#if EFCD_ROTATE_FRAME - void drawSolid(YUVPixel* color); - void drawStripes(); - int rotateFrame(); -#endif // EFCD_ROTATE_FRAME - - /**************************************************************************** - * Fake camera device data members - ***************************************************************************/ - - private: - /* - * Pixel colors in YUV format used when drawing the checker board. - */ - - YUVPixel mBlackYUV; - YUVPixel mWhiteYUV; - YUVPixel mRedYUV; - YUVPixel mGreenYUV; - YUVPixel mBlueYUV; - - /* Last time the frame has been redrawn. */ - nsecs_t mLastRedrawn; - - /* - * Precalculated values related to U/V panes. - */ - - /* U pane inside the framebuffer. */ - uint8_t* mFrameU; - - /* V pane inside the framebuffer. */ - uint8_t* mFrameV; - - /* Defines byte distance between adjacent U, and V values. */ - int mUVStep; - - /* Defines number of Us and Vs in a row inside the U/V panes. - * Note that if U/V panes are interleaved, this value reflects the total - * number of both, Us and Vs in a single row in the interleaved UV pane. */ - int mUVInRow; - - /* Total number of each, U, and V elements in the framebuffer. */ - int mUVTotalNum; - - /* - * Checkerboard drawing related stuff - */ - - int mCheckX; - int mCheckY; - int mCcounter; - - /* Defines time (in nanoseconds) between redrawing the checker board. - * We will redraw the checker board every 15 milliseconds. */ - static const nsecs_t mRedrawAfter = 15000000LL; - -#if EFCD_ROTATE_FRAME - /* Frame rotation frequency in nanosec (currently - 3 sec) */ - static const nsecs_t mRotateFreq = 3000000000LL; - - /* Last time the frame has rotated. */ - nsecs_t mLastRotatedAt; - - /* Type of the frame to display in the current rotation: - * 0 - Checkerboard. - * 1 - White/Red/Green/Blue horisontal stripes - * 2 - Solid color. */ - int mCurrentFrameType; - - /* Color to use to paint the solid color frame. Colors will rotate between - * white, red, gree, and blue each time rotation comes to the solid color - * frame. */ - YUVPixel* mCurrentColor; -#endif // EFCD_ROTATE_FRAME -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_FAKE_CAMERA_DEVICE_H */ diff --git a/guest/hals/camera/EmulatedQemuCamera.cpp b/guest/hals/camera/EmulatedQemuCamera.cpp deleted file mode 100644 index 99c4797e..00000000 --- a/guest/hals/camera/EmulatedQemuCamera.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedQemuCamera that encapsulates - * functionality of an emulated camera connected to the host. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_QemuCamera" -#include "EmulatedQemuCamera.h" -#include <log/log.h> -#include "EmulatedCameraFactory.h" - -namespace android { - -EmulatedQemuCamera::EmulatedQemuCamera(int cameraId, struct hw_module_t* module) - : EmulatedCamera(cameraId, module), mQemuCameraDevice(this) {} - -EmulatedQemuCamera::~EmulatedQemuCamera() {} - -/**************************************************************************** - * EmulatedCamera virtual overrides. - ***************************************************************************/ - -status_t EmulatedQemuCamera::Initialize(const char* device_name, - const char* frame_dims, - const char* facing_dir) { - ALOGV("%s:\n Name=%s\n Facing '%s'\n Dimensions=%s", __FUNCTION__, - device_name, facing_dir, frame_dims); - /* Save dimensions. */ - mFrameDims = frame_dims; - - /* Initialize camera device. */ - status_t res = mQemuCameraDevice.Initialize(device_name); - if (res != NO_ERROR) { - return res; - } - - /* Initialize base class. */ - res = EmulatedCamera::Initialize(); - if (res != NO_ERROR) { - return res; - } - - /* - * Set customizable parameters. - */ - - mParameters.set(EmulatedCamera::FACING_KEY, facing_dir); - mParameters.set(EmulatedCamera::ORIENTATION_KEY, - gEmulatedCameraFactory.getQemuCameraOrientation()); - mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, frame_dims); - mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, frame_dims); - - /* - * Use first dimension reported by the device to set current preview and - * picture sizes. - */ - - char first_dim[128]; - /* Dimensions are separated with ',' */ - const char* c = strchr(frame_dims, ','); - if (c == NULL) { - strncpy(first_dim, frame_dims, sizeof(first_dim)); - first_dim[sizeof(first_dim) - 1] = '\0'; - } else if (static_cast<size_t>(c - frame_dims) < sizeof(first_dim)) { - memcpy(first_dim, frame_dims, c - frame_dims); - first_dim[c - frame_dims] = '\0'; - } else { - memcpy(first_dim, frame_dims, sizeof(first_dim)); - first_dim[sizeof(first_dim) - 1] = '\0'; - } - - /* Width and height are separated with 'x' */ - char* sep = strchr(first_dim, 'x'); - if (sep == NULL) { - ALOGE("%s: Invalid first dimension format in %s", __FUNCTION__, frame_dims); - return EINVAL; - } - - *sep = '\0'; - const int x = atoi(first_dim); - const int y = atoi(sep + 1); - mParameters.setPreviewSize(x, y); - mParameters.setPictureSize(x, y); - - ALOGV("%s: Qemu camera %s is initialized. Current frame is %dx%d", - __FUNCTION__, device_name, x, y); - - return NO_ERROR; -} - -EmulatedCameraDevice* EmulatedQemuCamera::getCameraDevice() { - return &mQemuCameraDevice; -} - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedQemuCamera.h b/guest/hals/camera/EmulatedQemuCamera.h deleted file mode 100644 index fe063bfb..00000000 --- a/guest/hals/camera/EmulatedQemuCamera.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H -#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H - -/* - * Contains declaration of a class EmulatedQemuCamera that encapsulates - * functionality of an emulated camera connected to the host. - */ - -#include "EmulatedCamera.h" -#include "EmulatedQemuCameraDevice.h" - -namespace android { - -/* Encapsulates functionality of an emulated camera connected to the host. - */ -class EmulatedQemuCamera : public EmulatedCamera { - public: - /* Constructs EmulatedQemuCamera instance. */ - EmulatedQemuCamera(int cameraId, struct hw_module_t* module); - - /* Destructs EmulatedQemuCamera instance. */ - ~EmulatedQemuCamera(); - - /*************************************************************************** - * EmulatedCamera virtual overrides. - **************************************************************************/ - - public: - /* Initializes EmulatedQemuCamera instance. */ - status_t Initialize(const char* device_name, const char* frame_dims, - const char* facing_dir); - - /*************************************************************************** - * EmulatedCamera abstract API implementation. - **************************************************************************/ - - protected: - /* Gets emulated camera device ised by this instance of the emulated camera. - */ - EmulatedCameraDevice* getCameraDevice(); - - /*************************************************************************** - * Data memebers. - **************************************************************************/ - - protected: - /* Contained qemu camera device object. */ - EmulatedQemuCameraDevice mQemuCameraDevice; - - /* Supported frame dimensions reported by the camera device. */ - String8 mFrameDims; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_H */ diff --git a/guest/hals/camera/EmulatedQemuCamera2.cpp b/guest/hals/camera/EmulatedQemuCamera2.cpp deleted file mode 100644 index cf894fd1..00000000 --- a/guest/hals/camera/EmulatedQemuCamera2.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/* - * Contains implementation of a class EmulatedQemuCamera2 that encapsulates - * functionality of a host webcam with further processing to simulate the - * capabilities of a v2 camera device. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_QemuCamera2" -#include "EmulatedQemuCamera2.h" -#include <log/log.h> -#include <cutils/properties.h> -#include "EmulatedCameraFactory.h" - -namespace android { - -EmulatedQemuCamera2::EmulatedQemuCamera2(int cameraId, bool facingBack, - struct hw_module_t* module) - : EmulatedCamera2(cameraId, module), mFacingBack(facingBack) { - ALOGD("Constructing emulated qemu camera 2 facing %s", - facingBack ? "back" : "front"); -} - -EmulatedQemuCamera2::~EmulatedQemuCamera2() {} - -/**************************************************************************** - * Public API overrides - ***************************************************************************/ - -status_t EmulatedQemuCamera2::Initialize() { return NO_ERROR; } - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedQemuCamera2.h b/guest/hals/camera/EmulatedQemuCamera2.h deleted file mode 100644 index 7697c0ee..00000000 --- a/guest/hals/camera/EmulatedQemuCamera2.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H -#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H - -/* - * Contains declaration of a class EmulatedQemuCamera2 that encapsulates - * functionality of a host webcam with added processing to implement version 2 - * of the camera device interface. - */ - -#include "EmulatedCamera2.h" - -namespace android { - -/* Encapsulates functionality of an advanced fake camera based on real host - * camera data. - */ -class EmulatedQemuCamera2 : public EmulatedCamera2 { - public: - /* Constructs EmulatedFakeCamera instance. */ - EmulatedQemuCamera2(int cameraId, bool facingBack, - struct hw_module_t* module); - - /* Destructs EmulatedFakeCamera instance. */ - ~EmulatedQemuCamera2(); - - /**************************************************************************** - * EmulatedCamera2 virtual overrides. - ***************************************************************************/ - - public: - /* Initializes EmulatedQemuCamera2 instance. */ - status_t Initialize(); - - /**************************************************************************** - * EmulatedCamera abstract API implementation. - ***************************************************************************/ - - protected: - /**************************************************************************** - * Data memebers. - ***************************************************************************/ - - protected: - /* Facing back (true) or front (false) switch. */ - bool mFacingBack; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA2_H */ diff --git a/guest/hals/camera/EmulatedQemuCameraDevice.cpp b/guest/hals/camera/EmulatedQemuCameraDevice.cpp deleted file mode 100644 index 61291e8c..00000000 --- a/guest/hals/camera/EmulatedQemuCameraDevice.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class EmulatedQemuCameraDevice that encapsulates - * an emulated camera device connected to the host. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_QemuDevice" -#include "EmulatedQemuCameraDevice.h" -#include <log/log.h> -#include "EmulatedQemuCamera.h" - -namespace android { - -EmulatedQemuCameraDevice::EmulatedQemuCameraDevice( - EmulatedQemuCamera* camera_hal) - : EmulatedCameraDevice(camera_hal), mQemuClient(), mPreviewFrame(NULL) {} - -EmulatedQemuCameraDevice::~EmulatedQemuCameraDevice() { - if (mPreviewFrame != NULL) { - delete[] mPreviewFrame; - } -} - -/**************************************************************************** - * Public API - ***************************************************************************/ - -status_t EmulatedQemuCameraDevice::Initialize(const char* device_name) { - /* Connect to the service. */ - char connect_str[256]; - snprintf(connect_str, sizeof(connect_str), "name=%s", device_name); - status_t res = mQemuClient.connectClient(connect_str); - if (res != NO_ERROR) { - return res; - } - - /* Initialize base class. */ - res = EmulatedCameraDevice::Initialize(); - if (res == NO_ERROR) { - ALOGV("%s: Connected to the emulated camera service '%s'", __FUNCTION__, - device_name); - mDeviceName = device_name; - } else { - mQemuClient.queryDisconnect(); - } - - return res; -} - -/**************************************************************************** - * Emulated camera device abstract interface implementation. - ***************************************************************************/ - -status_t EmulatedQemuCameraDevice::connectDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isInitialized()) { - ALOGE("%s: Qemu camera device is not initialized.", __FUNCTION__); - return EINVAL; - } - if (isConnected()) { - ALOGW("%s: Qemu camera device '%s' is already connected.", __FUNCTION__, - (const char*)mDeviceName); - return NO_ERROR; - } - - /* Connect to the camera device via emulator. */ - const status_t res = mQemuClient.queryConnect(); - if (res == NO_ERROR) { - ALOGV("%s: Connected to device '%s'", __FUNCTION__, - (const char*)mDeviceName); - mState = ECDS_CONNECTED; - } else { - ALOGE("%s: Connection to device '%s' failed", __FUNCTION__, - (const char*)mDeviceName); - } - - return res; -} - -status_t EmulatedQemuCameraDevice::disconnectDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isConnected()) { - ALOGW("%s: Qemu camera device '%s' is already disconnected.", __FUNCTION__, - (const char*)mDeviceName); - return NO_ERROR; - } - if (isStarted()) { - ALOGE("%s: Cannot disconnect from the started device '%s.", __FUNCTION__, - (const char*)mDeviceName); - return EINVAL; - } - - /* Disconnect from the camera device via emulator. */ - const status_t res = mQemuClient.queryDisconnect(); - if (res == NO_ERROR) { - ALOGV("%s: Disonnected from device '%s'", __FUNCTION__, - (const char*)mDeviceName); - mState = ECDS_INITIALIZED; - } else { - ALOGE("%s: Disconnection from device '%s' failed", __FUNCTION__, - (const char*)mDeviceName); - } - - return res; -} - -status_t EmulatedQemuCameraDevice::startDevice(int width, int height, - uint32_t pix_fmt, int fps) { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isConnected()) { - ALOGE("%s: Qemu camera device '%s' is not connected.", __FUNCTION__, - (const char*)mDeviceName); - return EINVAL; - } - if (isStarted()) { - ALOGW("%s: Qemu camera device '%s' is already started.", __FUNCTION__, - (const char*)mDeviceName); - return NO_ERROR; - } - - status_t res = - EmulatedCameraDevice::commonStartDevice(width, height, pix_fmt, fps); - if (res != NO_ERROR) { - ALOGE("%s: commonStartDevice failed", __FUNCTION__); - return res; - } - - /* Allocate preview frame buffer. */ - /* TODO: Watch out for preview format changes! At this point we implement - * RGB32 only.*/ - mPreviewFrame = new uint32_t[mTotalPixels]; - if (mPreviewFrame == NULL) { - ALOGE("%s: Unable to allocate %d bytes for preview frame", __FUNCTION__, - mTotalPixels); - return ENOMEM; - } - - /* Start the actual camera device. */ - res = mQemuClient.queryStart(mPixelFormat, mFrameWidth, mFrameHeight); - if (res == NO_ERROR) { - ALOGV("%s: Qemu camera device '%s' is started for %.4s[%dx%d] frames", - __FUNCTION__, (const char*)mDeviceName, - reinterpret_cast<const char*>(&mPixelFormat), mFrameWidth, - mFrameHeight); - mState = ECDS_STARTED; - } else { - ALOGE("%s: Unable to start device '%s' for %.4s[%dx%d] frames", - __FUNCTION__, (const char*)mDeviceName, - reinterpret_cast<const char*>(&pix_fmt), width, height); - } - - return res; -} - -status_t EmulatedQemuCameraDevice::stopDevice() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - if (!isStarted()) { - ALOGW("%s: Qemu camera device '%s' is not started.", __FUNCTION__, - (const char*)mDeviceName); - return NO_ERROR; - } - - /* Stop the actual camera device. */ - status_t res = mQemuClient.queryStop(); - if (res == NO_ERROR) { - if (mPreviewFrame == NULL) { - delete[] mPreviewFrame; - mPreviewFrame = NULL; - } - EmulatedCameraDevice::commonStopDevice(); - mState = ECDS_CONNECTED; - ALOGV("%s: Qemu camera device '%s' is stopped", __FUNCTION__, - (const char*)mDeviceName); - } else { - ALOGE("%s: Unable to stop device '%s'", __FUNCTION__, - (const char*)mDeviceName); - } - - return res; -} - -/**************************************************************************** - * EmulatedCameraDevice virtual overrides - ***************************************************************************/ - -status_t EmulatedQemuCameraDevice::getCurrentPreviewFrame(void* buffer) { - ALOGW_IF(mPreviewFrame == NULL, "%s: No preview frame", __FUNCTION__); - if (mPreviewFrame != NULL) { - memcpy(buffer, mPreviewFrame, mTotalPixels * 4); - return 0; - } else { - return EmulatedCameraDevice::getCurrentPreviewFrame(buffer); - } -} - -/**************************************************************************** - * Worker thread management overrides. - ***************************************************************************/ - -bool EmulatedQemuCameraDevice::inWorkerThread() { - /* Wait till FPS timeout expires, or thread exit message is received. */ - WorkerThread::SelectRes res = - getWorkerThread()->Select(-1, 1000000 / mEmulatedFPS); - if (res == WorkerThread::EXIT_THREAD) { - ALOGV("%s: Worker thread has been terminated.", __FUNCTION__); - return false; - } - - /* Query frames from the service. */ - status_t query_res = mQemuClient.queryFrame( - mCurrentFrame, mPreviewFrame, mFrameBufferSize, mTotalPixels * 4, - mWhiteBalanceScale[0], mWhiteBalanceScale[1], mWhiteBalanceScale[2], - mExposureCompensation); - if (query_res == NO_ERROR) { - /* Timestamp the current frame, and notify the camera HAL. */ - mCurFrameTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); - mCameraHAL->onNextFrameAvailable(mCurrentFrame, mCurFrameTimestamp, this); - return true; - } else { - ALOGE("%s: Unable to get current video frame: %s", __FUNCTION__, - strerror(query_res)); - mCameraHAL->onCameraDeviceError(CAMERA_ERROR_SERVER_DIED); - return false; - } -} - -}; /* namespace android */ diff --git a/guest/hals/camera/EmulatedQemuCameraDevice.h b/guest/hals/camera/EmulatedQemuCameraDevice.h deleted file mode 100644 index 2e4770b4..00000000 --- a/guest/hals/camera/EmulatedQemuCameraDevice.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H -#define HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H - -/* - * Contains declaration of a class EmulatedQemuCameraDevice that encapsulates - * an emulated camera device connected to the host. - */ - -#include "EmulatedCameraDevice.h" -#include "QemuClient.h" - -namespace android { - -class EmulatedQemuCamera; - -/* Encapsulates an emulated camera device connected to the host. - */ -class EmulatedQemuCameraDevice : public EmulatedCameraDevice { - public: - /* Constructs EmulatedQemuCameraDevice instance. */ - explicit EmulatedQemuCameraDevice(EmulatedQemuCamera* camera_hal); - - /* Destructs EmulatedQemuCameraDevice instance. */ - ~EmulatedQemuCameraDevice(); - - /*************************************************************************** - * Public API - **************************************************************************/ - - public: - /* Initializes EmulatedQemuCameraDevice instance. - * Param: - * device_name - Name of the camera device connected to the host. The name - * that is used here must have been reported by the 'factory' camera - * service when it listed camera devices connected to the host. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - status_t Initialize(const char* device_name); - - /*************************************************************************** - * Emulated camera device abstract interface implementation. - * See declarations of these methods in EmulatedCameraDevice class for - * information on each of these methods. - **************************************************************************/ - - public: - /* Connects to the camera device. */ - status_t connectDevice(); - - /* Disconnects from the camera device. */ - status_t disconnectDevice(); - - /* Starts capturing frames from the camera device. */ - status_t startDevice(int width, int height, uint32_t pix_fmt, int fps); - - /* Stops capturing frames from the camera device. */ - status_t stopDevice(); - - /*************************************************************************** - * EmulatedCameraDevice virtual overrides - * See declarations of these methods in EmulatedCameraDevice class for - * information on each of these methods. - **************************************************************************/ - - public: - /* Gets current preview fame into provided buffer. - * We override this method in order to provide preview frames cached in this - * object. - */ - status_t getCurrentPreviewFrame(void* buffer); - - /*************************************************************************** - * Worker thread management overrides. - * See declarations of these methods in EmulatedCameraDevice class for - * information on each of these methods. - **************************************************************************/ - - protected: - /* Implementation of the worker thread routine. */ - bool inWorkerThread(); - - /*************************************************************************** - * Qemu camera device data members - **************************************************************************/ - - private: - /* Qemu client that is used to communicate with the 'emulated camera' - * service, created for this instance in the emulator. */ - CameraQemuClient mQemuClient; - - /* Name of the camera device connected to the host. */ - String8 mDeviceName; - - /* Current preview framebuffer. */ - uint32_t* mPreviewFrame; - - /* Emulated FPS (frames per second). - * We will emulate 50 FPS. */ - static const int mEmulatedFPS = 50; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_EMULATED_QEMU_CAMERA_DEVICE_H */ diff --git a/guest/hals/camera/Exif.cpp b/guest/hals/camera/Exif.cpp deleted file mode 100644 index e57bb8c2..00000000 --- a/guest/hals/camera/Exif.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Exif" -#include <log/log.h> - -#include <inttypes.h> -#include <math.h> -#include <stdint.h> - -#include <CameraParameters.h> - -using ::android::hardware::camera::common::V1_0::helper::CameraParameters; -using ::android::hardware::camera::common::V1_0::helper::Size; - -#include "Exif.h" - -#include <libexif/exif-data.h> -#include <libexif/exif-entry.h> -#include <libexif/exif-ifd.h> -#include <libexif/exif-tag.h> - -#include <string> -#include <vector> - -// For GPS timestamping we want to ensure we use a 64-bit time_t, 32-bit -// platforms have time64_t but 64-bit platforms do not. -#if defined(__LP64__) -#include <time.h> -using Timestamp = time_t; -#define TIMESTAMP_TO_TM(timestamp, tm) gmtime_r(timestamp, tm) -#else -#include <time64.h> -using Timestamp = time64_t; -#define TIMESTAMP_TO_TM(timestamp, tm) gmtime64_r(timestamp, tm) -#endif - -namespace android { - -// A prefix that is used for tags with the "undefined" format to indicate that -// the contents are ASCII encoded. See the user comment section of the EXIF spec -// for more details http://www.exif.org/Exif2-2.PDF -static const unsigned char kAsciiPrefix[] = { - 0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00 // "ASCII\0\0\0" -}; - -// Remove an existing EXIF entry from |exifData| if it exists. This is useful -// when replacing existing data, it's easier to just remove the data and -// re-allocate it than to adjust the amount of allocated data. -static void removeExistingEntry(ExifData* exifData, ExifIfd ifd, int tag) { - ExifEntry* entry = exif_content_get_entry(exifData->ifd[ifd], - static_cast<ExifTag>(tag)); - if (entry) { - exif_content_remove_entry(exifData->ifd[ifd], entry); - } -} - -static ExifEntry* allocateEntry(int tag, - ExifFormat format, - unsigned int numComponents) { - ExifMem* mem = exif_mem_new_default(); - ExifEntry* entry = exif_entry_new_mem(mem); - - unsigned int size = numComponents * exif_format_get_size(format); - entry->data = reinterpret_cast<unsigned char*>(exif_mem_alloc(mem, size)); - entry->size = size; - entry->tag = static_cast<ExifTag>(tag); - entry->components = numComponents; - entry->format = format; - - exif_mem_unref(mem); - return entry; -} - -// Create an entry and place it in |exifData|, the entry is initialized with an -// array of floats from |values| -template<size_t N> -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - const float (&values)[N], - float denominator = 1000.0) { - removeExistingEntry(exifData, ifd, tag); - ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); - ExifEntry* entry = allocateEntry(tag, EXIF_FORMAT_RATIONAL, N); - exif_content_add_entry(exifData->ifd[ifd], entry); - unsigned int rationalSize = exif_format_get_size(EXIF_FORMAT_RATIONAL); - for (size_t i = 0; i < N; ++i) { - ExifRational rational = { - static_cast<uint32_t>(values[i] * denominator), - static_cast<uint32_t>(denominator) - }; - - exif_set_rational(&entry->data[i * rationalSize], byteOrder, rational); - } - - // Unref entry after changing owner to the ExifData struct - exif_entry_unref(entry); - return true; -} - -// Create an entry with a single float |value| in it and place it in |exifData| -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - const float value, - float denominator = 1000.0) { - float values[1] = { value }; - // Recycling functions is good for the environment - return createEntry(exifData, ifd, tag, values, denominator); -} - -// Create an entry and place it in |exifData|, the entry contains the raw data -// pointed to by |data| of length |size|. -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - const unsigned char* data, - size_t size, - ExifFormat format = EXIF_FORMAT_UNDEFINED) { - removeExistingEntry(exifData, ifd, tag); - ExifEntry* entry = allocateEntry(tag, format, size); - memcpy(entry->data, data, size); - exif_content_add_entry(exifData->ifd[ifd], entry); - // Unref entry after changing owner to the ExifData struct - exif_entry_unref(entry); - return true; -} - -// Create an entry and place it in |exifData|, the entry is initialized with -// the string provided in |value| -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - const char* value) { - unsigned int length = strlen(value) + 1; - const unsigned char* data = reinterpret_cast<const unsigned char*>(value); - return createEntry(exifData, ifd, tag, data, length, EXIF_FORMAT_ASCII); -} - -// Create an entry and place it in |exifData|, the entry is initialized with a -// single byte in |value| -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - uint8_t value) { - return createEntry(exifData, ifd, tag, &value, 1, EXIF_FORMAT_BYTE); -} - -// Create an entry and place it in |exifData|, the entry is default initialized -// by the exif library based on |tag| -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag) { - removeExistingEntry(exifData, ifd, tag); - ExifEntry* entry = exif_entry_new(); - exif_content_add_entry(exifData->ifd[ifd], entry); - exif_entry_initialize(entry, static_cast<ExifTag>(tag)); - // Unref entry after changing owner to the ExifData struct - exif_entry_unref(entry); - return true; -} - -// Create an entry with a single EXIF LONG (32-bit value) and place it in -// |exifData|. -static bool createEntry(ExifData* exifData, - ExifIfd ifd, - int tag, - int value) { - removeExistingEntry(exifData, ifd, tag); - ExifByteOrder byteOrder = exif_data_get_byte_order(exifData); - ExifEntry* entry = allocateEntry(tag, EXIF_FORMAT_LONG, 1); - exif_content_add_entry(exifData->ifd[ifd], entry); - exif_set_long(entry->data, byteOrder, value); - - // Unref entry after changing owner to the ExifData struct - exif_entry_unref(entry); - return true; -} - -static bool getCameraParam(const CameraParameters& parameters, - const char* parameterKey, - const char** outValue) { - const char* value = parameters.get(parameterKey); - if (value) { - *outValue = value; - return true; - } - return false; -} - -static bool getCameraParam(const CameraParameters& parameters, - const char* parameterKey, - float* outValue) { - const char* value = parameters.get(parameterKey); - if (value) { - *outValue = parameters.getFloat(parameterKey); - return true; - } - return false; -} - -static bool getCameraParam(const CameraParameters& parameters, - const char* parameterKey, - int64_t* outValue) { - const char* value = parameters.get(parameterKey); - if (value) { - char dummy = 0; - // Attempt to scan an extra character and then make sure it was not - // scanned by checking that the return value indicates only one item. - // This way we fail on any trailing characters - if (sscanf(value, "%" SCNd64 "%c", outValue, &dummy) == 1) { - return true; - } - } - return false; -} - -// Convert a GPS coordinate represented as a decimal degree value to sexagesimal -// GPS coordinates comprised of <degrees> <minutes>' <seconds>" -static void convertGpsCoordinate(float degrees, float (*result)[3]) { - float absDegrees = fabs(degrees); - // First value is degrees without any decimal digits - (*result)[0] = floor(absDegrees); - - // Subtract degrees so we only have the fraction left, then multiply by - // 60 to get the minutes - float minutes = (absDegrees - (*result)[0]) * 60.0f; - (*result)[1] = floor(minutes); - - // Same thing for seconds but here we store seconds with the fraction - float seconds = (minutes - (*result)[1]) * 60.0f; - (*result)[2] = seconds; -} - -// Convert a UNIX epoch timestamp to a timestamp comprised of three floats for -// hour, minute and second, and a date part that is represented as a string. -static bool convertTimestampToTimeAndDate(int64_t timestamp, - float (*timeValues)[3], - std::string* date) { - Timestamp time = timestamp; - struct tm utcTime; - if (TIMESTAMP_TO_TM(&time, &utcTime) == nullptr) { - ALOGE("Could not decompose timestamp into components"); - return false; - } - (*timeValues)[0] = utcTime.tm_hour; - (*timeValues)[1] = utcTime.tm_min; - (*timeValues)[2] = utcTime.tm_sec; - - char buffer[64] = {}; - if (strftime(buffer, sizeof(buffer), "%Y:%m:%d", &utcTime) == 0) { - ALOGE("Could not construct date string from timestamp"); - return false; - } - *date = buffer; - return true; -} - -ExifData* createExifData(const CameraParameters& params) { - ExifData* exifData = exif_data_new(); - - exif_data_set_option(exifData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); - exif_data_set_data_type(exifData, EXIF_DATA_TYPE_COMPRESSED); - exif_data_set_byte_order(exifData, EXIF_BYTE_ORDER_INTEL); - - // Create mandatory exif fields and set their default values - exif_data_fix(exifData); - - float triplet[3]; - float floatValue = 0.0f; - const char* stringValue; - int64_t degrees; - - // Datetime, creating and initializing a datetime tag will automatically - // set the current date and time in the tag so just do that. - createEntry(exifData, EXIF_IFD_0, EXIF_TAG_DATE_TIME); - - // Make and model - createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MAKE, "Emulator-Cuttlefish"); - createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MODEL, "Emulator-Cuttlefish"); - - // Picture size - int width = -1, height = -1; - params.getPictureSize(&width, &height); - if (width >= 0 && height >= 0) { - createEntry(exifData, EXIF_IFD_EXIF, - EXIF_TAG_PIXEL_X_DIMENSION, width); - createEntry(exifData, EXIF_IFD_EXIF, - EXIF_TAG_PIXEL_Y_DIMENSION, height); - } - // Orientation - if (getCameraParam(params, - CameraParameters::KEY_ROTATION, - °rees)) { - // Exif orientation values, please refer to - // http://www.exif.org/Exif2-2.PDF, Section 4.6.4-A-Orientation - // Or these websites: - // http://sylvana.net/jpegcrop/exif_orientation.html - // http://www.impulseadventure.com/photo/exif-orientation.html - enum { - EXIF_ROTATE_CAMERA_CW0 = 1, - EXIF_ROTATE_CAMERA_CW90 = 6, - EXIF_ROTATE_CAMERA_CW180 = 3, - EXIF_ROTATE_CAMERA_CW270 = 8, - }; - uint16_t exifOrien = 1; - switch (degrees) { - case 0: - exifOrien = EXIF_ROTATE_CAMERA_CW0; - break; - case 90: - exifOrien = EXIF_ROTATE_CAMERA_CW90; - break; - case 180: - exifOrien = EXIF_ROTATE_CAMERA_CW180; - break; - case 270: - exifOrien = EXIF_ROTATE_CAMERA_CW270; - break; - } - createEntry(exifData, EXIF_IFD_0, EXIF_TAG_ORIENTATION, exifOrien); - } - // Focal length - if (getCameraParam(params, - CameraParameters::KEY_FOCAL_LENGTH, - &floatValue)) { - createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, floatValue); - } - // GPS latitude and reference, reference indicates sign, store unsigned - if (getCameraParam(params, - CameraParameters::KEY_GPS_LATITUDE, - &floatValue)) { - convertGpsCoordinate(floatValue, &triplet); - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, triplet); - - const char* ref = floatValue < 0.0f ? "S" : "N"; - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, ref); - } - // GPS longitude and reference, reference indicates sign, store unsigned - if (getCameraParam(params, - CameraParameters::KEY_GPS_LONGITUDE, - &floatValue)) { - convertGpsCoordinate(floatValue, &triplet); - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, triplet); - - const char* ref = floatValue < 0.0f ? "W" : "E"; - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, ref); - } - // GPS altitude and reference, reference indicates sign, store unsigned - if (getCameraParam(params, - CameraParameters::KEY_GPS_ALTITUDE, - &floatValue)) { - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE, - static_cast<float>(fabs(floatValue))); - - // 1 indicated below sea level, 0 indicates above sea level - uint8_t ref = floatValue < 0.0f ? 1 : 0; - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE_REF, ref); - } - // GPS timestamp and datestamp - int64_t timestamp = 0; - if (getCameraParam(params, - CameraParameters::KEY_GPS_TIMESTAMP, - ×tamp)) { - std::string date; - if (convertTimestampToTimeAndDate(timestamp, &triplet, &date)) { - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_TIME_STAMP, - triplet, 1.0f); - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_DATE_STAMP, - date.c_str()); - } - } - - // GPS processing method - if (getCameraParam(params, - CameraParameters::KEY_GPS_PROCESSING_METHOD, - &stringValue)) { - std::vector<unsigned char> data; - // Because this is a tag with an undefined format it has to be prefixed - // with the encoding type. Insert an ASCII prefix first, then the - // actual string. Undefined tags do not have to be null terminated. - data.insert(data.end(), - std::begin(kAsciiPrefix), - std::end(kAsciiPrefix)); - data.insert(data.end(), stringValue, stringValue + strlen(stringValue)); - createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_PROCESSING_METHOD, - &data[0], data.size()); - } - - return exifData; -} - -void freeExifData(ExifData* exifData) { - exif_data_free(exifData); -} - -} // namespace android - diff --git a/guest/hals/camera/Exif.h b/guest/hals/camera/Exif.h deleted file mode 100644 index 4ea06e16..00000000 --- a/guest/hals/camera/Exif.h +++ /dev/null @@ -1,41 +0,0 @@ - -/* - * Copyright (C) 2016 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. - */ - -#ifndef CUTTLEFISH_CAMERA_EXIF_H -#define CUTTLEFISH_CAMERA_EXIF_H - -#include <CameraParameters.h> - -using ::android::hardware::camera::common::V1_0::helper::CameraParameters; - -struct _ExifData; -typedef struct _ExifData ExifData; - -namespace android { - -/* Create an EXIF data structure based on camera parameters. This includes - * things like GPS information that has been set by the camera client. - */ -ExifData* createExifData(const CameraParameters& parameters); - -/* Free EXIF data created in the createExifData call */ -void freeExifData(ExifData* exifData); - -} // namespace android - -#endif // CUTTLEFISH_CAMERA_EXIF_H - diff --git a/guest/hals/camera/GrallocModule.h b/guest/hals/camera/GrallocModule.h deleted file mode 100644 index 2033e8d5..00000000 --- a/guest/hals/camera/GrallocModule.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ -#ifndef GUEST_HALS_CAMERA_GRALLOCMODULE_H_ -#define GUEST_HALS_CAMERA_GRALLOCMODULE_H_ - -#include <hardware/gralloc.h> - -class GrallocModule { - public: - static GrallocModule &getInstance() { - static GrallocModule instance; - return instance; - } - - int lock(buffer_handle_t handle, int usage, int l, int t, int w, int h, - void **vaddr) { - return mModule->lock(mModule, handle, usage, l, t, w, h, vaddr); - } - -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - int lock_ycbcr(buffer_handle_t handle, int usage, int l, int t, int w, int h, - struct android_ycbcr *ycbcr) { - return mModule->lock_ycbcr(mModule, handle, usage, l, t, w, h, ycbcr); - } -#endif - - int unlock(buffer_handle_t handle) { - return mModule->unlock(mModule, handle); - } - - private: - GrallocModule() { - const hw_module_t *module = NULL; - int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - if (ret) { - ALOGE("%s: Failed to get gralloc module: %d", __FUNCTION__, ret); - } - mModule = reinterpret_cast<const gralloc_module_t *>(module); - } - const gralloc_module_t *mModule; -}; - -#endif // GUEST_HALS_CAMERA_GRALLOCMODULE_H_ diff --git a/guest/hals/camera/JpegCompressor.cpp b/guest/hals/camera/JpegCompressor.cpp deleted file mode 100644 index 99164c9c..00000000 --- a/guest/hals/camera/JpegCompressor.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class NV21JpegCompressor that encapsulates a - * converter between NV21, and JPEG formats. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_JPEG" -#include "JpegCompressor.h" -#include <assert.h> -#include <log/log.h> -#include <dlfcn.h> - -namespace android { - -void* NV21JpegCompressor::mDl = NULL; - -static void* getSymbol(void* dl, const char* signature) { - void* res = dlsym(dl, signature); - assert(res != NULL); - - return res; -} - -typedef void (*InitFunc)(JpegStub* stub); -typedef void (*CleanupFunc)(JpegStub* stub); -typedef int (*CompressFunc)(JpegStub* stub, const void* image, int width, - int height, int quality, ExifData* exifData); -typedef void (*GetCompressedImageFunc)(JpegStub* stub, void* buff); -typedef size_t (*GetCompressedSizeFunc)(JpegStub* stub); - -NV21JpegCompressor::NV21JpegCompressor() { - if (mDl == NULL) { - mDl = dlopen("/vendor/lib/hw/camera.cutf.jpeg.so", RTLD_NOW); - } - if (mDl == NULL) { - mDl = dlopen("/system/lib/hw/camera.cutf.jpeg.so", RTLD_NOW); - } - assert(mDl != NULL); - - InitFunc f = (InitFunc)getSymbol(mDl, "JpegStub_init"); - (*f)(&mStub); -} - -NV21JpegCompressor::~NV21JpegCompressor() { - CleanupFunc f = (CleanupFunc)getSymbol(mDl, "JpegStub_cleanup"); - (*f)(&mStub); -} - -/**************************************************************************** - * Public API - ***************************************************************************/ - -status_t NV21JpegCompressor::compressRawImage(const void* image, - ExifData* exifData, - int quality, - int width, - int height) { - mStrides[0] = width; - mStrides[1] = width; - CompressFunc f = (CompressFunc)getSymbol(mDl, "JpegStub_compress"); - return (status_t)(*f)(&mStub, image, width, height, quality, exifData); -} - -size_t NV21JpegCompressor::getCompressedSize() { - GetCompressedSizeFunc f = - (GetCompressedSizeFunc)getSymbol(mDl, "JpegStub_getCompressedSize"); - return (*f)(&mStub); -} - -void NV21JpegCompressor::getCompressedImage(void* buff) { - GetCompressedImageFunc f = - (GetCompressedImageFunc)getSymbol(mDl, "JpegStub_getCompressedImage"); - (*f)(&mStub, buff); -} - -}; /* namespace android */ diff --git a/guest/hals/camera/JpegCompressor.h b/guest/hals/camera/JpegCompressor.h deleted file mode 100644 index 6d93c461..00000000 --- a/guest/hals/camera/JpegCompressor.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H -#define HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H - -/* - * Contains declaration of a class NV21JpegCompressor that encapsulates a - * converter between YV21, and JPEG formats. - */ - -#include <utils/threads.h> -#include "JpegStub.h" - -namespace android { - -/* Encapsulates a converter between YV12, and JPEG formats. - */ -class NV21JpegCompressor { - public: - /* Constructs JpegCompressor instance. */ - NV21JpegCompressor(); - /* Destructs JpegCompressor instance. */ - ~NV21JpegCompressor(); - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Compresses raw NV21 image into a JPEG. - * The compressed image will be saved in mStream member of this class. Use - * getCompressedSize method to obtain buffer size of the compressed image, - * and getCompressedImage to copy out the compressed image. - * Param: - * image - Raw NV21 image. - * metadata - Image metadata (dimensions, location etc). - * quality - JPEG quality. - * Return: - * NO_ERROR on success, or an appropriate error status. - * - */ - status_t compressRawImage(const void* image, ExifData* exifData, - int quality, int width, int height); - - /* Get size of the compressed JPEG buffer. - * This method must be called only after a successful completion of - * compressRawImage call. - * Return: - * Size of the compressed JPEG buffer. - */ - size_t getCompressedSize(); - - /* Copies out compressed JPEG buffer. - * This method must be called only after a successful completion of - * compressRawImage call. - * Param: - * buff - Buffer where to copy the JPEG. Must be large enough to contain the - * entire image. - */ - void getCompressedImage(void* buff); - - /**************************************************************************** - * Class data - ***************************************************************************/ - - protected: - /* Strides for Y (the first element), and UV (the second one) panes. */ - int mStrides[2]; - - private: - // library handle to dlopen - static void* mDl; - JpegStub mStub; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_JPEG_COMPRESSOR_H */ diff --git a/guest/hals/camera/JpegStub.cpp b/guest/hals/camera/JpegStub.cpp deleted file mode 100644 index 3e02de06..00000000 --- a/guest/hals/camera/JpegStub.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "JpegStub.h" - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_JPEGStub" -#include <errno.h> -#include <log/log.h> -#include <stdlib.h> - -#include "Compressor.h" - -extern "C" void JpegStub_init(JpegStub* stub) { - stub->mCompressor = static_cast<void*>(new Compressor()); -} - -extern "C" void JpegStub_cleanup(JpegStub* stub) { - delete reinterpret_cast<Compressor*>(stub->mCompressor); - stub->mCompressor = nullptr; -} - -extern "C" int JpegStub_compress(JpegStub* stub, - const void* buffer, - int width, - int height, - int quality, - ExifData* exifData) -{ - Compressor* compressor = reinterpret_cast<Compressor*>(stub->mCompressor); - - if (compressor->compress(reinterpret_cast<const unsigned char*>(buffer), - width, height, quality, exifData)) { - ALOGV("%s: Compressed JPEG: %d[%dx%d] -> %zu bytes", - __FUNCTION__, (width * height * 12) / 8, - width, height, compressor->getCompressedData().size()); - return 0; - } - ALOGE("%s: JPEG compression failed", __FUNCTION__); - return errno ? errno : EINVAL; -} - -extern "C" void JpegStub_getCompressedImage(JpegStub* stub, void* buff) { - Compressor* compressor = reinterpret_cast<Compressor*>(stub->mCompressor); - - const std::vector<unsigned char>& data = compressor->getCompressedData(); - memcpy(buff, &data[0], data.size()); -} - -extern "C" size_t JpegStub_getCompressedSize(JpegStub* stub) { - Compressor* compressor = reinterpret_cast<Compressor*>(stub->mCompressor); - - return compressor->getCompressedData().size(); -} diff --git a/guest/hals/camera/JpegStub.h b/guest/hals/camera/JpegStub.h deleted file mode 100644 index 2e621820..00000000 --- a/guest/hals/camera/JpegStub.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -#ifndef JPEGSTUB_H_ -#define JPEGSTUB_H_ - -#include <stddef.h> - -struct _ExifData; -typedef _ExifData ExifData; - -extern "C" { - -struct JpegStub { - void* mCompressor; -}; - -void JpegStub_init(JpegStub* stub); -void JpegStub_cleanup(JpegStub* stub); -int JpegStub_compress(JpegStub* stub, - const void* image, - int width, - int height, - int quality, - ExifData* exifData); -void JpegStub_getCompressedImage(JpegStub* stub, void* buff); -size_t JpegStub_getCompressedSize(JpegStub* stub); - -}; -#endif // JPEGSTUB_H_ diff --git a/guest/hals/camera/PreviewWindow.cpp b/guest/hals/camera/PreviewWindow.cpp deleted file mode 100644 index e4984352..00000000 --- a/guest/hals/camera/PreviewWindow.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of a class PreviewWindow that encapsulates - * functionality of a preview window set via set_preview_window camera HAL API. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Preview" -#include "PreviewWindow.h" -#include <log/log.h> -#include <hardware/camera.h> -#include "EmulatedCameraDevice.h" -#include "GrallocModule.h" - -namespace android { - -PreviewWindow::PreviewWindow() - : mPreviewWindow(NULL), - mLastPreviewed(0), - mPreviewFrameWidth(0), - mPreviewFrameHeight(0), - mPreviewEnabled(false) {} - -PreviewWindow::~PreviewWindow() {} - -/**************************************************************************** - * Camera API - ***************************************************************************/ - -status_t PreviewWindow::setPreviewWindow(struct preview_stream_ops* window, - int preview_fps) { - ALOGV("%s: current: %p -> new: %p", __FUNCTION__, mPreviewWindow, window); - - status_t res = NO_ERROR; - Mutex::Autolock locker(&mObjectLock); - - /* Reset preview info. */ - mPreviewFrameWidth = mPreviewFrameHeight = 0; - mPreviewAfter = 0; - mLastPreviewed = 0; - - if (window != NULL) { - /* The CPU will write each frame to the preview window buffer. - * Note that we delay setting preview window buffer geometry until - * frames start to come in. */ - res = window->set_usage(window, GRALLOC_USAGE_SW_WRITE_OFTEN); - if (res == NO_ERROR) { - /* Set preview frequency. */ - mPreviewAfter = 1000000 / preview_fps; - } else { - window = NULL; - res = -res; // set_usage returns a negative errno. - ALOGE("%s: Error setting preview window usage %d -> %s", __FUNCTION__, - res, strerror(res)); - } - } - mPreviewWindow = window; - - return res; -} - -status_t PreviewWindow::startPreview() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - mPreviewEnabled = true; - - return NO_ERROR; -} - -void PreviewWindow::stopPreview() { - ALOGV("%s", __FUNCTION__); - - Mutex::Autolock locker(&mObjectLock); - mPreviewEnabled = false; -} - -/**************************************************************************** - * Public API - ***************************************************************************/ - -void PreviewWindow::onNextFrameAvailable(const void* /*frame*/, - nsecs_t timestamp, - EmulatedCameraDevice* camera_dev) { - int res; - Mutex::Autolock locker(&mObjectLock); - - if (!isPreviewEnabled() || mPreviewWindow == NULL || !isPreviewTime()) { - return; - } - - /* Make sure that preview window dimensions are OK with the camera device */ - if (adjustPreviewDimensions(camera_dev)) { - /* Need to set / adjust buffer geometry for the preview window. - * Note that in the emulator preview window uses only RGB for pixel - * formats. */ - ALOGV("%s: Adjusting preview windows %p geometry to %dx%d", __FUNCTION__, - mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight); - res = mPreviewWindow->set_buffers_geometry( - mPreviewWindow, mPreviewFrameWidth, mPreviewFrameHeight, - HAL_PIXEL_FORMAT_RGBA_8888); - if (res != NO_ERROR) { - ALOGE("%s: Error in set_buffers_geometry %d -> %s", __FUNCTION__, -res, - strerror(-res)); - return; - } - } - - /* - * Push new frame to the preview window. - */ - - /* Dequeue preview window buffer for the frame. */ - buffer_handle_t* buffer = NULL; - int stride = 0; - res = mPreviewWindow->dequeue_buffer(mPreviewWindow, &buffer, &stride); - if (res != NO_ERROR || buffer == NULL) { - ALOGE("%s: Unable to dequeue preview window buffer: %d -> %s", __FUNCTION__, - -res, strerror(-res)); - return; - } - - /* Let the preview window to lock the buffer. */ - res = mPreviewWindow->lock_buffer(mPreviewWindow, buffer); - if (res != NO_ERROR) { - ALOGE("%s: Unable to lock preview window buffer: %d -> %s", __FUNCTION__, - -res, strerror(-res)); - mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); - return; - } - - /* Now let the graphics framework to lock the buffer, and provide - * us with the framebuffer data address. */ - void* img = NULL; - res = GrallocModule::getInstance().lock(*buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, - 0, 0, mPreviewFrameWidth, - mPreviewFrameHeight, &img); - if (res != NO_ERROR) { - ALOGE("%s: gralloc.lock failure: %d -> %s", __FUNCTION__, res, - strerror(res)); - mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); - return; - } - - /* Frames come in in YV12/NV12/NV21 format. Since preview window doesn't - * supports those formats, we need to obtain the frame in RGB565. */ - res = camera_dev->getCurrentPreviewFrame(img); - if (res == NO_ERROR) { - /* Show it. */ - mPreviewWindow->set_timestamp(mPreviewWindow, timestamp); - mPreviewWindow->enqueue_buffer(mPreviewWindow, buffer); - } else { - ALOGE("%s: Unable to obtain preview frame: %d", __FUNCTION__, res); - mPreviewWindow->cancel_buffer(mPreviewWindow, buffer); - } - GrallocModule::getInstance().unlock(*buffer); -} - -/*************************************************************************** - * Private API - **************************************************************************/ - -bool PreviewWindow::adjustPreviewDimensions(EmulatedCameraDevice* camera_dev) { - /* Match the cached frame dimensions against the actual ones. */ - if (mPreviewFrameWidth == camera_dev->getFrameWidth() && - mPreviewFrameHeight == camera_dev->getFrameHeight()) { - /* They match. */ - return false; - } - - /* They don't match: adjust the cache. */ - mPreviewFrameWidth = camera_dev->getFrameWidth(); - mPreviewFrameHeight = camera_dev->getFrameHeight(); - - return true; -} - -bool PreviewWindow::isPreviewTime() { - timeval cur_time; - gettimeofday(&cur_time, NULL); - const uint64_t cur_mks = cur_time.tv_sec * 1000000LL + cur_time.tv_usec; - if ((cur_mks - mLastPreviewed) >= mPreviewAfter) { - mLastPreviewed = cur_mks; - return true; - } - return false; -} - -}; /* namespace android */ diff --git a/guest/hals/camera/PreviewWindow.h b/guest/hals/camera/PreviewWindow.h deleted file mode 100644 index 0041c554..00000000 --- a/guest/hals/camera/PreviewWindow.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H -#define HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H - -#include <hardware/camera.h> -#include <utils/Errors.h> -#include <utils/Mutex.h> -#include <utils/Timers.h> - -/* - * Contains declaration of a class PreviewWindow that encapsulates functionality - * of a preview window set via set_preview_window camera HAL API. - */ - -namespace android { - -class EmulatedCameraDevice; - -/* Encapsulates functionality of a preview window set via set_preview_window - * camera HAL API. - * - * Objects of this class are contained in EmulatedCamera objects, and handle - * relevant camera API callbacks. - */ -class PreviewWindow { - public: - /* Constructs PreviewWindow instance. */ - PreviewWindow(); - - /* Destructs PreviewWindow instance. */ - ~PreviewWindow(); - - /*************************************************************************** - * Camera API - **************************************************************************/ - - public: - /* Actual handler for camera_device_ops_t::set_preview_window callback. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::set_preview_window callback. - * Param: - * window - Preview window to set. This parameter might be NULL, which - * indicates preview window reset. - * preview_fps - Preview's frame frequency. This parameter determins when - * a frame received via onNextFrameAvailable call will be pushed to - * the preview window. If 'window' parameter passed to this method is - * NULL, this parameter is ignored. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - status_t setPreviewWindow(struct preview_stream_ops* window, int preview_fps); - - /* Starts the preview. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::start_preview callback. - */ - status_t startPreview(); - - /* Stops the preview. - * This method is called by the containing emulated camera object when it is - * handing the camera_device_ops_t::start_preview callback. - */ - void stopPreview(); - - /* Checks if preview is enabled. */ - inline bool isPreviewEnabled() { return mPreviewEnabled; } - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Next frame is available in the camera device. - * This is a notification callback that is invoked by the camera device when - * a new frame is available. - * Note that most likely this method is called in context of a worker thread - * that camera device has created for frame capturing. - * Param: - * frame - Captured frame, or NULL if camera device didn't pull the frame - * yet. If NULL is passed in this parameter use GetCurrentFrame method - * of the camera device class to obtain the next frame. Also note that - * the size of the frame that is passed here (as well as the frame - * returned from the GetCurrentFrame method) is defined by the current - * frame settings (width + height + pixel format) for the camera device. - * timestamp - Frame's timestamp. - * camera_dev - Camera device instance that delivered the frame. - */ - void onNextFrameAvailable(const void* frame, nsecs_t timestamp, - EmulatedCameraDevice* camera_dev); - - /*************************************************************************** - * Private API - **************************************************************************/ - - protected: - /* Adjusts cached dimensions of the preview window frame according to the - * frame dimensions used by the camera device. - * - * When preview is started, it's not known (hard to define) what are going - * to be the dimensions of the frames that are going to be displayed. Plus, - * it might be possible, that such dimensions can be changed on the fly. So, - * in order to be always in sync with frame dimensions, this method is - * called for each frame passed to onNextFrameAvailable method, in order to - * properly adjust frame dimensions, used by the preview window. - * Note that this method must be called while object is locked. - * Param: - * camera_dev - Camera device, prpviding frames displayed in the preview - * window. - * Return: - * true if cached dimensions have been adjusted, or false if cached - * dimensions match device's frame dimensions. - */ - bool adjustPreviewDimensions(EmulatedCameraDevice* camera_dev); - - /* Checks if it's the time to push new frame to the preview window. - * Note that this method must be called while object is locked. */ - bool isPreviewTime(); - - /*************************************************************************** - * Data members - **************************************************************************/ - - protected: - /* Locks this instance for data changes. */ - Mutex mObjectLock; - - /* Preview window instance. */ - preview_stream_ops* mPreviewWindow; - - /* Timestamp (abs. microseconds) when last frame has been pushed to the - * preview window. */ - uint64_t mLastPreviewed; - - /* Preview frequency in microseconds. */ - uint32_t mPreviewAfter; - - /* - * Cached preview window frame dimensions. - */ - - int mPreviewFrameWidth; - int mPreviewFrameHeight; - - /* Preview status. */ - bool mPreviewEnabled; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_PREVIEW_WINDOW_H */ diff --git a/guest/hals/camera/QemuClient.cpp b/guest/hals/camera/QemuClient.cpp deleted file mode 100644 index eb897024..00000000 --- a/guest/hals/camera/QemuClient.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* - * Contains implementation of classes that encapsulate connection to camera - * services in the emulator via qemu pipe. - */ - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_QemuClient" -#include "QemuClient.h" -#include <log/log.h> -#include "EmulatedCamera.h" - -#define LOG_QUERIES 0 -#if LOG_QUERIES -#define LOGQ(...) ALOGD(__VA_ARGS__) -#else -#define LOGQ(...) (void(0)) - -#endif // LOG_QUERIES -namespace android { - -/**************************************************************************** - * Qemu query - ***************************************************************************/ - -QemuQuery::QemuQuery() - : mQuery(mQueryPrealloc), - mQueryDeliveryStatus(NO_ERROR), - mReplyBuffer(NULL), - mReplyData(NULL), - mReplySize(0), - mReplyDataSize(0), - mReplyStatus(0) { - *mQuery = '\0'; -} - -QemuQuery::QemuQuery(const char* query_string) - : mQuery(mQueryPrealloc), - mQueryDeliveryStatus(NO_ERROR), - mReplyBuffer(NULL), - mReplyData(NULL), - mReplySize(0), - mReplyDataSize(0), - mReplyStatus(0) { - mQueryDeliveryStatus = QemuQuery::createQuery(query_string, NULL); -} - -QemuQuery::QemuQuery(const char* query_name, const char* query_param) - : mQuery(mQueryPrealloc), - mQueryDeliveryStatus(NO_ERROR), - mReplyBuffer(NULL), - mReplyData(NULL), - mReplySize(0), - mReplyDataSize(0), - mReplyStatus(0) { - mQueryDeliveryStatus = QemuQuery::createQuery(query_name, query_param); -} - -QemuQuery::~QemuQuery() { QemuQuery::resetQuery(); } - -status_t QemuQuery::createQuery(const char* name, const char* param) { - /* Reset from the previous use. */ - resetQuery(); - - /* Query name cannot be NULL or an empty string. */ - if (name == NULL || *name == '\0') { - ALOGE("%s: NULL or an empty string is passed as query name.", __FUNCTION__); - mQueryDeliveryStatus = EINVAL; - return EINVAL; - } - - const size_t name_len = strlen(name); - const size_t param_len = (param != NULL) ? strlen(param) : 0; - const size_t required = strlen(name) + (param_len ? (param_len + 2) : 1); - - if (required > sizeof(mQueryPrealloc)) { - /* Preallocated buffer was too small. Allocate a bigger query buffer. */ - mQuery = new char[required]; - if (mQuery == NULL) { - ALOGE("%s: Unable to allocate %zu bytes for query buffer", __FUNCTION__, - required); - mQueryDeliveryStatus = ENOMEM; - return ENOMEM; - } - } - - /* At this point mQuery buffer is big enough for the query. */ - if (param_len) { - sprintf(mQuery, "%s %s", name, param); - } else { - memcpy(mQuery, name, name_len + 1); - } - - return NO_ERROR; -} - -status_t QemuQuery::completeQuery(status_t status) { - /* Save query completion status. */ - mQueryDeliveryStatus = status; - if (mQueryDeliveryStatus != NO_ERROR) { - return mQueryDeliveryStatus; - } - - /* Make sure reply buffer contains at least 'ok', or 'ko'. - * Note that 'ok', or 'ko' prefixes are always 3 characters long: in case - * there are more data in the reply, that data will be separated from - * 'ok'/'ko' with a ':'. If there is no more data in the reply, the prefix - * will be - * zero-terminated, and the terminator will be inculded in the reply. */ - if (mReplyBuffer == NULL || mReplySize < 3) { - ALOGE("%s: Invalid reply to the query", __FUNCTION__); - mQueryDeliveryStatus = EINVAL; - return EINVAL; - } - - /* Lets see the reply status. */ - if (!memcmp(mReplyBuffer, "ok", 2)) { - mReplyStatus = 1; - } else if (!memcmp(mReplyBuffer, "ko", 2)) { - mReplyStatus = 0; - } else { - ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); - mQueryDeliveryStatus = EINVAL; - return EINVAL; - } - - /* Lets see if there are reply data that follow. */ - if (mReplySize > 3) { - /* There are extra data. Make sure they are separated from the status - * with a ':' */ - if (mReplyBuffer[2] != ':') { - ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); - mQueryDeliveryStatus = EINVAL; - return EINVAL; - } - mReplyData = mReplyBuffer + 3; - mReplyDataSize = mReplySize - 3; - } else { - /* Make sure reply buffer containing just 'ok'/'ko' ends with - * zero-terminator. */ - if (mReplyBuffer[2] != '\0') { - ALOGE("%s: Invalid query reply: '%s'", __FUNCTION__, mReplyBuffer); - mQueryDeliveryStatus = EINVAL; - return EINVAL; - } - } - - return NO_ERROR; -} - -void QemuQuery::resetQuery() { - if (mQuery != NULL && mQuery != mQueryPrealloc) { - delete[] mQuery; - } - mQuery = mQueryPrealloc; - mQueryDeliveryStatus = NO_ERROR; - if (mReplyBuffer != NULL) { - free(mReplyBuffer); - mReplyBuffer = NULL; - } - mReplyData = NULL; - mReplySize = mReplyDataSize = 0; - mReplyStatus = 0; -} - -/**************************************************************************** - * Qemu client base - ***************************************************************************/ - -/* Camera service name. */ -const char QemuClient::mCameraServiceName[] = "camera"; - -QemuClient::QemuClient() : mPipeFD(-1) {} - -QemuClient::~QemuClient() { - if (mPipeFD >= 0) { - close(mPipeFD); - } -} - -/**************************************************************************** - * Qemu client API - ***************************************************************************/ - -status_t QemuClient::connectClient(const char* param) { - ALOGV("%s: '%s'", __FUNCTION__, param ? param : ""); - - /* Make sure that client is not connected already. */ - if (mPipeFD >= 0) { - ALOGE("%s: Qemu client is already connected", __FUNCTION__); - return EINVAL; - } - - /* Select one of the two: 'factory', or 'emulated camera' service */ - if (param == NULL || *param == '\0') { - /* No parameters: connect to the factory service. */ - char pipe_name[512]; - snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", mCameraServiceName); - mPipeFD = qemu_pipe_open(pipe_name); - } else { - /* One extra char ':' that separates service name and parameters + six - * characters for 'qemud:'. This is required by qemu pipe protocol. */ - char* connection_str = - new char[strlen(mCameraServiceName) + strlen(param) + 8]; - sprintf(connection_str, "qemud:%s:%s", mCameraServiceName, param); - - mPipeFD = qemu_pipe_open(connection_str); - delete[] connection_str; - } - if (mPipeFD < 0) { - ALOGE("%s: Unable to connect to the camera service '%s': %s", __FUNCTION__, - param ? param : "Factory", strerror(errno)); - return errno ? errno : EINVAL; - } - - return NO_ERROR; -} - -void QemuClient::disconnectClient() { - ALOGV("%s", __FUNCTION__); - - if (mPipeFD >= 0) { - close(mPipeFD); - mPipeFD = -1; - } -} - -status_t QemuClient::sendMessage(const void* data, size_t data_size) { - if (mPipeFD < 0) { - ALOGE("%s: Qemu client is not connected", __FUNCTION__); - return EINVAL; - } - - /* Note that we don't use here qemud_client_send, since with qemu pipes we - * don't need to provide payload size prior to payload when we're writing to - * the pipe. So, we can use simple write, and qemu pipe will take care of the - * rest, calling the receiving end with the number of bytes transferred. */ - const size_t written = qemud_fd_write(mPipeFD, data, data_size); - if (written == data_size) { - return NO_ERROR; - } else { - ALOGE("%s: Error sending data via qemu pipe: '%s'", __FUNCTION__, - strerror(errno)); - return errno ? errno : EIO; - } -} - -status_t QemuClient::receiveMessage(void** data, size_t* data_size) { - *data = NULL; - *data_size = 0; - - if (mPipeFD < 0) { - ALOGE("%s: Qemu client is not connected", __FUNCTION__); - return EINVAL; - } - - /* The way the service replies to a query, it sends payload size first, and - * then it sends the payload itself. Note that payload size is sent as a - * string, containing 8 characters representing a hexadecimal payload size - * value. Note also, that the string doesn't contain zero-terminator. */ - size_t payload_size; - char payload_size_str[9]; - int rd_res = qemud_fd_read(mPipeFD, payload_size_str, 8); - if (rd_res != 8) { - ALOGE("%s: Unable to obtain payload size: %s", __FUNCTION__, - strerror(errno)); - return errno ? errno : EIO; - } - - /* Convert payload size. */ - errno = 0; - payload_size_str[8] = '\0'; - payload_size = strtol(payload_size_str, NULL, 16); - if (errno) { - ALOGE("%s: Invalid payload size '%s'", __FUNCTION__, payload_size_str); - return EIO; - } - - /* Allocate payload data buffer, and read the payload there. */ - *data = malloc(payload_size); - if (*data == NULL) { - ALOGE("%s: Unable to allocate %zu bytes payload buffer", __FUNCTION__, - payload_size); - return ENOMEM; - } - rd_res = qemud_fd_read(mPipeFD, *data, payload_size); - if (static_cast<size_t>(rd_res) == payload_size) { - *data_size = payload_size; - return NO_ERROR; - } else { - ALOGE("%s: Read size %d doesnt match expected payload size %zu: %s", - __FUNCTION__, rd_res, payload_size, strerror(errno)); - free(*data); - *data = NULL; - return errno ? errno : EIO; - } -} - -status_t QemuClient::doQuery(QemuQuery* query) { - /* Make sure that query has been successfuly constructed. */ - if (query->mQueryDeliveryStatus != NO_ERROR) { - ALOGE("%s: Query is invalid", __FUNCTION__); - return query->mQueryDeliveryStatus; - } - - LOGQ("Send query '%s'", query->mQuery); - - /* Send the query. */ - status_t res = sendMessage(query->mQuery, strlen(query->mQuery) + 1); - if (res == NO_ERROR) { - /* Read the response. */ - res = receiveMessage(reinterpret_cast<void**>(&query->mReplyBuffer), - &query->mReplySize); - if (res == NO_ERROR) { - LOGQ("Response to query '%s': Status = '%.2s', %d bytes in response", - query->mQuery, query->mReplyBuffer, query->mReplySize); - } else { - ALOGE("%s Response to query '%s' has failed: %s", __FUNCTION__, - query->mQuery, strerror(res)); - } - } else { - ALOGE("%s: Send query '%s' failed: %s", __FUNCTION__, query->mQuery, - strerror(res)); - } - - /* Complete the query, and return its completion handling status. */ - const status_t res1 = query->completeQuery(res); - ALOGE_IF(res1 != NO_ERROR && res1 != res, - "%s: Error %d in query '%s' completion", __FUNCTION__, res1, - query->mQuery); - return res1; -} - -/**************************************************************************** - * Qemu client for the 'factory' service. - ***************************************************************************/ - -/* - * Factory service queries. - */ - -/* Queries list of cameras connected to the host. */ -const char FactoryQemuClient::mQueryList[] = "list"; - -FactoryQemuClient::FactoryQemuClient() : QemuClient() {} - -FactoryQemuClient::~FactoryQemuClient() {} - -status_t FactoryQemuClient::listCameras(char** list) { - ALOGV("%s", __FUNCTION__); - - QemuQuery query(mQueryList); - if (doQuery(&query) || !query.isQuerySucceeded()) { - ALOGE("%s: List cameras query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return query.getCompletionStatus(); - } - - /* Make sure there is a list returned. */ - if (query.mReplyDataSize == 0) { - ALOGE("%s: No camera list is returned.", __FUNCTION__); - return EINVAL; - } - - /* Copy the list over. */ - *list = (char*)malloc(query.mReplyDataSize); - if (*list != NULL) { - memcpy(*list, query.mReplyData, query.mReplyDataSize); - ALOGD("Emulated camera list: %s", *list); - return NO_ERROR; - } else { - ALOGE("%s: Unable to allocate %zu bytes", __FUNCTION__, - query.mReplyDataSize); - return ENOMEM; - } -} - -/**************************************************************************** - * Qemu client for an 'emulated camera' service. - ***************************************************************************/ - -/* - * Emulated camera queries - */ - -/* Connect to the camera device. */ -const char CameraQemuClient::mQueryConnect[] = "connect"; -/* Disconect from the camera device. */ -const char CameraQemuClient::mQueryDisconnect[] = "disconnect"; -/* Start capturing video from the camera device. */ -const char CameraQemuClient::mQueryStart[] = "start"; -/* Stop capturing video from the camera device. */ -const char CameraQemuClient::mQueryStop[] = "stop"; -/* Get next video frame from the camera device. */ -const char CameraQemuClient::mQueryFrame[] = "frame"; - -CameraQemuClient::CameraQemuClient() : QemuClient() {} - -CameraQemuClient::~CameraQemuClient() {} - -status_t CameraQemuClient::queryConnect() { - ALOGV("%s", __FUNCTION__); - - QemuQuery query(mQueryConnect); - doQuery(&query); - const status_t res = query.getCompletionStatus(); - ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return res; -} - -status_t CameraQemuClient::queryDisconnect() { - ALOGV("%s", __FUNCTION__); - - QemuQuery query(mQueryDisconnect); - doQuery(&query); - const status_t res = query.getCompletionStatus(); - ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return res; -} - -status_t CameraQemuClient::queryStart(uint32_t pixel_format, int width, - int height) { - ALOGV("%s", __FUNCTION__); - - char query_str[256]; - snprintf(query_str, sizeof(query_str), "%s dim=%dx%d pix=%d", mQueryStart, - width, height, pixel_format); - QemuQuery query(query_str); - doQuery(&query); - const status_t res = query.getCompletionStatus(); - ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return res; -} - -status_t CameraQemuClient::queryStop() { - ALOGV("%s", __FUNCTION__); - - QemuQuery query(mQueryStop); - doQuery(&query); - const status_t res = query.getCompletionStatus(); - ALOGE_IF(res != NO_ERROR, "%s: Query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return res; -} - -status_t CameraQemuClient::queryFrame(void* vframe, void* pframe, - size_t vframe_size, size_t pframe_size, - float r_scale, float g_scale, - float b_scale, float exposure_comp) { - ALOGV("%s", __FUNCTION__); - - char query_str[256]; - snprintf(query_str, sizeof(query_str), - "%s video=%zu preview=%zu whiteb=%g,%g,%g expcomp=%g", mQueryFrame, - (vframe && vframe_size) ? vframe_size : 0, - (pframe && pframe_size) ? pframe_size : 0, r_scale, g_scale, b_scale, - exposure_comp); - QemuQuery query(query_str); - doQuery(&query); - const status_t res = query.getCompletionStatus(); - if (res != NO_ERROR) { - ALOGE("%s: Query failed: %s", __FUNCTION__, - query.mReplyData ? query.mReplyData : "No error message"); - return res; - } - - /* Copy requested frames. */ - size_t cur_offset = 0; - const uint8_t* frame = reinterpret_cast<const uint8_t*>(query.mReplyData); - /* Video frame is always first. */ - if (vframe != NULL && vframe_size != 0) { - /* Make sure that video frame is in. */ - if ((query.mReplyDataSize - cur_offset) >= vframe_size) { - memcpy(vframe, frame, vframe_size); - cur_offset += vframe_size; - } else { - ALOGE("%s: Reply %zu bytes is to small to contain %zu bytes video frame", - __FUNCTION__, query.mReplyDataSize - cur_offset, vframe_size); - return EINVAL; - } - } - if (pframe != NULL && pframe_size != 0) { - /* Make sure that preview frame is in. */ - if ((query.mReplyDataSize - cur_offset) >= pframe_size) { - memcpy(pframe, frame + cur_offset, pframe_size); - cur_offset += pframe_size; - } else { - ALOGE( - "%s: Reply %zu bytes is to small to contain %zu bytes preview frame", - __FUNCTION__, query.mReplyDataSize - cur_offset, pframe_size); - return EINVAL; - } - } - - return NO_ERROR; -} - -}; /* namespace android */ diff --git a/guest/hals/camera/QemuClient.h b/guest/hals/camera/QemuClient.h deleted file mode 100644 index 290ab41c..00000000 --- a/guest/hals/camera/QemuClient.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#ifndef HW_EMULATOR_CAMERA_QEMU_CLIENT_H -#define HW_EMULATOR_CAMERA_QEMU_CLIENT_H - -/* - * Contains declaration of classes that encapsulate connection to camera - * services in the emulator via qemu pipe. - */ - -#include <hardware/qemud.h> - -namespace android { - -/**************************************************************************** - * Qemu query - ***************************************************************************/ - -/* Encapsulates a query to the emulator. - * Guest exchanges data with the emulator via queries sent over the qemu pipe. - * The queries as well as replies to the queries are all strings (except for the - * 'frame' query where reply is a framebuffer). - * Each query is formatted as such: - * - * "<query name>[ <parameters>]", - * - * where <query name> is a string representing query name, and <parameters> are - * optional parameters for the query. If parameters are present, they must be - * separated from the query name with a single space, and they must be formatted - * as such: - * - * "<name1>=<value1> <name2>=<value2> ... <nameN>=<valueN>" - * - * I.e.: - * - Every parameter must have a name, and a value. - * - Name and value must be separated with '='. - * - No spaces are allowed around '=' separating name and value. - * - Parameters must be separated with a single space character. - * - No '=' character is allowed in name and in value. - * - * There are certain restrictions on strings used in the query: - * - Spaces are allowed only as separators. - * - '=' are allowed only to divide parameter names from parameter values. - * - * Emulator replies to each query in two chunks: - * - 8 bytes encoding the payload size as a string containing hexadecimal - * representation of the payload size value. This is done in order to simplify - * dealing with different endianness on the host, and on the guest. - * - Payload, whose size is defined by the first chunk. - * - * Every payload always begins with two characters, encoding the result of the - * query: - * - 'ok' Encoding the success - * - 'ko' Encoding a failure. - * After that payload may have optional data. If payload has more data following - * the query result, there is a ':' character separating them. If payload - * carries only the result, it always ends with a zero-terminator. So, payload - * 'ok'/'ko' prefix is always 3 bytes long: it either includes a - * zero-terminator, if there is no data, or a ':' separator. - */ -class QemuQuery { - public: - /* Constructs an uninitialized QemuQuery instance. */ - QemuQuery(); - - /* Constructs and initializes QemuQuery instance for a query. - * Param: - * query_string - Query string. This constructor can also be used to - * construct a query that doesn't have parameters. In this case query - * name can be passed as a parameter here. - */ - explicit QemuQuery(const char* query_string); - - /* Constructs and initializes QemuQuery instance for a query with parameters. - * Param: - * query_name - Query name. - * query_param - Query parameters. Can be NULL. - */ - QemuQuery(const char* query_name, const char* query_param); - - /* Destructs QemuQuery instance. */ - ~QemuQuery(); - - /**************************************************************************** - * Public API - ***************************************************************************/ - - /* Creates new query. - * Note: this method will reset this instance prior to creating a new query - * in order to discard possible "leftovers" from the previous query. - * Param: - * query_name - Query name. - * query_param - Query parameters. Can be NULL. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - status_t createQuery(const char* name, const char* param); - - /* Completes the query after a reply from the emulator. - * This method will parse the reply buffer, and calculate the final query - * status, which depends not only on the transport success / failure, but - * also on 'ok' / 'ko' in the reply buffer. - * Param: - * status - Query delivery status. This status doesn't necessarily reflects - * the final query status (which is defined by 'ok'/'ko' prefix in the - * reply buffer). This status simply states whether or not the query has - * been sent, and a reply has been received successfuly. However, if - * this status indicates a failure, it means that the entire query has - * failed. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. Note that - * status returned here just signals whether or not the method has succeeded. - * Use isQuerySucceeded() / getCompletionStatus() methods of this class to - * check the final query status. - */ - status_t completeQuery(status_t status); - - /* Resets the query from a previous use. */ - void resetQuery(); - - /* Checks if query has succeeded. - * Note that this method must be called after completeQuery() method of this - * class has been executed. - */ - inline bool isQuerySucceeded() const { - return mQueryDeliveryStatus == NO_ERROR && mReplyStatus != 0; - } - - /* Gets final completion status of the query. - * Note that this method must be called after completeQuery() method of this - * class has been executed. - * Return: - * NO_ERROR if query has succeeded, or an appropriate error status on query - * failure. - */ - inline status_t getCompletionStatus() const { - if (mQueryDeliveryStatus == NO_ERROR) { - if (mReplyStatus) { - return NO_ERROR; - } else { - return EINVAL; - } - } else { - return mQueryDeliveryStatus; - } - } - - /**************************************************************************** - * Public data memebers - ***************************************************************************/ - - public: - /* Query string. */ - char* mQuery; - /* Query delivery status. */ - status_t mQueryDeliveryStatus; - /* Reply buffer */ - char* mReplyBuffer; - /* Reply data (past 'ok'/'ko'). If NULL, there were no data in reply. */ - char* mReplyData; - /* Reply buffer size. */ - size_t mReplySize; - /* Reply data size. */ - size_t mReplyDataSize; - /* Reply status: 1 - ok, 0 - ko. */ - int mReplyStatus; - - /**************************************************************************** - * Private data memebers - ***************************************************************************/ - - protected: - /* Preallocated buffer for small queries. */ - char mQueryPrealloc[256]; -}; - -/**************************************************************************** - * Qemu client base - ***************************************************************************/ - -/* Encapsulates a connection to the 'camera' service in the emulator via qemu - * pipe. - */ -class QemuClient { - public: - /* Constructs QemuClient instance. */ - QemuClient(); - - /* Destructs QemuClient instance. */ - virtual ~QemuClient(); - - /**************************************************************************** - * Qemu client API - ***************************************************************************/ - - public: - /* Connects to the 'camera' service in the emulator via qemu pipe. - * Param: - * param - Parameters to pass to the camera service. There are two types of - * camera services implemented by the emulator. The first one is a - * 'camera factory' type of service that provides list of cameras - * connected to the host. Another one is an 'emulated camera' type of - * service that provides interface to a camera connected to the host. At - * the connection time emulator makes distinction between the two by - * looking at connection parameters: no parameters means connection to - * the 'factory' service, while connection with parameters means - * connection to an 'emulated camera' service, where camera is identified - * by one of the connection parameters. So, passing NULL, or an empty - * string to this method will establish a connection with the 'factory' - * service, while not empty string passed here will establish connection - * with an 'emulated camera' service. Parameters defining the emulated - * camera must be formatted as such: - * - * "name=<device name> [inp_channel=<input channel #>]", - * - * where 'device name' is a required parameter defining name of the - * camera device, and 'input channel' is an optional parameter (positive - * integer), defining the input channel to use on the camera device. - * Note that device name passed here must have been previously obtained - * from the factory service using 'list' query. - * Return: - * NO_ERROR on success, or an appropriate error status. - */ - virtual status_t connectClient(const char* param); - - /* Disconnects from the service. */ - virtual void disconnectClient(); - - /* Sends data to the service. - * Param: - * data, data_size - Data to send. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - virtual status_t sendMessage(const void* data, size_t data_size); - - /* Receives data from the service. - * This method assumes that data to receive will come in two chunks: 8 - * characters encoding the payload size in hexadecimal string, followed by - * the paylod (if any). - * This method will allocate data buffer where to receive the response. - * Param: - * data - Upon success contains address of the allocated data buffer with - * the data received from the service. The caller is responsible for - * freeing allocated data buffer. - * data_size - Upon success contains size of the data received from the - * service. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - virtual status_t receiveMessage(void** data, size_t* data_size); - - /* Sends a query, and receives a response from the service. - * Param: - * query - Query to send to the service. When this method returns, the query - * is completed, and all its relevant data members are properly initialized. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. Note that - * status returned here is not the final query status. Use - * isQuerySucceeded(), or getCompletionStatus() method on the query object to - * see if it has succeeded. However, if this method returns a failure, it - * means that the query has failed, and there is no guarantee that its data - * members are properly initialized (except for the 'mQueryDeliveryStatus', - * which is always in the proper state). - */ - virtual status_t doQuery(QemuQuery* query); - - /**************************************************************************** - * Data members - ***************************************************************************/ - - protected: - /* Qemu pipe handle. */ - int mPipeFD; - - private: - /* Camera service name. */ - static const char mCameraServiceName[]; -}; - -/**************************************************************************** - * Qemu client for the 'factory' service. - ***************************************************************************/ - -/* Encapsulates QemuClient for the 'factory' service. */ -class FactoryQemuClient : public QemuClient { - public: - /* Constructs FactoryQemuClient instance. */ - FactoryQemuClient(); - - /* Destructs FactoryQemuClient instance. */ - ~FactoryQemuClient(); - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Lists camera devices connected to the host. - * Param: - * list - Upon success contains a list of cameras connected to the host. The - * list returned here is represented as a string, containing multiple - * lines separated with '\n', where each line represents a camera. Each - * camera line is formatted as such: - * - * "name=<device name> channel=<num> pix=<num> - * framedims=<dimensions>\n" - * - * Where: - * - 'name' is the name of the camera device attached to the host. This - * name must be used for subsequent connection to the 'emulated camera' - * service for that camera. - * - 'channel' - input channel number (positive int) to use to - * communicate with the camera. - * - 'pix' - pixel format (a "fourcc" uint), chosen for the video frames - * by the camera service. - * - 'framedims' contains a list of frame dimensions supported by the - * camera for the chosen pixel format. Each etry in the list is in form - * '<width>x<height>', where 'width' and 'height' are numeric values - * for width and height of a supported frame dimension. Entries in - * this list are separated with ',' with no spaces between the entries. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t listCameras(char** list); - - /**************************************************************************** - * Names of the queries available for the emulated camera factory. - ***************************************************************************/ - - private: - /* List cameras connected to the host. */ - static const char mQueryList[]; -}; - -/**************************************************************************** - * Qemu client for an 'emulated camera' service. - ***************************************************************************/ - -/* Encapsulates QemuClient for an 'emulated camera' service. - */ -class CameraQemuClient : public QemuClient { - public: - /* Constructs CameraQemuClient instance. */ - CameraQemuClient(); - - /* Destructs CameraQemuClient instance. */ - ~CameraQemuClient(); - - /**************************************************************************** - * Public API - ***************************************************************************/ - - public: - /* Queries camera connection. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t queryConnect(); - - /* Queries camera disconnection. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t queryDisconnect(); - - /* Queries camera to start capturing video. - * Param: - * pixel_format - Pixel format that is used by the client to push video - * frames to the camera framework. - * width, height - Frame dimensions, requested by the framework. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t queryStart(uint32_t pixel_format, int width, int height); - - /* Queries camera to stop capturing video. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t queryStop(); - - /* Queries camera for the next video frame. - * Param: - * vframe, vframe_size - Define buffer, allocated to receive a video frame. - * Any of these parameters can be 0, indicating that the caller is - * interested only in preview frame. - * pframe, pframe_size - Define buffer, allocated to receive a preview frame. - * Any of these parameters can be 0, indicating that the caller is - * interested only in video frame. - * r_scale, g_scale, b_scale - White balance scale. - * exposure_comp - Expsoure compensation. - * Return: - * NO_ERROR on success, or an appropriate error status on failure. - */ - status_t queryFrame(void* vframe, void* pframe, size_t vframe_size, - size_t pframe_size, float r_scale, float g_scale, - float b_scale, float exposure_comp); - - /**************************************************************************** - * Names of the queries available for the emulated camera. - ***************************************************************************/ - - private: - /* Connect to the camera. */ - static const char mQueryConnect[]; - /* Disconnect from the camera. */ - static const char mQueryDisconnect[]; - /* Start video capturing. */ - static const char mQueryStart[]; - /* Stop video capturing. */ - static const char mQueryStop[]; - /* Query frame(s). */ - static const char mQueryFrame[]; -}; - -}; /* namespace android */ - -#endif /* HW_EMULATOR_CAMERA_QEMU_CLIENT_H */ diff --git a/guest/hals/camera/Thumbnail.cpp b/guest/hals/camera/Thumbnail.cpp deleted file mode 100644 index e8f8126e..00000000 --- a/guest/hals/camera/Thumbnail.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* -* Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Thumbnail.h" - -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Thumbnail" -#include <log/log.h> -#include <libexif/exif-data.h> -#include <libyuv.h> - -#include "JpegCompressor.h" - -#include <vector> - -/* - * The NV21 format is a YUV format with an 8-bit Y-component and the U and V - * components are stored as 8 bits each but they are shared between a block of - * 2x2 pixels. So when calculating bits per pixel the 16 bits of U and V are - * shared between 4 pixels leading to 4 bits of U and V per pixel. Together - * with the 8 bits of Y this gives us 12 bits per pixel.. - * - * The components are not grouped by pixels but separated into one Y-plane and - * one interleaved U and V-plane. The first half of the byte sequence is all of - * the Y data laid out in a linear fashion. After that the interleaved U and V- - * plane starts with one byte of V followed by one byte of U followed by one - * byte of V and so on. Each byte of U or V is associated with a 2x2 pixel block - * in a linear fashion. - * - * For an 8 by 4 pixel image the layout would be: - * - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | Y0 | Y1 | Y2 | Y3 | Y4 | Y5 | Y6 | Y7 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | Y8 | Y9 | Y10 | Y11 | Y12 | Y13 | Y14 | Y15 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | Y16 | Y17 | Y18 | Y19 | Y20 | Y21 | Y22 | Y23 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | Y24 | Y25 | Y26 | Y27 | Y28 | Y29 | Y30 | Y31 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | V0 | U0 | V1 | U1 | V2 | U2 | V3 | U3 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * | V4 | U4 | V5 | U5 | V6 | U6 | V7 | U7 | - * +-----+-----+-----+-----+-----+-----+-----+-----+ - * - * In this image V0 and U0 are the V and U components for the 2x2 block of - * pixels whose Y components are Y0, Y1, Y8 and Y9. V1 and U1 are matched with - * the Y components Y2, Y3, Y10, Y11, and so on for that row. For the next row - * of V and U the V4 and U4 components would be paired with Y16, Y17, Y24 and - * Y25. - */ - -namespace android { - -static bool createRawThumbnail(const unsigned char* sourceImage, - int sourceWidth, int sourceHeight, - int thumbnailWidth, int thumbnailHeight, - std::vector<unsigned char>* thumbnail) { - // Deinterleave the U and V planes into separate planes, this is because - // libyuv requires the planes to be separate when scaling - const size_t sourceUVPlaneSize = (sourceWidth * sourceHeight) / 4; - // Put both U and V planes in one buffer, one after the other, to reduce - // memory fragmentation and number of allocations - std::vector<unsigned char> sourcePlanes(sourceUVPlaneSize * 2); - const unsigned char* ySourcePlane = sourceImage; - unsigned char* uSourcePlane = &sourcePlanes[0]; - unsigned char* vSourcePlane = &sourcePlanes[sourceUVPlaneSize]; - - for (size_t i = 0; i < sourceUVPlaneSize; ++i) { - vSourcePlane[i] = sourceImage[sourceWidth * sourceHeight + i * 2 + 0]; - uSourcePlane[i] = sourceImage[sourceWidth * sourceHeight + i * 2 + 1]; - } - - // Create enough space in the output vector for the result - thumbnail->resize((thumbnailWidth * thumbnailHeight * 12) / 8); - - // The downscaled U and V planes will also be linear instead of interleaved, - // allocate space for them here - const size_t destUVPlaneSize = (thumbnailWidth * thumbnailHeight) / 4; - std::vector<unsigned char> destPlanes(destUVPlaneSize * 2); - unsigned char* yDestPlane = &(*thumbnail)[0]; - unsigned char* uDestPlane = &destPlanes[0]; - unsigned char* vDestPlane = &destPlanes[destUVPlaneSize]; - - // The strides for the U and V planes are half the width because the U and V - // components are common to 2x2 pixel blocks - int result = libyuv::I420Scale(ySourcePlane, sourceWidth, - uSourcePlane, sourceWidth / 2, - vSourcePlane, sourceWidth / 2, - sourceWidth, sourceHeight, - yDestPlane, thumbnailWidth, - uDestPlane, thumbnailWidth / 2, - vDestPlane, thumbnailWidth / 2, - thumbnailWidth, thumbnailHeight, - libyuv::kFilterBilinear); - if (result != 0) { - ALOGE("Unable to create thumbnail, downscaling failed with error: %d", - result); - return false; - } - - // Now we need to interleave the downscaled U and V planes into the - // output buffer to make it NV21 encoded - const size_t uvPlanesOffset = thumbnailWidth * thumbnailHeight; - for (size_t i = 0; i < destUVPlaneSize; ++i) { - (*thumbnail)[uvPlanesOffset + i * 2 + 0] = vDestPlane[i]; - (*thumbnail)[uvPlanesOffset + i * 2 + 1] = uDestPlane[i]; - } - - return true; -} - -bool createThumbnail(const unsigned char* sourceImage, - int sourceWidth, int sourceHeight, - int thumbWidth, int thumbHeight, int quality, - ExifData* exifData) { - if (thumbWidth <= 0 || thumbHeight <= 0) { - ALOGE("%s: Invalid thumbnail width=%d or height=%d, must be > 0", - __FUNCTION__, thumbWidth, thumbHeight); - return false; - } - - // First downscale the source image into a thumbnail-sized raw image - std::vector<unsigned char> rawThumbnail; - if (!createRawThumbnail(sourceImage, sourceWidth, sourceHeight, - thumbWidth, thumbHeight, &rawThumbnail)) { - // The thumbnail function will log an appropriate error if needed - return false; - } - - // And then compress it into JPEG format without any EXIF data - NV21JpegCompressor compressor; - status_t result = compressor.compressRawImage(&rawThumbnail[0], - nullptr /* EXIF */, - quality, thumbWidth, thumbHeight); - if (result != NO_ERROR) { - ALOGE("%s: Unable to compress thumbnail", __FUNCTION__); - return false; - } - - // And finally put it in the EXIF data. This transfers ownership of the - // malloc'd memory to the EXIF data structure. As long as the EXIF data - // structure is free'd using the EXIF library this memory will be free'd. - exifData->size = compressor.getCompressedSize(); - exifData->data = reinterpret_cast<unsigned char*>(malloc(exifData->size)); - if (exifData->data == nullptr) { - ALOGE("%s: Unable to allocate %u bytes of memory for thumbnail", - __FUNCTION__, exifData->size); - exifData->size = 0; - return false; - } - compressor.getCompressedImage(exifData->data); - return true; -} - -} // namespace android - diff --git a/guest/hals/camera/Thumbnail.h b/guest/hals/camera/Thumbnail.h deleted file mode 100644 index b27636c1..00000000 --- a/guest/hals/camera/Thumbnail.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* Copyright (C) 2016 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. - */ - -#ifndef GOLDFISH_CAMERA_THUMBNAIL_H -#define GOLDFISH_CAMERA_THUMBNAIL_H - -struct _ExifData; -typedef struct _ExifData ExifData; - -namespace android { - -/* Create a thumbnail from NV21 source data in |sourceImage| with the given - * dimensions. The resulting thumbnail is JPEG compressed and a pointer and size - * is placed in |exifData| which takes ownership of the allocated memory. - */ -bool createThumbnail(const unsigned char* sourceImage, - int sourceWidth, int sourceHeight, - int thumbnailWidth, int thumbnailHeight, int quality, - ExifData* exifData); - -} // namespace android - -#endif // GOLDFISH_CAMERA_THUMBNAIL_H - diff --git a/guest/hals/camera/VSoCEmulatedCameraHotplugThread.cpp b/guest/hals/camera/VSoCEmulatedCameraHotplugThread.cpp deleted file mode 100644 index 2378dc07..00000000 --- a/guest/hals/camera/VSoCEmulatedCameraHotplugThread.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ -#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_HotplugThread" -#include <log/log.h> - -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "EmulatedCameraFactory.h" -#include "EmulatedCameraHotplugThread.h" - -#define SubscriberInfo EmulatedCameraHotplugThread::SubscriberInfo - -namespace android { - -EmulatedCameraHotplugThread::EmulatedCameraHotplugThread( - size_t /*totalCameraCount*/) - : Thread(/*canCallJava*/ false) {} - -EmulatedCameraHotplugThread::~EmulatedCameraHotplugThread() {} - -status_t EmulatedCameraHotplugThread::requestExitAndWait() { - ALOGE("%s: Not implemented. Use requestExit + join instead", __FUNCTION__); - return INVALID_OPERATION; -} - -void EmulatedCameraHotplugThread::requestExit() { - ALOGV("%s: Requesting thread exit", __FUNCTION__); - mRunning = false; -} - -status_t EmulatedCameraHotplugThread::readyToRun() { return OK; } - -bool EmulatedCameraHotplugThread::threadLoop() { - // Thread is irrelevant right now; hoplug is not supported. - return false; -} - -String8 EmulatedCameraHotplugThread::getFilePath(int /*cameraId*/) const { - return String8(); -} - -bool EmulatedCameraHotplugThread::createFileIfNotExists( - int /*cameraId*/) const { - return true; -} - -int EmulatedCameraHotplugThread::getCameraId(String8 /*filePath*/) const { - // Not used anywhere. - return NAME_NOT_FOUND; -} - -int EmulatedCameraHotplugThread::getCameraId(int /*wd*/) const { - // Not used anywhere. - return NAME_NOT_FOUND; -} - -SubscriberInfo* EmulatedCameraHotplugThread::getSubscriberInfo( - int /*cameraId*/) { - // Not used anywhere. - return NULL; -} - -bool EmulatedCameraHotplugThread::addWatch(int /*cameraId*/) { return true; } - -bool EmulatedCameraHotplugThread::removeWatch(int /*cameraId*/) { return true; } - -int EmulatedCameraHotplugThread::readFile(String8 /*filePath*/) const { - return 1; -} - -} // namespace android diff --git a/guest/hals/camera/fake-pipeline2/Base.h b/guest/hals/camera/fake-pipeline2/Base.h deleted file mode 100644 index 3cd1e153..00000000 --- a/guest/hals/camera/fake-pipeline2/Base.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/** - * This file includes various basic structures that are needed by multiple parts - * of the fake camera 2 implementation. - */ - -#ifndef HW_EMULATOR_CAMERA2_BASE_H -#define HW_EMULATOR_CAMERA2_BASE_H - -#include <hardware/camera2.h> -#include <utils/Vector.h> - -namespace android { - -/* Internal structure for passing buffers across threads */ -struct StreamBuffer { - // Positive numbers are output streams - // Negative numbers are input reprocess streams - // Zero is an auxillary buffer - int streamId; - uint32_t width, height; - uint32_t format; - uint32_t dataSpace; - uint32_t stride; - buffer_handle_t *buffer; - uint8_t *img; -}; -typedef Vector<StreamBuffer> Buffers; - -struct Stream { - const camera2_stream_ops_t *ops; - uint32_t width, height; - int32_t format; - uint32_t stride; -}; - -struct ReprocessStream { - const camera2_stream_in_ops_t *ops; - uint32_t width, height; - int32_t format; - uint32_t stride; - // -1 if the reprocessing stream is independent - int32_t sourceStreamId; -}; - -} // namespace android - -#endif diff --git a/guest/hals/camera/fake-pipeline2/JpegCompressor.cpp b/guest/hals/camera/fake-pipeline2/JpegCompressor.cpp deleted file mode 100644 index 7fb6cf16..00000000 --- a/guest/hals/camera/fake-pipeline2/JpegCompressor.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -//#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera2_JpegCompressor" - -#include <utils/Log.h> - -#include "../EmulatedFakeCamera2.h" -#include "../EmulatedFakeCamera3.h" -#include "JpegCompressor.h" - -namespace android { - -JpegCompressor::JpegCompressor() - : Thread(false), - mIsBusy(false), - mSynchronous(false), - mBuffers(NULL), - mListener(NULL) {} - -JpegCompressor::~JpegCompressor() { Mutex::Autolock lock(mMutex); } - -status_t JpegCompressor::reserve() { - Mutex::Autolock busyLock(mBusyMutex); - if (mIsBusy) { - ALOGE("%s: Already processing a buffer!", __FUNCTION__); - return INVALID_OPERATION; - } - mIsBusy = true; - return OK; -} - -status_t JpegCompressor::start(Buffers *buffers, JpegListener *listener) { - if (listener == NULL) { - ALOGE("%s: NULL listener not allowed!", __FUNCTION__); - return BAD_VALUE; - } - ALOGV("%s: Starting JPEG compression thread", __FUNCTION__); - Mutex::Autolock lock(mMutex); - { - Mutex::Autolock busyLock(mBusyMutex); - - if (!mIsBusy) { - ALOGE("Called start without reserve() first!"); - return INVALID_OPERATION; - } - mSynchronous = false; - mBuffers = buffers; - mListener = listener; - } - - status_t res; - res = run("EmulatedFakeCamera2::JpegCompressor"); - if (res != OK) { - ALOGE("%s: Unable to start up compression thread: %s (%d)", __FUNCTION__, - strerror(-res), res); - delete mBuffers; - } - return res; -} - -status_t JpegCompressor::compressSynchronous(Buffers *buffers) { - status_t res; - - Mutex::Autolock lock(mMutex); - { - Mutex::Autolock busyLock(mBusyMutex); - - if (mIsBusy) { - ALOGE("%s: Already processing a buffer!", __FUNCTION__); - return INVALID_OPERATION; - } - - mIsBusy = true; - mSynchronous = true; - mBuffers = buffers; - } - - res = compress(); - - cleanUp(); - - return res; -} - -status_t JpegCompressor::cancel() { - requestExitAndWait(); - return OK; -} - -status_t JpegCompressor::readyToRun() { return OK; } - -bool JpegCompressor::threadLoop() { - status_t res; - ALOGV("%s: Starting compression thread", __FUNCTION__); - - res = compress(); - - mListener->onJpegDone(mJpegBuffer, res == OK); - - cleanUp(); - - return false; -} - -status_t JpegCompressor::compress() { - // Find source and target buffers. Assumes only one buffer matches - // each condition! - ALOGV("%s: Compressing start", __FUNCTION__); - bool mFoundAux = false; - for (size_t i = 0; i < mBuffers->size(); i++) { - const StreamBuffer &b = (*mBuffers)[i]; - if (b.format == HAL_PIXEL_FORMAT_BLOB) { - mJpegBuffer = b; - mFoundJpeg = true; - } else if (b.streamId <= 0) { - mAuxBuffer = b; - mFoundAux = true; - } - if (mFoundJpeg && mFoundAux) break; - } - if (!mFoundJpeg || !mFoundAux) { - ALOGE("%s: Unable to find buffers for JPEG source/destination", - __FUNCTION__); - return BAD_VALUE; - } - - // Set up error management - - mJpegErrorInfo = NULL; - JpegError error; - error.parent = this; - - mCInfo.err = jpeg_std_error(&error); - mCInfo.err->error_exit = jpegErrorHandler; - - jpeg_create_compress(&mCInfo); - if (checkError("Error initializing compression")) return NO_INIT; - - // Route compressed data straight to output stream buffer - - JpegDestination jpegDestMgr; - jpegDestMgr.parent = this; - jpegDestMgr.init_destination = jpegInitDestination; - jpegDestMgr.empty_output_buffer = jpegEmptyOutputBuffer; - jpegDestMgr.term_destination = jpegTermDestination; - - mCInfo.dest = &jpegDestMgr; - - // Set up compression parameters - - mCInfo.image_width = mAuxBuffer.width; - mCInfo.image_height = mAuxBuffer.height; - mCInfo.input_components = 3; - mCInfo.in_color_space = JCS_RGB; - - jpeg_set_defaults(&mCInfo); - if (checkError("Error configuring defaults")) return NO_INIT; - - // Do compression - - jpeg_start_compress(&mCInfo, TRUE); - if (checkError("Error starting compression")) return NO_INIT; - - size_t rowStride = mAuxBuffer.stride * 3; - const size_t kChunkSize = 32; - while (mCInfo.next_scanline < mCInfo.image_height) { - JSAMPROW chunk[kChunkSize]; - for (size_t i = 0; i < kChunkSize; i++) { - chunk[i] = - (JSAMPROW)(mAuxBuffer.img + (i + mCInfo.next_scanline) * rowStride); - } - jpeg_write_scanlines(&mCInfo, chunk, kChunkSize); - if (checkError("Error while compressing")) return NO_INIT; - if (exitPending()) { - ALOGV("%s: Cancel called, exiting early", __FUNCTION__); - return TIMED_OUT; - } - } - - jpeg_finish_compress(&mCInfo); - if (checkError("Error while finishing compression")) return NO_INIT; - - // All done - ALOGV("%s: Compressing done", __FUNCTION__); - - return OK; -} - -bool JpegCompressor::isBusy() { - Mutex::Autolock busyLock(mBusyMutex); - return mIsBusy; -} - -bool JpegCompressor::isStreamInUse(uint32_t id) { - Mutex::Autolock lock(mBusyMutex); - - if (mBuffers && mIsBusy) { - for (size_t i = 0; i < mBuffers->size(); i++) { - if ((*mBuffers)[i].streamId == (int)id) return true; - } - } - return false; -} - -bool JpegCompressor::waitForDone(nsecs_t timeout) { - Mutex::Autolock lock(mBusyMutex); - while (mIsBusy) { - status_t res = mDone.waitRelative(mBusyMutex, timeout); - if (res != OK) return false; - } - return true; -} - -bool JpegCompressor::checkError(const char *msg) { - if (mJpegErrorInfo) { - char errBuffer[JMSG_LENGTH_MAX]; - mJpegErrorInfo->err->format_message(mJpegErrorInfo, errBuffer); - ALOGE("%s: %s: %s", __FUNCTION__, msg, errBuffer); - mJpegErrorInfo = NULL; - return true; - } - return false; -} - -void JpegCompressor::cleanUp() { - jpeg_destroy_compress(&mCInfo); - Mutex::Autolock lock(mBusyMutex); - - if (mFoundAux) { - if (mAuxBuffer.streamId == 0) { - delete[] mAuxBuffer.img; - } else if (!mSynchronous) { - mListener->onJpegInputDone(mAuxBuffer); - } - } - if (!mSynchronous) { - delete mBuffers; - } - - mBuffers = NULL; - - mIsBusy = false; - mDone.signal(); -} - -void JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) { - JpegError *error = static_cast<JpegError *>(cinfo->err); - error->parent->mJpegErrorInfo = cinfo; -} - -void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) { - JpegDestination *dest = static_cast<JpegDestination *>(cinfo->dest); - ALOGV("%s: Setting destination to %p, size %zu", __FUNCTION__, - dest->parent->mJpegBuffer.img, kMaxJpegSize); - dest->next_output_byte = (JOCTET *)(dest->parent->mJpegBuffer.img); - dest->free_in_buffer = kMaxJpegSize; -} - -boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr /*cinfo*/) { - ALOGE("%s: JPEG destination buffer overflow!", __FUNCTION__); - return true; -} - -void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) { - ALOGV("%s: Done writing JPEG data. %zu bytes left in buffer", __FUNCTION__, - cinfo->dest->free_in_buffer); -} - -JpegCompressor::JpegListener::~JpegListener() {} - -} // namespace android diff --git a/guest/hals/camera/fake-pipeline2/JpegCompressor.h b/guest/hals/camera/fake-pipeline2/JpegCompressor.h deleted file mode 100644 index bdbc7722..00000000 --- a/guest/hals/camera/fake-pipeline2/JpegCompressor.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/** - * This class simulates a hardware JPEG compressor. It receives image buffers - * in RGBA_8888 format, processes them in a worker thread, and then pushes them - * out to their destination stream. - */ - -#ifndef HW_EMULATOR_CAMERA2_JPEG_H -#define HW_EMULATOR_CAMERA2_JPEG_H - -#include "utils/Mutex.h" -#include "utils/Thread.h" -#include "utils/Timers.h" - -#include "Base.h" - -#include <stdio.h> - -extern "C" { -#include <jpeglib.h> -} - -namespace android { - -class JpegCompressor : private Thread, public virtual RefBase { - public: - JpegCompressor(); - ~JpegCompressor(); - - struct JpegListener { - // Called when JPEG compression has finished, or encountered an error - virtual void onJpegDone(const StreamBuffer &jpegBuffer, bool success) = 0; - // Called when the input buffer for JPEG is not needed any more, - // if the buffer came from the framework. - virtual void onJpegInputDone(const StreamBuffer &inputBuffer) = 0; - virtual ~JpegListener(); - }; - - // Start compressing COMPRESSED format buffers; JpegCompressor takes - // ownership of the Buffers vector. - // Reserve() must be called first. - status_t start(Buffers *buffers, JpegListener *listener); - - // Compress and block until buffer is complete. - status_t compressSynchronous(Buffers *buffers); - - status_t cancel(); - - bool isBusy(); - bool isStreamInUse(uint32_t id); - - bool waitForDone(nsecs_t timeout); - - // Reserve the compressor for a later start() call. - status_t reserve(); - - // TODO: Measure this - static const size_t kMaxJpegSize = 300000; - - private: - Mutex mBusyMutex; - bool mIsBusy; - Condition mDone; - bool mSynchronous; - - Mutex mMutex; - - Buffers *mBuffers; - JpegListener *mListener; - - StreamBuffer mJpegBuffer, mAuxBuffer; - bool mFoundJpeg, mFoundAux; - - jpeg_compress_struct mCInfo; - - struct JpegError : public jpeg_error_mgr { - JpegCompressor *parent; - }; - j_common_ptr mJpegErrorInfo; - - struct JpegDestination : public jpeg_destination_mgr { - JpegCompressor *parent; - }; - - static void jpegErrorHandler(j_common_ptr cinfo); - - static void jpegInitDestination(j_compress_ptr cinfo); - static boolean jpegEmptyOutputBuffer(j_compress_ptr cinfo); - static void jpegTermDestination(j_compress_ptr cinfo); - - bool checkError(const char *msg); - status_t compress(); - - void cleanUp(); - - /** - * Inherited Thread virtual overrides - */ - private: - virtual status_t readyToRun(); - virtual bool threadLoop(); -}; - -} // namespace android - -#endif diff --git a/guest/hals/camera/fake-pipeline2/Scene.cpp b/guest/hals/camera/fake-pipeline2/Scene.cpp deleted file mode 100644 index c70dc4c8..00000000 --- a/guest/hals/camera/fake-pipeline2/Scene.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -//#define LOG_NDEBUG 0 -#define LOG_TAG "EmulatedCamera_Scene" -#include "Scene.h" -#include <stdlib.h> -#include <utils/Log.h> -#include <cmath> - -// TODO: This should probably be done host-side in OpenGL for speed and better -// quality - -namespace android { - -// Define single-letter shortcuts for scene definition, for directly indexing -// mCurrentColors -#define G (Scene::GRASS * Scene::NUM_CHANNELS) -#define S (Scene::GRASS_SHADOW * Scene::NUM_CHANNELS) -#define H (Scene::HILL * Scene::NUM_CHANNELS) -#define W (Scene::WALL * Scene::NUM_CHANNELS) -#define R (Scene::ROOF * Scene::NUM_CHANNELS) -#define D (Scene::DOOR * Scene::NUM_CHANNELS) -#define C (Scene::CHIMNEY * Scene::NUM_CHANNELS) -#define I (Scene::WINDOW * Scene::NUM_CHANNELS) -#define U (Scene::SUN * Scene::NUM_CHANNELS) -#define K (Scene::SKY * Scene::NUM_CHANNELS) -#define M (Scene::MOON * Scene::NUM_CHANNELS) - -const int Scene::kSceneWidth = 20; -const int Scene::kSceneHeight = 20; - -const uint8_t Scene::kScene[Scene::kSceneWidth * Scene::kSceneHeight] = { - // 5 10 15 20 - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, // 5 - K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, K, - K, K, K, K, K, K, K, K, H, H, H, H, H, H, H, H, H, H, H, H, - K, K, K, K, K, K, K, K, H, H, H, H, H, H, H, C, C, H, H, H, - K, K, K, K, K, K, H, H, H, H, H, H, H, H, H, C, C, H, H, H, - H, K, K, K, K, K, H, R, R, R, R, R, R, R, R, R, R, R, R, H, // 10 - H, K, K, K, K, H, H, R, R, R, R, R, R, R, R, R, R, R, R, H, - H, H, H, K, K, H, H, R, R, R, R, R, R, R, R, R, R, R, R, H, - H, H, H, K, K, H, H, H, W, W, W, W, W, W, W, W, W, W, H, H, - S, S, S, G, G, S, S, S, W, W, W, W, W, W, W, W, W, W, S, S, - S, G, G, G, G, S, S, S, W, I, I, W, D, D, W, I, I, W, S, S, // 15 - G, G, G, G, G, G, S, S, W, I, I, W, D, D, W, I, I, W, S, S, - G, G, G, G, G, G, G, G, W, W, W, W, D, D, W, W, W, W, G, G, - G, G, G, G, G, G, G, G, W, W, W, W, D, D, W, W, W, W, G, G, - G, G, G, G, G, G, G, G, S, S, S, S, S, S, S, S, S, S, G, G, - G, G, G, G, G, G, G, G, S, S, S, S, S, S, S, S, S, S, G, G, // 20 - // 5 10 15 20 -}; - -#undef G -#undef S -#undef H -#undef W -#undef R -#undef D -#undef C -#undef I -#undef U -#undef K -#undef M - -Scene::Scene(int sensorWidthPx, int sensorHeightPx, float sensorSensitivity) - : mSensorWidth(sensorWidthPx), - mSensorHeight(sensorHeightPx), - mHour(12), - mExposureDuration(0.033f), - mSensorSensitivity(sensorSensitivity) { - // Map scene to sensor pixels - if (mSensorWidth > mSensorHeight) { - mMapDiv = (mSensorWidth / (kSceneWidth + 1)) + 1; - } else { - mMapDiv = (mSensorHeight / (kSceneHeight + 1)) + 1; - } - mOffsetX = (kSceneWidth * mMapDiv - mSensorWidth) / 2; - mOffsetY = (kSceneHeight * mMapDiv - mSensorHeight) / 2; - - // Assume that sensor filters are sRGB primaries to start - mFilterR[0] = 3.2406f; - mFilterR[1] = -1.5372f; - mFilterR[2] = -0.4986f; - mFilterGr[0] = -0.9689f; - mFilterGr[1] = 1.8758f; - mFilterGr[2] = 0.0415f; - mFilterGb[0] = -0.9689f; - mFilterGb[1] = 1.8758f; - mFilterGb[2] = 0.0415f; - mFilterB[0] = 0.0557f; - mFilterB[1] = -0.2040f; - mFilterB[2] = 1.0570f; -} - -Scene::~Scene() {} - -void Scene::setColorFilterXYZ(float rX, float rY, float rZ, float grX, - float grY, float grZ, float gbX, float gbY, - float gbZ, float bX, float bY, float bZ) { - mFilterR[0] = rX; - mFilterR[1] = rY; - mFilterR[2] = rZ; - mFilterGr[0] = grX; - mFilterGr[1] = grY; - mFilterGr[2] = grZ; - mFilterGb[0] = gbX; - mFilterGb[1] = gbY; - mFilterGb[2] = gbZ; - mFilterB[0] = bX; - mFilterB[1] = bY; - mFilterB[2] = bZ; -} - -void Scene::setHour(int hour) { - ALOGV("Hour set to: %d", hour); - mHour = hour % 24; -} - -int Scene::getHour() { return mHour; } - -void Scene::setExposureDuration(float seconds) { mExposureDuration = seconds; } - -void Scene::calculateScene(nsecs_t time) { - // Calculate time fractions for interpolation - int timeIdx = mHour / kTimeStep; - int nextTimeIdx = (timeIdx + 1) % (24 / kTimeStep); - const nsecs_t kOneHourInNsec = 1e9 * 60 * 60; - nsecs_t timeSinceIdx = (mHour - timeIdx * kTimeStep) * kOneHourInNsec + time; - float timeFrac = timeSinceIdx / (float)(kOneHourInNsec * kTimeStep); - - // Determine overall sunlight levels - float sunLux = - kSunlight[timeIdx] * (1 - timeFrac) + kSunlight[nextTimeIdx] * timeFrac; - ALOGV("Sun lux: %f", sunLux); - - float sunShadeLux = sunLux * (kDaylightShadeIllum / kDirectSunIllum); - - // Determine sun/shade illumination chromaticity - float currentSunXY[2]; - float currentShadeXY[2]; - - const float *prevSunXY, *nextSunXY; - const float *prevShadeXY, *nextShadeXY; - if (kSunlight[timeIdx] == kSunsetIllum || - kSunlight[timeIdx] == kTwilightIllum) { - prevSunXY = kSunsetXY; - prevShadeXY = kSunsetXY; - } else { - prevSunXY = kDirectSunlightXY; - prevShadeXY = kDaylightXY; - } - if (kSunlight[nextTimeIdx] == kSunsetIllum || - kSunlight[nextTimeIdx] == kTwilightIllum) { - nextSunXY = kSunsetXY; - nextShadeXY = kSunsetXY; - } else { - nextSunXY = kDirectSunlightXY; - nextShadeXY = kDaylightXY; - } - currentSunXY[0] = prevSunXY[0] * (1 - timeFrac) + nextSunXY[0] * timeFrac; - currentSunXY[1] = prevSunXY[1] * (1 - timeFrac) + nextSunXY[1] * timeFrac; - - currentShadeXY[0] = - prevShadeXY[0] * (1 - timeFrac) + nextShadeXY[0] * timeFrac; - currentShadeXY[1] = - prevShadeXY[1] * (1 - timeFrac) + nextShadeXY[1] * timeFrac; - - ALOGV("Sun XY: %f, %f, Shade XY: %f, %f", currentSunXY[0], currentSunXY[1], - currentShadeXY[0], currentShadeXY[1]); - - // Converting for xyY to XYZ: - // X = Y / y * x - // Y = Y - // Z = Y / y * (1 - x - y); - float sunXYZ[3] = { - sunLux / currentSunXY[1] * currentSunXY[0], sunLux, - sunLux / currentSunXY[1] * (1 - currentSunXY[0] - currentSunXY[1])}; - float sunShadeXYZ[3] = {sunShadeLux / currentShadeXY[1] * currentShadeXY[0], - sunShadeLux, - sunShadeLux / currentShadeXY[1] * - (1 - currentShadeXY[0] - currentShadeXY[1])}; - ALOGV("Sun XYZ: %f, %f, %f", sunXYZ[0], sunXYZ[1], sunXYZ[2]); - ALOGV("Sun shade XYZ: %f, %f, %f", sunShadeXYZ[0], sunShadeXYZ[1], - sunShadeXYZ[2]); - - // Determine moonlight levels - float moonLux = - kMoonlight[timeIdx] * (1 - timeFrac) + kMoonlight[nextTimeIdx] * timeFrac; - float moonShadeLux = moonLux * (kDaylightShadeIllum / kDirectSunIllum); - - float moonXYZ[3] = { - moonLux / kMoonlightXY[1] * kMoonlightXY[0], moonLux, - moonLux / kMoonlightXY[1] * (1 - kMoonlightXY[0] - kMoonlightXY[1])}; - float moonShadeXYZ[3] = { - moonShadeLux / kMoonlightXY[1] * kMoonlightXY[0], moonShadeLux, - moonShadeLux / kMoonlightXY[1] * (1 - kMoonlightXY[0] - kMoonlightXY[1])}; - - // Determine starlight level - const float kClearNightXYZ[3] = { - kClearNightIllum / kMoonlightXY[1] * kMoonlightXY[0], kClearNightIllum, - kClearNightIllum / kMoonlightXY[1] * - (1 - kMoonlightXY[0] - kMoonlightXY[1])}; - - // Calculate direct and shaded light - float directIllumXYZ[3] = { - sunXYZ[0] + moonXYZ[0] + kClearNightXYZ[0], - sunXYZ[1] + moonXYZ[1] + kClearNightXYZ[1], - sunXYZ[2] + moonXYZ[2] + kClearNightXYZ[2], - }; - - float shadeIllumXYZ[3] = {kClearNightXYZ[0], kClearNightXYZ[1], - kClearNightXYZ[2]}; - - shadeIllumXYZ[0] += (mHour < kSunOverhead) ? sunXYZ[0] : sunShadeXYZ[0]; - shadeIllumXYZ[1] += (mHour < kSunOverhead) ? sunXYZ[1] : sunShadeXYZ[1]; - shadeIllumXYZ[2] += (mHour < kSunOverhead) ? sunXYZ[2] : sunShadeXYZ[2]; - - // Moon up period covers 23->0 transition, shift for simplicity - int adjHour = (mHour + 12) % 24; - int adjMoonOverhead = (kMoonOverhead + 12) % 24; - shadeIllumXYZ[0] += - (adjHour < adjMoonOverhead) ? moonXYZ[0] : moonShadeXYZ[0]; - shadeIllumXYZ[1] += - (adjHour < adjMoonOverhead) ? moonXYZ[1] : moonShadeXYZ[1]; - shadeIllumXYZ[2] += - (adjHour < adjMoonOverhead) ? moonXYZ[2] : moonShadeXYZ[2]; - - ALOGV("Direct XYZ: %f, %f, %f", directIllumXYZ[0], directIllumXYZ[1], - directIllumXYZ[2]); - ALOGV("Shade XYZ: %f, %f, %f", shadeIllumXYZ[0], shadeIllumXYZ[1], - shadeIllumXYZ[2]); - - for (int i = 0; i < NUM_MATERIALS; i++) { - // Converting for xyY to XYZ: - // X = Y / y * x - // Y = Y - // Z = Y / y * (1 - x - y); - float matXYZ[3] = { - kMaterials_xyY[i][2] / kMaterials_xyY[i][1] * kMaterials_xyY[i][0], - kMaterials_xyY[i][2], - kMaterials_xyY[i][2] / kMaterials_xyY[i][1] * - (1 - kMaterials_xyY[i][0] - kMaterials_xyY[i][1])}; - - if (kMaterialsFlags[i] == 0 || kMaterialsFlags[i] & kSky) { - matXYZ[0] *= directIllumXYZ[0]; - matXYZ[1] *= directIllumXYZ[1]; - matXYZ[2] *= directIllumXYZ[2]; - } else if (kMaterialsFlags[i] & kShadowed) { - matXYZ[0] *= shadeIllumXYZ[0]; - matXYZ[1] *= shadeIllumXYZ[1]; - matXYZ[2] *= shadeIllumXYZ[2]; - } // else if (kMaterialsFlags[i] * kSelfLit), do nothing - - ALOGV("Mat %d XYZ: %f, %f, %f", i, matXYZ[0], matXYZ[1], matXYZ[2]); - float luxToElectrons = - mSensorSensitivity * mExposureDuration / (kAperture * kAperture); - mCurrentColors[i * NUM_CHANNELS + 0] = - (mFilterR[0] * matXYZ[0] + mFilterR[1] * matXYZ[1] + - mFilterR[2] * matXYZ[2]) * - luxToElectrons; - mCurrentColors[i * NUM_CHANNELS + 1] = - (mFilterGr[0] * matXYZ[0] + mFilterGr[1] * matXYZ[1] + - mFilterGr[2] * matXYZ[2]) * - luxToElectrons; - mCurrentColors[i * NUM_CHANNELS + 2] = - (mFilterGb[0] * matXYZ[0] + mFilterGb[1] * matXYZ[1] + - mFilterGb[2] * matXYZ[2]) * - luxToElectrons; - mCurrentColors[i * NUM_CHANNELS + 3] = - (mFilterB[0] * matXYZ[0] + mFilterB[1] * matXYZ[1] + - mFilterB[2] * matXYZ[2]) * - luxToElectrons; - - ALOGV("Color %d RGGB: %d, %d, %d, %d", i, - mCurrentColors[i * NUM_CHANNELS + 0], - mCurrentColors[i * NUM_CHANNELS + 1], - mCurrentColors[i * NUM_CHANNELS + 2], - mCurrentColors[i * NUM_CHANNELS + 3]); - } - // Shake viewpoint; horizontal and vertical sinusoids at roughly - // human handshake frequencies - mHandshakeX = (kFreq1Magnitude * std::sin(kHorizShakeFreq1 * timeSinceIdx) + - kFreq2Magnitude * std::sin(kHorizShakeFreq2 * timeSinceIdx)) * - mMapDiv * kShakeFraction; - - mHandshakeY = (kFreq1Magnitude * std::sin(kVertShakeFreq1 * timeSinceIdx) + - kFreq2Magnitude * std::sin(kVertShakeFreq2 * timeSinceIdx)) * - mMapDiv * kShakeFraction; - - // Set starting pixel - setReadoutPixel(0, 0); -} - -void Scene::setReadoutPixel(int x, int y) { - mCurrentX = x; - mCurrentY = y; - mSubX = (x + mOffsetX + mHandshakeX) % mMapDiv; - mSubY = (y + mOffsetY + mHandshakeY) % mMapDiv; - mSceneX = (x + mOffsetX + mHandshakeX) / mMapDiv; - mSceneY = (y + mOffsetY + mHandshakeY) / mMapDiv; - mSceneIdx = mSceneY * kSceneWidth + mSceneX; - mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]); -} - -const uint32_t *Scene::getPixelElectrons() { - const uint32_t *pixel = mCurrentSceneMaterial; - mCurrentX++; - mSubX++; - if (mCurrentX >= mSensorWidth) { - mCurrentX = 0; - mCurrentY++; - if (mCurrentY >= mSensorHeight) mCurrentY = 0; - setReadoutPixel(mCurrentX, mCurrentY); - } else if (mSubX > mMapDiv) { - mSceneIdx++; - mSceneX++; - mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]); - mSubX = 0; - } - return pixel; -} - -// Handshake model constants. -// Frequencies measured in a nanosecond timebase -const float Scene::kHorizShakeFreq1 = 2 * M_PI * 2 / 1e9; // 2 Hz -const float Scene::kHorizShakeFreq2 = 2 * M_PI * 13 / 1e9; // 13 Hz -const float Scene::kVertShakeFreq1 = 2 * M_PI * 3 / 1e9; // 3 Hz -const float Scene::kVertShakeFreq2 = 2 * M_PI * 11 / 1e9; // 1 Hz -const float Scene::kFreq1Magnitude = 5; -const float Scene::kFreq2Magnitude = 1; -const float Scene::kShakeFraction = 0.03; // As a fraction of a scene tile - -// RGB->YUV, Jpeg standard -const float Scene::kRgb2Yuv[12] = { - 0.299f, 0.587f, 0.114f, 0.f, -0.16874f, -0.33126f, - 0.5f, -128.f, 0.5f, -0.41869f, -0.08131f, -128.f, -}; - -// Aperture of imaging lens -const float Scene::kAperture = 2.8; - -// Sun illumination levels through the day -const float Scene::kSunlight[24 / kTimeStep] = {0, // 00:00 - 0, - 0, - kTwilightIllum, // 06:00 - kDirectSunIllum, - kDirectSunIllum, - kDirectSunIllum, // 12:00 - kDirectSunIllum, - kDirectSunIllum, - kSunsetIllum, // 18:00 - kTwilightIllum, - 0}; - -// Moon illumination levels through the day -const float Scene::kMoonlight[24 / kTimeStep] = {kFullMoonIllum, // 00:00 - kFullMoonIllum, - 0, - 0, // 06:00 - 0, - 0, - 0, // 12:00 - 0, - 0, - 0, // 18:00 - 0, - kFullMoonIllum}; - -const int Scene::kSunOverhead = 12; -const int Scene::kMoonOverhead = 0; - -// Used for sun illumination levels -const float Scene::kDirectSunIllum = 100000; -const float Scene::kSunsetIllum = 400; -const float Scene::kTwilightIllum = 4; -// Used for moon illumination levels -const float Scene::kFullMoonIllum = 1; -// Other illumination levels -const float Scene::kDaylightShadeIllum = 20000; -const float Scene::kClearNightIllum = 2e-3; -const float Scene::kStarIllum = 2e-6; -const float Scene::kLivingRoomIllum = 50; - -const float Scene::kIncandescentXY[2] = {0.44757f, 0.40745f}; -const float Scene::kDirectSunlightXY[2] = {0.34842f, 0.35161f}; -const float Scene::kDaylightXY[2] = {0.31271f, 0.32902f}; -const float Scene::kNoonSkyXY[2] = {0.346f, 0.359f}; -const float Scene::kMoonlightXY[2] = {0.34842f, 0.35161f}; -const float Scene::kSunsetXY[2] = {0.527f, 0.413f}; - -const uint8_t Scene::kSelfLit = 0x01; -const uint8_t Scene::kShadowed = 0x02; -const uint8_t Scene::kSky = 0x04; - -// For non-self-lit materials, the Y component is normalized with 1=full -// reflectance; for self-lit materials, it's the constant illuminance in lux. -const float Scene::kMaterials_xyY[Scene::NUM_MATERIALS][3] = { - {0.3688f, 0.4501f, .1329f}, // GRASS - {0.3688f, 0.4501f, .1329f}, // GRASS_SHADOW - {0.3986f, 0.5002f, .4440f}, // HILL - {0.3262f, 0.5040f, .2297f}, // WALL - {0.4336f, 0.3787f, .1029f}, // ROOF - {0.3316f, 0.2544f, .0639f}, // DOOR - {0.3425f, 0.3577f, .0887f}, // CHIMNEY - {kIncandescentXY[0], kIncandescentXY[1], kLivingRoomIllum}, // WINDOW - {kDirectSunlightXY[0], kDirectSunlightXY[1], kDirectSunIllum}, // SUN - {kNoonSkyXY[0], kNoonSkyXY[1], - kDaylightShadeIllum / kDirectSunIllum}, // SKY - {kMoonlightXY[0], kMoonlightXY[1], kFullMoonIllum} // MOON -}; - -const uint8_t Scene::kMaterialsFlags[Scene::NUM_MATERIALS] = { - 0, kShadowed, kShadowed, kShadowed, kShadowed, kShadowed, - kShadowed, kSelfLit, kSelfLit, kSky, kSelfLit, -}; - -} // namespace android diff --git a/guest/hals/camera/fake-pipeline2/Scene.h b/guest/hals/camera/fake-pipeline2/Scene.h deleted file mode 100644 index 5e86861e..00000000 --- a/guest/hals/camera/fake-pipeline2/Scene.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/** - * The Scene class implements a simple physical simulation of a scene, using the - * CIE 1931 colorspace to represent light in physical units (lux). - * - * It's fairly approximate, but does provide a scene with realistic widely - * variable illumination levels and colors over time. - * - */ - -#ifndef HW_EMULATOR_CAMERA2_SCENE_H -#define HW_EMULATOR_CAMERA2_SCENE_H - -#include "utils/Timers.h" - -namespace android { - -class Scene { - public: - Scene(int sensorWidthPx, int sensorHeightPx, float sensorSensitivity); - ~Scene(); - - // Set the filter coefficients for the red, green, and blue filters on the - // sensor. Used as an optimization to pre-calculate various illuminance - // values. Two different green filters can be provided, to account for - // possible cross-talk on a Bayer sensor. Must be called before - // calculateScene. - void setColorFilterXYZ(float rX, float rY, float rZ, float grX, float grY, - float grZ, float gbX, float gbY, float gbZ, float bX, - float bY, float bZ); - - // Set time of day (24-hour clock). This controls the general light levels - // in the scene. Must be called before calculateScene - void setHour(int hour); - // Get current hour - int getHour(); - - // Set the duration of exposure for determining luminous exposure. - // Must be called before calculateScene - void setExposureDuration(float seconds); - - // Calculate scene information for current hour and the time offset since - // the hour. Must be called at least once before calling getLuminousExposure. - // Resets pixel readout location to 0,0 - void calculateScene(nsecs_t time); - - // Set sensor pixel readout location. - void setReadoutPixel(int x, int y); - - // Get sensor response in physical units (electrons) for light hitting the - // current readout pixel, after passing through color filters. The readout - // pixel will be auto-incremented. The returned array can be indexed with - // ColorChannels. - const uint32_t* getPixelElectrons(); - - enum ColorChannels { R = 0, Gr, Gb, B, Y, Cb, Cr, NUM_CHANNELS }; - - private: - // Sensor color filtering coefficients in XYZ - float mFilterR[3]; - float mFilterGr[3]; - float mFilterGb[3]; - float mFilterB[3]; - - int mOffsetX, mOffsetY; - int mMapDiv; - - int mHandshakeX, mHandshakeY; - - int mSensorWidth; - int mSensorHeight; - int mCurrentX; - int mCurrentY; - int mSubX; - int mSubY; - int mSceneX; - int mSceneY; - int mSceneIdx; - uint32_t* mCurrentSceneMaterial; - - int mHour; - float mExposureDuration; - float mSensorSensitivity; - - enum Materials { - GRASS = 0, - GRASS_SHADOW, - HILL, - WALL, - ROOF, - DOOR, - CHIMNEY, - WINDOW, - SUN, - SKY, - MOON, - NUM_MATERIALS - }; - - uint32_t mCurrentColors[NUM_MATERIALS * NUM_CHANNELS]; - - /** - * Constants for scene definition. These are various degrees of approximate. - */ - - // Fake handshake parameters. Two shake frequencies per axis, plus magnitude - // as a fraction of a scene tile, and relative magnitudes for the frequencies - static const float kHorizShakeFreq1; - static const float kHorizShakeFreq2; - static const float kVertShakeFreq1; - static const float kVertShakeFreq2; - static const float kFreq1Magnitude; - static const float kFreq2Magnitude; - - static const float kShakeFraction; - - // RGB->YUV conversion - static const float kRgb2Yuv[12]; - - // Aperture of imaging lens - static const float kAperture; - - // Sun, moon illuminance levels in 2-hour increments. These don't match any - // real day anywhere. - static const uint32_t kTimeStep = 2; - static const float kSunlight[]; - static const float kMoonlight[]; - static const int kSunOverhead; - static const int kMoonOverhead; - - // Illumination levels for various conditions, in lux - static const float kDirectSunIllum; - static const float kDaylightShadeIllum; - static const float kSunsetIllum; - static const float kTwilightIllum; - static const float kFullMoonIllum; - static const float kClearNightIllum; - static const float kStarIllum; - static const float kLivingRoomIllum; - - // Chromaticity of various illumination sources - static const float kIncandescentXY[2]; - static const float kDirectSunlightXY[2]; - static const float kDaylightXY[2]; - static const float kNoonSkyXY[2]; - static const float kMoonlightXY[2]; - static const float kSunsetXY[2]; - - static const uint8_t kSelfLit; - static const uint8_t kShadowed; - static const uint8_t kSky; - - static const float kMaterials_xyY[NUM_MATERIALS][3]; - static const uint8_t kMaterialsFlags[NUM_MATERIALS]; - - static const int kSceneWidth; - static const int kSceneHeight; - static const uint8_t kScene[]; -}; - -} // namespace android - -#endif // HW_EMULATOR_CAMERA2_SCENE_H diff --git a/guest/hals/camera/fake-pipeline2/Sensor.cpp b/guest/hals/camera/fake-pipeline2/Sensor.cpp deleted file mode 100644 index f39bbbdd..00000000 --- a/guest/hals/camera/fake-pipeline2/Sensor.cpp +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -//#define LOG_NDEBUG 0 -//#define LOG_NNDEBUG 0 -#define LOG_TAG "EmulatedCamera2_Sensor" - -#ifdef LOG_NNDEBUG -#define ALOGVV(...) ALOGV(__VA_ARGS__) -#else -#define ALOGVV(...) ((void)0) -#endif - -#include <utils/Log.h> - -#include <cmath> -#include <cstdlib> -#include "../EmulatedFakeCamera2.h" -#include "Sensor.h" -#include "system/camera_metadata.h" - -namespace android { - -// const nsecs_t Sensor::kExposureTimeRange[2] = -// {1000L, 30000000000L} ; // 1 us - 30 sec -// const nsecs_t Sensor::kFrameDurationRange[2] = -// {33331760L, 30000000000L}; // ~1/30 s - 30 sec -const nsecs_t Sensor::kExposureTimeRange[2] = {1000L, - 300000000L}; // 1 us - 0.3 sec -const nsecs_t Sensor::kFrameDurationRange[2] = { - 33331760L, 300000000L}; // ~1/30 s - 0.3 sec - -const nsecs_t Sensor::kMinVerticalBlank = 10000L; - -const uint8_t Sensor::kColorFilterArrangement = - ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB; - -// Output image data characteristics -const uint32_t Sensor::kMaxRawValue = 4000; -const uint32_t Sensor::kBlackLevel = 1000; - -// Sensor sensitivity -const float Sensor::kSaturationVoltage = 0.520f; -const uint32_t Sensor::kSaturationElectrons = 2000; -const float Sensor::kVoltsPerLuxSecond = 0.100f; - -const float Sensor::kElectronsPerLuxSecond = Sensor::kSaturationElectrons / - Sensor::kSaturationVoltage * - Sensor::kVoltsPerLuxSecond; - -const float Sensor::kBaseGainFactor = - (float)Sensor::kMaxRawValue / Sensor::kSaturationElectrons; - -const float Sensor::kReadNoiseStddevBeforeGain = 1.177; // in electrons -const float Sensor::kReadNoiseStddevAfterGain = 2.100; // in digital counts -const float Sensor::kReadNoiseVarBeforeGain = - Sensor::kReadNoiseStddevBeforeGain * Sensor::kReadNoiseStddevBeforeGain; -const float Sensor::kReadNoiseVarAfterGain = - Sensor::kReadNoiseStddevAfterGain * Sensor::kReadNoiseStddevAfterGain; - -const int32_t Sensor::kSensitivityRange[2] = {100, 1600}; -const uint32_t Sensor::kDefaultSensitivity = 100; - -/** A few utility functions for math, normal distributions */ - -// Take advantage of IEEE floating-point format to calculate an approximate -// square root. Accurate to within +-3.6% -float sqrtf_approx(float r) { - // Modifier is based on IEEE floating-point representation; the - // manipulations boil down to finding approximate log2, dividing by two, and - // then inverting the log2. A bias is added to make the relative error - // symmetric about the real answer. - const int32_t modifier = 0x1FBB4000; - - int32_t r_i = *(int32_t *)(&r); - r_i = (r_i >> 1) + modifier; - - return *(float *)(&r_i); -} - -Sensor::Sensor(uint32_t width, uint32_t height) - : Thread(false), - mResolution{width, height}, - mActiveArray{0, 0, width, height}, - mRowReadoutTime(kFrameDurationRange[0] / height), - mGotVSync(false), - mExposureTime(kFrameDurationRange[0] - kMinVerticalBlank), - mFrameDuration(kFrameDurationRange[0]), - mGainFactor(kDefaultSensitivity), - mNextBuffers(NULL), - mFrameNumber(0), - mCapturedBuffers(NULL), - mListener(NULL), - mScene(width, height, kElectronsPerLuxSecond) { - ALOGV("Sensor created with pixel array %d x %d", width, height); -} - -Sensor::~Sensor() { shutDown(); } - -status_t Sensor::startUp() { - ALOGV("%s: E", __FUNCTION__); - - int res; - mCapturedBuffers = NULL; - res = run("EmulatedFakeCamera2::Sensor", ANDROID_PRIORITY_URGENT_DISPLAY); - - if (res != OK) { - ALOGE("Unable to start up sensor capture thread: %d", res); - } - return res; -} - -status_t Sensor::shutDown() { - ALOGV("%s: E", __FUNCTION__); - - int res; - res = requestExitAndWait(); - if (res != OK) { - ALOGE("Unable to shut down sensor capture thread: %d", res); - } - return res; -} - -Scene &Sensor::getScene() { return mScene; } - -void Sensor::setExposureTime(uint64_t ns) { - Mutex::Autolock lock(mControlMutex); - ALOGVV("Exposure set to %f", ns / 1000000.f); - mExposureTime = ns; -} - -void Sensor::setFrameDuration(uint64_t ns) { - Mutex::Autolock lock(mControlMutex); - ALOGVV("Frame duration set to %f", ns / 1000000.f); - mFrameDuration = ns; -} - -void Sensor::setSensitivity(uint32_t gain) { - Mutex::Autolock lock(mControlMutex); - ALOGVV("Gain set to %d", gain); - mGainFactor = gain; -} - -void Sensor::setDestinationBuffers(Buffers *buffers) { - Mutex::Autolock lock(mControlMutex); - mNextBuffers = buffers; -} - -void Sensor::setFrameNumber(uint32_t frameNumber) { - Mutex::Autolock lock(mControlMutex); - mFrameNumber = frameNumber; -} - -bool Sensor::waitForVSync(nsecs_t reltime) { - int res; - Mutex::Autolock lock(mControlMutex); - - mGotVSync = false; - res = mVSync.waitRelative(mControlMutex, reltime); - if (res != OK && res != TIMED_OUT) { - ALOGE("%s: Error waiting for VSync signal: %d", __FUNCTION__, res); - return false; - } - return mGotVSync; -} - -bool Sensor::waitForNewFrame(nsecs_t reltime, nsecs_t *captureTime) { - Mutex::Autolock lock(mReadoutMutex); - - if (mCapturedBuffers == NULL) { - int res; - res = mReadoutAvailable.waitRelative(mReadoutMutex, reltime); - if (res == TIMED_OUT) { - return false; - } else if (res != OK || mCapturedBuffers == NULL) { - ALOGE("Error waiting for sensor readout signal: %d", res); - return false; - } - } - mReadoutComplete.signal(); - - *captureTime = mCaptureTime; - mCapturedBuffers = NULL; - return true; -} - -Sensor::SensorListener::~SensorListener() {} - -void Sensor::setSensorListener(SensorListener *listener) { - Mutex::Autolock lock(mControlMutex); - mListener = listener; -} - -status_t Sensor::readyToRun() { - ALOGV("Starting up sensor thread"); - mStartupTime = systemTime(); - mNextCaptureTime = 0; - mNextCapturedBuffers = NULL; - return OK; -} - -bool Sensor::threadLoop() { - /** - * Sensor capture operation main loop. - * - * Stages are out-of-order relative to a single frame's processing, but - * in-order in time. - */ - - /** - * Stage 1: Read in latest control parameters - */ - uint64_t exposureDuration; - uint64_t frameDuration; - uint32_t gain; - Buffers *nextBuffers; - uint32_t frameNumber; - SensorListener *listener = NULL; - { - Mutex::Autolock lock(mControlMutex); - exposureDuration = mExposureTime; - frameDuration = mFrameDuration; - gain = mGainFactor; - nextBuffers = mNextBuffers; - frameNumber = mFrameNumber; - listener = mListener; - // Don't reuse a buffer set - mNextBuffers = NULL; - - // Signal VSync for start of readout - ALOGVV("Sensor VSync"); - mGotVSync = true; - mVSync.signal(); - } - - /** - * Stage 3: Read out latest captured image - */ - - Buffers *capturedBuffers = NULL; - nsecs_t captureTime = 0; - - nsecs_t startRealTime = systemTime(); - // Stagefright cares about system time for timestamps, so base simulated - // time on that. - nsecs_t simulatedTime = startRealTime; - nsecs_t frameEndRealTime = startRealTime + frameDuration; - - if (mNextCapturedBuffers != NULL) { - ALOGVV("Sensor starting readout"); - // Pretend we're doing readout now; will signal once enough time has elapsed - capturedBuffers = mNextCapturedBuffers; - captureTime = mNextCaptureTime; - } - simulatedTime += mRowReadoutTime + kMinVerticalBlank; - - // TODO: Move this signal to another thread to simulate readout - // time properly - if (capturedBuffers != NULL) { - ALOGVV("Sensor readout complete"); - Mutex::Autolock lock(mReadoutMutex); - if (mCapturedBuffers != NULL) { - ALOGV("Waiting for readout thread to catch up!"); - mReadoutComplete.wait(mReadoutMutex); - } - - mCapturedBuffers = capturedBuffers; - mCaptureTime = captureTime; - mReadoutAvailable.signal(); - capturedBuffers = NULL; - } - - /** - * Stage 2: Capture new image - */ - mNextCaptureTime = simulatedTime; - mNextCapturedBuffers = nextBuffers; - - if (mNextCapturedBuffers != NULL) { - if (listener != NULL) { - listener->onSensorEvent(frameNumber, SensorListener::EXPOSURE_START, - mNextCaptureTime); - } - ALOGVV("Starting next capture: Exposure: %f ms, gain: %d", - (float)exposureDuration / 1e6, gain); - mScene.setExposureDuration((float)exposureDuration / 1e9); - mScene.calculateScene(mNextCaptureTime); - - // Might be adding more buffers, so size isn't constant - for (size_t i = 0; i < mNextCapturedBuffers->size(); i++) { - const StreamBuffer &b = (*mNextCapturedBuffers)[i]; - ALOGVV( - "Sensor capturing buffer %d: stream %d," - " %d x %d, format %x, stride %d, buf %p, img %p", - i, b.streamId, b.width, b.height, b.format, b.stride, b.buffer, - b.img); - switch (b.format) { - case HAL_PIXEL_FORMAT_RAW16: - captureRaw(b.img, gain, b.stride); - break; - case HAL_PIXEL_FORMAT_RGB_888: - captureRGB(b.img, gain, b.stride); - break; - case HAL_PIXEL_FORMAT_RGBA_8888: - captureRGBA(b.img, gain, b.stride); - break; - case HAL_PIXEL_FORMAT_BLOB: -#if defined HAL_DATASPACE_DEPTH - if (b.dataSpace != HAL_DATASPACE_DEPTH) { -#endif - // Add auxillary buffer of the right size - // Assumes only one BLOB (JPEG) buffer in - // mNextCapturedBuffers - StreamBuffer bAux; - bAux.streamId = 0; - bAux.width = b.width; - bAux.height = b.height; - bAux.format = HAL_PIXEL_FORMAT_RGB_888; - bAux.stride = b.width; - bAux.buffer = NULL; - // TODO: Reuse these - bAux.img = new uint8_t[b.width * b.height * 3]; - mNextCapturedBuffers->push_back(bAux); -#if defined HAL_DATASPACE_DEPTH - } else { - captureDepthCloud(b.img); - } -#endif - break; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YCbCr_420_888: - captureNV21(b.img, gain, b.stride); - break; - case HAL_PIXEL_FORMAT_YV12: - // TODO: - ALOGE("%s: Format %x is TODO", __FUNCTION__, b.format); - break; - case HAL_PIXEL_FORMAT_Y16: - captureDepth(b.img, gain, b.stride); - break; - default: - ALOGE("%s: Unknown format %x, no output", __FUNCTION__, b.format); - break; - } - } - } - - ALOGVV("Sensor vertical blanking interval"); - nsecs_t workDoneRealTime = systemTime(); - const nsecs_t timeAccuracy = 2e6; // 2 ms of imprecision is ok - if (workDoneRealTime < frameEndRealTime - timeAccuracy) { - timespec t; - t.tv_sec = (frameEndRealTime - workDoneRealTime) / 1000000000L; - t.tv_nsec = (frameEndRealTime - workDoneRealTime) % 1000000000L; - - int ret; - do { - ret = nanosleep(&t, &t); - } while (ret != 0); - } - nsecs_t endRealTime __unused = systemTime(); - ALOGVV("Frame cycle took %d ms, target %d ms", - (int)((endRealTime - startRealTime) / 1000000), - (int)(frameDuration / 1000000)); - return true; -}; - -void Sensor::captureRaw(uint8_t *img, uint32_t gain, uint32_t stride) { - float totalGain = gain / 100.0 * kBaseGainFactor; - float noiseVarGain = totalGain * totalGain; - float readNoiseVar = - kReadNoiseVarBeforeGain * noiseVarGain + kReadNoiseVarAfterGain; - - int bayerSelect[4] = {Scene::R, Scene::Gr, Scene::Gb, Scene::B}; // RGGB - mScene.setReadoutPixel(0, 0); - for (unsigned int y = 0; y < mResolution[1]; y++) { - int *bayerRow = bayerSelect + (y & 0x1) * 2; - uint16_t *px = (uint16_t *)img + y * stride; - for (unsigned int x = 0; x < mResolution[0]; x++) { - uint32_t electronCount; - electronCount = mScene.getPixelElectrons()[bayerRow[x & 0x1]]; - - // TODO: Better pixel saturation curve? - electronCount = (electronCount < kSaturationElectrons) - ? electronCount - : kSaturationElectrons; - - // TODO: Better A/D saturation curve? - uint16_t rawCount = electronCount * totalGain; - rawCount = (rawCount < kMaxRawValue) ? rawCount : kMaxRawValue; - - // Calculate noise value - // TODO: Use more-correct Gaussian instead of uniform noise - float photonNoiseVar = electronCount * noiseVarGain; - float noiseStddev = sqrtf_approx(readNoiseVar + photonNoiseVar); - // Scaled to roughly match gaussian/uniform noise stddev - float noiseSample = std::rand() * (2.5 / (1.0 + RAND_MAX)) - 1.25; - - rawCount += kBlackLevel; - rawCount += noiseStddev * noiseSample; - - *px++ = rawCount; - } - // TODO: Handle this better - // simulatedTime += mRowReadoutTime; - } - ALOGVV("Raw sensor image captured"); -} - -void Sensor::captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride) { - float totalGain = gain / 100.0 * kBaseGainFactor; - // In fixed-point math, calculate total scaling from electrons to 8bpp - int scale64x = 64 * totalGain * 255 / kMaxRawValue; - uint32_t inc = ceil((float)mResolution[0] / stride); - - for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++) { - uint8_t *px = img + outY * stride * 4; - mScene.setReadoutPixel(0, y); - for (unsigned int x = 0; x < mResolution[0]; x += inc) { - uint32_t rCount, gCount, bCount; - // TODO: Perfect demosaicing is a cheat - const uint32_t *pixel = mScene.getPixelElectrons(); - rCount = pixel[Scene::R] * scale64x; - gCount = pixel[Scene::Gr] * scale64x; - bCount = pixel[Scene::B] * scale64x; - - *px++ = rCount < 255 * 64 ? rCount / 64 : 255; - *px++ = gCount < 255 * 64 ? gCount / 64 : 255; - *px++ = bCount < 255 * 64 ? bCount / 64 : 255; - *px++ = 255; - for (unsigned int j = 1; j < inc; j++) mScene.getPixelElectrons(); - } - // TODO: Handle this better - // simulatedTime += mRowReadoutTime; - } - ALOGVV("RGBA sensor image captured"); -} - -void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) { - float totalGain = gain / 100.0 * kBaseGainFactor; - // In fixed-point math, calculate total scaling from electrons to 8bpp - int scale64x = 64 * totalGain * 255 / kMaxRawValue; - uint32_t inc = ceil((float)mResolution[0] / stride); - - for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++) { - mScene.setReadoutPixel(0, y); - uint8_t *px = img + outY * stride * 3; - for (unsigned int x = 0; x < mResolution[0]; x += inc) { - uint32_t rCount, gCount, bCount; - // TODO: Perfect demosaicing is a cheat - const uint32_t *pixel = mScene.getPixelElectrons(); - rCount = pixel[Scene::R] * scale64x; - gCount = pixel[Scene::Gr] * scale64x; - bCount = pixel[Scene::B] * scale64x; - - *px++ = rCount < 255 * 64 ? rCount / 64 : 255; - *px++ = gCount < 255 * 64 ? gCount / 64 : 255; - *px++ = bCount < 255 * 64 ? bCount / 64 : 255; - for (unsigned int j = 1; j < inc; j++) mScene.getPixelElectrons(); - } - // TODO: Handle this better - // simulatedTime += mRowReadoutTime; - } - ALOGVV("RGB sensor image captured"); -} - -void Sensor::captureNV21(uint8_t *img, uint32_t gain, uint32_t stride) { - float totalGain = gain / 100.0 * kBaseGainFactor; - // Using fixed-point math with 6 bits of fractional precision. - // In fixed-point math, calculate total scaling from electrons to 8bpp - const int scale64x = 64 * totalGain * 255 / kMaxRawValue; - // In fixed-point math, saturation point of sensor after gain - const int saturationPoint = 64 * 255; - // Fixed-point coefficients for RGB-YUV transform - // Based on JFIF RGB->YUV transform. - // Cb/Cr offset scaled by 64x twice since they're applied post-multiply - const int rgbToY[] = {19, 37, 7}; - const int rgbToCb[] = {-10, -21, 32, 524288}; - const int rgbToCr[] = {32, -26, -5, 524288}; - // Scale back to 8bpp non-fixed-point - const int scaleOut = 64; - const int scaleOutSq = scaleOut * scaleOut; // after multiplies - - // inc = how many pixels to skip while reading every next pixel - // horizontally. - uint32_t inc = ceil((float)mResolution[0] / stride); - // outH = projected vertical resolution based on stride. - uint32_t outH = mResolution[1] / inc; - for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++) { - uint8_t *pxY = img + outY * stride; - uint8_t *pxVU = img + (outH + outY / 2) * stride; - mScene.setReadoutPixel(0, y); - for (unsigned int outX = 0; outX < stride; outX++) { - int32_t rCount, gCount, bCount; - // TODO: Perfect demosaicing is a cheat - const uint32_t *pixel = mScene.getPixelElectrons(); - rCount = pixel[Scene::R] * scale64x; - rCount = rCount < saturationPoint ? rCount : saturationPoint; - gCount = pixel[Scene::Gr] * scale64x; - gCount = gCount < saturationPoint ? gCount : saturationPoint; - bCount = pixel[Scene::B] * scale64x; - bCount = bCount < saturationPoint ? bCount : saturationPoint; - - *pxY++ = (rgbToY[0] * rCount + rgbToY[1] * gCount + rgbToY[2] * bCount) / - scaleOutSq; - if (outY % 2 == 0 && outX % 2 == 0) { - *pxVU++ = (rgbToCb[0] * rCount + rgbToCb[1] * gCount + - rgbToCb[2] * bCount + rgbToCb[3]) / - scaleOutSq; - *pxVU++ = (rgbToCr[0] * rCount + rgbToCr[1] * gCount + - rgbToCr[2] * bCount + rgbToCr[3]) / - scaleOutSq; - } - - // Skip unprocessed pixels from sensor. - for (unsigned int j = 1; j < inc; j++) mScene.getPixelElectrons(); - } - } - ALOGVV("NV21 sensor image captured"); -} - -void Sensor::captureDepth(uint8_t *img, uint32_t gain, uint32_t stride) { - float totalGain = gain / 100.0 * kBaseGainFactor; - // In fixed-point math, calculate scaling factor to 13bpp millimeters - int scale64x = 64 * totalGain * 8191 / kMaxRawValue; - uint32_t inc = ceil((float)mResolution[0] / stride); - - for (unsigned int y = 0, outY = 0; y < mResolution[1]; y += inc, outY++) { - mScene.setReadoutPixel(0, y); - uint16_t *px = ((uint16_t *)img) + outY * stride; - for (unsigned int x = 0; x < mResolution[0]; x += inc) { - uint32_t depthCount; - // TODO: Make up real depth scene instead of using green channel - // as depth - const uint32_t *pixel = mScene.getPixelElectrons(); - depthCount = pixel[Scene::Gr] * scale64x; - - *px++ = depthCount < 8191 * 64 ? depthCount / 64 : 0; - for (unsigned int j = 1; j < inc; j++) mScene.getPixelElectrons(); - } - // TODO: Handle this better - // simulatedTime += mRowReadoutTime; - } - ALOGVV("Depth sensor image captured"); -} - -void Sensor::captureDepthCloud(uint8_t * /*img*/) { -#if defined HAL_DATASPACE_DEPTH - android_depth_points *cloud = reinterpret_cast<android_depth_points *>(img); - - cloud->num_points = 16; - - // TODO: Create point cloud values that match RGB scene - const int FLOATS_PER_POINT = 4; - const float JITTER_STDDEV = 0.1f; - for (size_t y = 0, i = 0; y < 4; y++) { - for (size_t x = 0; x < 4; x++, i++) { - float randSampleX = std::rand() * (2.5f / (1.0f + RAND_MAX)) - 1.25f; - randSampleX *= JITTER_STDDEV; - - float randSampleY = std::rand() * (2.5f / (1.0f + RAND_MAX)) - 1.25f; - randSampleY *= JITTER_STDDEV; - - float randSampleZ = std::rand() * (2.5f / (1.0f + RAND_MAX)) - 1.25f; - randSampleZ *= JITTER_STDDEV; - - cloud->xyzc_points[i * FLOATS_PER_POINT + 0] = x - 1.5f + randSampleX; - cloud->xyzc_points[i * FLOATS_PER_POINT + 1] = y - 1.5f + randSampleY; - cloud->xyzc_points[i * FLOATS_PER_POINT + 2] = 3.f + randSampleZ; - cloud->xyzc_points[i * FLOATS_PER_POINT + 3] = 0.8f; - } - } - - ALOGVV("Depth point cloud captured"); -#endif -} - -} // namespace android diff --git a/guest/hals/camera/fake-pipeline2/Sensor.h b/guest/hals/camera/fake-pipeline2/Sensor.h deleted file mode 100644 index 326af297..00000000 --- a/guest/hals/camera/fake-pipeline2/Sensor.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2012 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. - */ - -/** - * This class is a simple simulation of a typical CMOS cellphone imager chip, - * which outputs 12-bit Bayer-mosaic raw images. - * - * Unlike most real image sensors, this one's native color space is linear sRGB. - * - * The sensor is abstracted as operating as a pipeline 3 stages deep; - * conceptually, each frame to be captured goes through these three stages. The - * processing step for the sensor is marked off by vertical sync signals, which - * indicate the start of readout of the oldest frame. The interval between - * processing steps depends on the frame duration of the frame currently being - * captured. The stages are 1) configure, 2) capture, and 3) readout. During - * configuration, the sensor's registers for settings such as exposure time, - * frame duration, and gain are set for the next frame to be captured. In stage - * 2, the image data for the frame is actually captured by the sensor. Finally, - * in stage 3, the just-captured data is read out and sent to the rest of the - * system. - * - * The sensor is assumed to be rolling-shutter, so low-numbered rows of the - * sensor are exposed earlier in time than larger-numbered rows, with the time - * offset between each row being equal to the row readout time. - * - * The characteristics of this sensor don't correspond to any actual sensor, - * but are not far off typical sensors. - * - * Example timing diagram, with three frames: - * Frame 0-1: Frame duration 50 ms, exposure time 20 ms. - * Frame 2: Frame duration 75 ms, exposure time 65 ms. - * Legend: - * C = update sensor registers for frame - * v = row in reset (vertical blanking interval) - * E = row capturing image data - * R = row being read out - * | = vertical sync signal - *time(ms)| 0 55 105 155 230 270 - * Frame 0| :configure : capture : readout : : : - * Row # | ..|CCCC______|_________|_________| : : - * 0 | :\ \vvvvvEEEER \ : : - * 500 | : \ \vvvvvEEEER \ : : - * 1000 | : \ \vvvvvEEEER \ : : - * 1500 | : \ \vvvvvEEEER \ : : - * 2000 | : \__________\vvvvvEEEER_________\ : : - * Frame 1| : configure capture readout : : - * Row # | : |CCCC_____|_________|______________| : - * 0 | : :\ \vvvvvEEEER \ : - * 500 | : : \ \vvvvvEEEER \ : - * 1000 | : : \ \vvvvvEEEER \ : - * 1500 | : : \ \vvvvvEEEER \ : - * 2000 | : : \_________\vvvvvEEEER______________\ : - * Frame 2| : : configure capture readout: - * Row # | : : |CCCC_____|______________|_______|... - * 0 | : : :\ \vEEEEEEEEEEEEER \ - * 500 | : : : \ \vEEEEEEEEEEEEER \ - * 1000 | : : : \ \vEEEEEEEEEEEEER \ - * 1500 | : : : \ \vEEEEEEEEEEEEER \ - * 2000 | : : : \_________\vEEEEEEEEEEEEER_______\ - */ - -#ifndef HW_EMULATOR_CAMERA2_SENSOR_H -#define HW_EMULATOR_CAMERA2_SENSOR_H - -#include "utils/Mutex.h" -#include "utils/Thread.h" -#include "utils/Timers.h" - -#include "Base.h" -#include "Scene.h" - -namespace android { - -class EmulatedFakeCamera2; - -class Sensor : private Thread, public virtual RefBase { - public: - // width: Width of pixel array - // height: Height of pixel array - Sensor(uint32_t width, uint32_t height); - ~Sensor(); - - /* - * Power control - */ - - status_t startUp(); - status_t shutDown(); - - /* - * Access to scene - */ - Scene &getScene(); - - /* - * Controls that can be updated every frame - */ - - void setExposureTime(uint64_t ns); - void setFrameDuration(uint64_t ns); - void setSensitivity(uint32_t gain); - // Buffer must be at least stride*height*2 bytes in size - void setDestinationBuffers(Buffers *buffers); - // To simplify tracking sensor's current frame - void setFrameNumber(uint32_t frameNumber); - - /* - * Controls that cause reconfiguration delay - */ - - void setBinning(int horizontalFactor, int verticalFactor); - - /* - * Synchronizing with sensor operation (vertical sync) - */ - - // Wait until the sensor outputs its next vertical sync signal, meaning it - // is starting readout of its latest frame of data. Returns true if vertical - // sync is signaled, false if the wait timed out. - bool waitForVSync(nsecs_t reltime); - - // Wait until a new frame has been read out, and then return the time - // capture started. May return immediately if a new frame has been pushed - // since the last wait for a new frame. Returns true if new frame is - // returned, false if timed out. - bool waitForNewFrame(nsecs_t reltime, nsecs_t *captureTime); - - /* - * Interrupt event servicing from the sensor. Only triggers for sensor - * cycles that have valid buffers to write to. - */ - struct SensorListener { - enum Event { - EXPOSURE_START, // Start of exposure - }; - - virtual void onSensorEvent(uint32_t frameNumber, Event e, - nsecs_t timestamp) = 0; - virtual ~SensorListener(); - }; - - void setSensorListener(SensorListener *listener); - - /** - * Static sensor characteristics - */ - const uint32_t mResolution[2]; - const uint32_t mActiveArray[4]; - - static const nsecs_t kExposureTimeRange[2]; - static const nsecs_t kFrameDurationRange[2]; - static const nsecs_t kMinVerticalBlank; - - static const uint8_t kColorFilterArrangement; - - // Output image data characteristics - static const uint32_t kMaxRawValue; - static const uint32_t kBlackLevel; - // Sensor sensitivity, approximate - - static const float kSaturationVoltage; - static const uint32_t kSaturationElectrons; - static const float kVoltsPerLuxSecond; - static const float kElectronsPerLuxSecond; - - static const float kBaseGainFactor; - - static const float kReadNoiseStddevBeforeGain; // In electrons - static const float kReadNoiseStddevAfterGain; // In raw digital units - static const float kReadNoiseVarBeforeGain; - static const float kReadNoiseVarAfterGain; - - // While each row has to read out, reset, and then expose, the (reset + - // expose) sequence can be overlapped by other row readouts, so the final - // minimum frame duration is purely a function of row readout time, at least - // if there's a reasonable number of rows. - const nsecs_t mRowReadoutTime; - - static const int32_t kSensitivityRange[2]; - static const uint32_t kDefaultSensitivity; - - private: - Mutex mControlMutex; // Lock before accessing control parameters - // Start of control parameters - Condition mVSync; - bool mGotVSync; - uint64_t mExposureTime; - uint64_t mFrameDuration; - uint32_t mGainFactor; - Buffers *mNextBuffers; - uint32_t mFrameNumber; - - // End of control parameters - - Mutex mReadoutMutex; // Lock before accessing readout variables - // Start of readout variables - Condition mReadoutAvailable; - Condition mReadoutComplete; - Buffers *mCapturedBuffers; - nsecs_t mCaptureTime; - SensorListener *mListener; - // End of readout variables - - // Time of sensor startup, used for simulation zero-time point - nsecs_t mStartupTime; - - /** - * Inherited Thread virtual overrides, and members only used by the - * processing thread - */ - private: - virtual status_t readyToRun(); - - virtual bool threadLoop(); - - nsecs_t mNextCaptureTime; - Buffers *mNextCapturedBuffers; - - Scene mScene; - - void captureRaw(uint8_t *img, uint32_t gain, uint32_t stride); - void captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride); - void captureRGB(uint8_t *img, uint32_t gain, uint32_t stride); - void captureNV21(uint8_t *img, uint32_t gain, uint32_t stride); - void captureDepth(uint8_t *img, uint32_t gain, uint32_t stride); - void captureDepthCloud(uint8_t *img); -}; - -} // namespace android - -#endif // HW_EMULATOR_CAMERA2_SENSOR_H diff --git a/guest/hals/gps/Android.bp b/guest/hals/gps/Android.bp deleted file mode 100644 index 22c5998b..00000000 --- a/guest/hals/gps/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2017 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. - -// HAL module implemenation, not prelinked and stored in -// hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so -cc_library_shared { - name: "gps.cutf", - relative_install_path: "hw", - srcs: [ - "gps_vsoc.cpp", - "gps_thread.cpp", - ], - shared_libs: [ - "liblog", - "libcutils", - ], - header_libs: ["libhardware_headers"], - cflags: [ - "-Wno-missing-field-initializers", - "-DLOG_TAG=\"VSoCGPS\"", - ], - defaults: ["cuttlefish_guest_only"], -} diff --git a/guest/hals/gps/gps_thread.cpp b/guest/hals/gps/gps_thread.cpp deleted file mode 100644 index cea830cb..00000000 --- a/guest/hals/gps/gps_thread.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "guest/hals/gps/gps_thread.h" - -#include <errno.h> -#include <fcntl.h> -#include <math.h> -#include <pthread.h> -#include <sys/epoll.h> -#include <time.h> -#include <unistd.h> - -#include <log/log.h> -#include <cutils/sockets.h> -#include <hardware/gps.h> - -// Calls an callback function to pass received and parsed GPS data to Android. -static void reader_call_callback(GpsDataReader* r) { - if (!r) { - ALOGW("%s: called with r=NULL", __FUNCTION__); - return; - } - if (!r->callback) { - ALOGW("%s: no callback registered; keeping the data to send later", - __FUNCTION__); - return; - } - if (!r->fix.flags) { - ALOGW("%s: no GPS fix", __FUNCTION__); - return; - } - // Always uses current time converted to UTC time in milliseconds. - time_t secs = time(NULL); // seconds from 01/01/1970. - r->fix.timestamp = (long long)secs * 1000; - -#if GPS_DEBUG - D("* Parsed GPS Data"); - if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) { - D(" - latitude = %g", r->fix.latitude); - D(" - longitude = %g", r->fix.longitude); - } - if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) - D(" - altitude = %g", r->fix.altitude); - if (r->fix.flags & GPS_LOCATION_HAS_SPEED) D(" - speed = %g", r->fix.speed); - if (r->fix.flags & GPS_LOCATION_HAS_BEARING) - D(" - bearing = %g", r->fix.bearing); - if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) - D(" - accuracy = %g", r->fix.accuracy); - long long utc_secs = r->fix.timestamp / 1000; - struct tm utc; - gmtime_r((time_t*)&utc_secs, &utc); - D(" - time = %s", asctime(&utc)); -#endif - - D("Sending fix to callback %p", r->callback); - r->callback(&r->fix); -} - -// Parses data received so far and calls reader_call_callback(). -static void reader_parse_message(GpsDataReader* r) { - D("Received: '%s'", r->buffer); - - int num_read = sscanf(r->buffer, "%lf,%lf,%lf,%f,%f,%f", &r->fix.longitude, - &r->fix.latitude, &r->fix.altitude, &r->fix.bearing, - &r->fix.speed, &r->fix.accuracy); - if (num_read != 6) { - ALOGE("Couldn't find 6 values from the received message %s.", r->buffer); - return; - } - r->fix.flags = DEFAULT_GPS_LOCATION_FLAG; - reader_call_callback(r); -} - -// Accepts a newly received string & calls reader_parse_message if '\n' is seen. -static void reader_accept_string(GpsDataReader* r, char* const str, - const int len) { - int index; - for (index = 0; index < len; index++) { - if (r->index >= (int)sizeof(r->buffer) - 1) { - if (str[index] == '\n') { - ALOGW("Message longer than buffer; new byte (%d) skipped.", str[index]); - r->index = 0; - } - } else { - r->buffer[r->index++] = str[index]; - if (str[index] == '\n') { - r->buffer[r->index] = '\0'; - reader_parse_message(r); - r->index = 0; - } - } - } -} - -// GPS state threads which communicates with control and data sockets. -void gps_state_thread(void* arg) { - GpsState* state = (GpsState*)arg; - GpsDataReader reader; - int epoll_fd = epoll_create(2); - int started = -1; - int gps_fd = state->fd; - int control_fd = state->control[1]; - - memset(&reader, 0, sizeof(reader)); - reader.fix.size = sizeof(reader.fix); - - epoll_register(epoll_fd, control_fd); - epoll_register(epoll_fd, gps_fd); - - while (1) { - struct epoll_event events[2]; - int nevents, event_index; - - nevents = epoll_wait(epoll_fd, events, 2, 500); - D("Thread received %d events", nevents); - if (nevents < 0) { - if (errno != EINTR) - ALOGE("epoll_wait() unexpected error: %s", strerror(errno)); - continue; - } else if (nevents == 0) { - if (started == 1) { - reader_call_callback(&reader); - } - continue; - } - - for (event_index = 0; event_index < nevents; event_index++) { - if ((events[event_index].events & (EPOLLERR | EPOLLHUP)) != 0) { - ALOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?"); - goto Exit; - } - - if ((events[event_index].events & EPOLLIN) != 0) { - int fd = events[event_index].data.fd; - if (fd == control_fd) { - unsigned char cmd = 255; - int ret; - do { - ret = read(fd, &cmd, 1); - } while (ret < 0 && errno == EINTR); - - if (cmd == CMD_STOP || cmd == CMD_QUIT) { - if (started == 1) { - D("Thread stopping"); - started = 0; - reader.callback = NULL; - } - if (cmd == CMD_QUIT) { - D("Thread quitting"); - goto Exit; - } - } else if (cmd == CMD_START) { - if (started != 1) { - reader.callback = state->callbacks.location_cb; - D("Thread starting callback=%p", reader.callback); - reader_call_callback(&reader); - started = 1; - } - } else { - ALOGE("unknown control command %d", cmd); - } - } else if (fd == gps_fd) { - char buff[256]; - int ret; - for (;;) { - ret = read(fd, buff, sizeof(buff)); - if (ret < 0) { - if (errno == EINTR) continue; - if (errno != EWOULDBLOCK) - ALOGE("error while reading from gps daemon socket: %s:", - strerror(errno)); - break; - } - D("Thread received %d bytes: %.*s", ret, ret, buff); - reader_accept_string(&reader, buff, ret); - } - } else { - ALOGE("epoll_wait() returned unknown fd %d.", fd); - } - } - } - } - -Exit: - epoll_deregister(epoll_fd, control_fd); - epoll_deregister(epoll_fd, gps_fd); -} diff --git a/guest/hals/gps/gps_thread.h b/guest/hals/gps/gps_thread.h deleted file mode 100644 index 7cd3c9ea..00000000 --- a/guest/hals/gps/gps_thread.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <errno.h> -#include <fcntl.h> -#include <sys/epoll.h> - -#include <hardware/gps.h> - -#define GPS_DEBUG 0 -#define GPS_DATA_BUFFER_MAX_SIZE 256 - -#define DEFAULT_GPS_LOCATION_FLAG \ - (GPS_LOCATION_HAS_LAT_LONG | GPS_LOCATION_HAS_ALTITUDE | \ - GPS_LOCATION_HAS_BEARING | GPS_LOCATION_HAS_SPEED | \ - GPS_LOCATION_HAS_ACCURACY) - -#if GPS_DEBUG -#define D(...) ALOGD(__VA_ARGS__) -#else -#define D(...) ((void)0) -#endif - -// Control commands to GPS thread -enum { CMD_QUIT = 0, CMD_START = 1, CMD_STOP = 2 }; - -// GPS HAL's state -typedef struct { - int init; - int fd; - int control[2]; - pthread_t thread; - GpsCallbacks callbacks; -} GpsState; - -typedef struct { - GpsLocation fix; - gps_location_callback callback; - char buffer[GPS_DATA_BUFFER_MAX_SIZE + 1]; - int index; -} GpsDataReader; - -void gps_state_thread(void* arg); - -static inline int epoll_register(int epoll_fd, int fd) { - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); - - struct epoll_event ev; - ev.events = EPOLLIN; - ev.data.fd = fd; - - int ret; - do { - ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev); - } while (ret < 0 && errno == EINTR); - return ret; -} - -static inline int epoll_deregister(int epoll_fd, int fd) { - int ret; - do { - ret = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); - } while (ret < 0 && errno == EINTR); - return ret; -} diff --git a/guest/hals/gps/gps_vsoc.cpp b/guest/hals/gps/gps_vsoc.cpp deleted file mode 100644 index 94bfce4f..00000000 --- a/guest/hals/gps/gps_vsoc.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -/* This implements a GPS hardware HAL library for cuttlefish. - * A produced shared library is placed in /system/lib/hw/gps.gce.so, and - * loaded by hardware/libhardware/hardware.c code which is called from - * android_location_GpsLocationProvider.cpp - */ - -#include <errno.h> -#include <pthread.h> -#include <stdint.h> -#include <unistd.h> -#include <inttypes.h> - -#include <log/log.h> -#include <cutils/sockets.h> -#include <hardware/gps.h> - -#include "guest/hals/gps/gps_thread.h" - -static GpsState _gps_state; - -// Cleans up GpsState data structure. -static void gps_state_cleanup(GpsState* s) { - char cmd = CMD_QUIT; - - write(s->control[0], &cmd, 1); - if (s->thread > 0) { - pthread_join(s->thread, NULL); - } - - close(s->control[0]); - close(s->control[1]); - close(s->fd); - - s->thread = 0; - s->control[0] = -1; - s->control[1] = -1; - s->fd = -1; - s->init = 0; -} - -static int gce_gps_init(GpsCallbacks* callbacks) { - D("%s: called", __FUNCTION__); - // Stop if the framework does not fulfill its interface contract. - // We don't want to return an error and continue to ensure that we - // catch framework breaks ASAP and to give a tombstone to track down the - // offending code. - LOG_ALWAYS_FATAL_IF(!callbacks->location_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->status_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->sv_status_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->nmea_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->set_capabilities_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->acquire_wakelock_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->release_wakelock_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->create_thread_cb); - LOG_ALWAYS_FATAL_IF(!callbacks->request_utc_time_cb); - if (!_gps_state.init) { - _gps_state.init = 1; - _gps_state.control[0] = -1; - _gps_state.control[1] = -1; - _gps_state.thread = 0; - - _gps_state.fd = socket_local_client( - "gps_broadcasts", ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - if (_gps_state.fd < 0) { - ALOGE("no GPS emulation detected."); - goto Fail; - } - D("GPS HAL will receive data from remoter via gps_broadcasts channel."); - - if (socketpair(AF_LOCAL, SOCK_STREAM, 0, _gps_state.control) < 0) { - ALOGE("could not create thread control socket pair: %s", strerror(errno)); - goto Fail; - } - - _gps_state.callbacks = *callbacks; - ALOGE("Starting thread callback=%p", callbacks->location_cb); - _gps_state.thread = callbacks->create_thread_cb( - "gps_state_thread", gps_state_thread, &_gps_state); - if (!_gps_state.thread) { - ALOGE("could not create GPS thread: %s", strerror(errno)); - goto Fail; - } - } - - if (_gps_state.fd < 0) return -1; - return 0; - -Fail: - gps_state_cleanup(&_gps_state); - return -1; -} - -static void gce_gps_cleanup() { - D("%s: called", __FUNCTION__); - if (_gps_state.init) gps_state_cleanup(&_gps_state); -} - -static int gce_gps_start() { - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return -1; - } - - char cmd = CMD_START; - int ret; - do { - ret = write(_gps_state.control[0], &cmd, 1); - } while (ret < 0 && errno == EINTR); - - if (ret != 1) { - D("%s: could not send CMD_START command: ret=%d: %s", __FUNCTION__, ret, - strerror(errno)); - return -1; - } - - return 0; -} - -static int gce_gps_stop() { - D("%s: called", __FUNCTION__); - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return -1; - } - - char cmd = CMD_STOP; - int ret; - - do { - ret = write(_gps_state.control[0], &cmd, 1); - } while (ret < 0 && errno == EINTR); - - if (ret != 1) { - ALOGE("%s: could not send CMD_STOP command: ret=%d: %s", __FUNCTION__, ret, - strerror(errno)); - return -1; - } - return 0; -} - -static int gce_gps_inject_time(GpsUtcTime /*time*/, int64_t /*time_ref*/, - int /*uncertainty*/) { - D("%s: called", __FUNCTION__); - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return -1; - } - - return 0; -} - -static int gce_gps_inject_location(double /*latitude*/, double /*longitude*/, - float /*accuracy*/) { - D("%s: called", __FUNCTION__); - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return -1; - } - - return 0; -} - -static void gce_gps_delete_aiding_data(GpsAidingData /*flags*/) { - D("%s: called", __FUNCTION__); - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return; - } -} - -static int gce_gps_set_position_mode(GpsPositionMode mode, - GpsPositionRecurrence recurrence, - uint32_t min_interval, - uint32_t preferred_accuracy, - uint32_t preferred_time) { - D("%s: called", __FUNCTION__); - if (!_gps_state.init) { - ALOGE("%s: called with uninitialized gps_state!", __FUNCTION__); - return -1; - } - ALOGE("%s(mode=%d, recurrence=%d, min_interval=%" PRIu32 - ", " - "preferred_accuracy=%" PRIu32 ", preferred_time=%" PRIu32 - ") unimplemented", - __FUNCTION__, mode, recurrence, min_interval, preferred_accuracy, - preferred_time); - return 0; -} - -static const void* gce_gps_get_extension(const char* name) { - D("%s: called", __FUNCTION__); - // It is normal for this to be called before init. - ALOGE("%s(%s): called but not implemented.", __FUNCTION__, - name ? name : "NULL"); - return NULL; -} - -static const GpsInterface gceGpsInterface = { - sizeof(GpsInterface), - gce_gps_init, - gce_gps_start, - gce_gps_stop, - gce_gps_cleanup, - gce_gps_inject_time, - gce_gps_inject_location, - gce_gps_delete_aiding_data, - gce_gps_set_position_mode, - gce_gps_get_extension, -}; - -const GpsInterface* gps_get_gps_interface(struct gps_device_t* /*dev*/) { - return &gceGpsInterface; -} - -static int open_gps(const struct hw_module_t* module, char const* /*name*/, - struct hw_device_t** device) { - struct gps_device_t* dev = - (struct gps_device_t*)malloc(sizeof(struct gps_device_t)); - LOG_FATAL_IF(!dev, "%s: malloc returned NULL.", __FUNCTION__); - memset(dev, 0, sizeof(*dev)); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t*)module; - dev->get_gps_interface = gps_get_gps_interface; - - *device = (struct hw_device_t*)dev; - return 0; -} - -static struct hw_module_methods_t gps_module_methods = { - .open = open_gps}; - -struct hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = GPS_HARDWARE_MODULE_ID, - .name = "GCE GPS Module", - .author = "The Android Open Source Project", - .methods = & gps_module_methods, -}; diff --git a/guest/hals/gralloc/legacy/Android.mk b/guest/hals/gralloc/legacy/Android.mk deleted file mode 100644 index ac789fb9..00000000 --- a/guest/hals/gralloc/legacy/Android.mk +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) 2016 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. - -# Temporary, should be removed once vsoc hals are in usable state - -LOCAL_PATH := $(call my-dir) - -VSOC_GRALLOC_COMMON_SRC_FILES := \ - gralloc.cpp \ - mapper.cpp \ - region_registry.cpp - -VSOC_GRALLOC_COMMON_CFLAGS:= \ - -DLOG_TAG=\"gralloc_vsoc_legacy\" \ - -Wno-missing-field-initializers \ - -Wall -Werror \ - $(VSOC_VERSION_CFLAGS) - -include $(CLEAR_VARS) -LOCAL_MODULE := gralloc.cutf_ashmem -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := $(VSOC_GRALLOC_COMMON_SRC_FILES) - -LOCAL_CFLAGS := $(VSOC_GRALLOC_COMMON_CFLAGS) -LOCAL_C_INCLUDES := \ - device/google/cuttlefish_common \ - device/google/cuttlefish_kernel - -LOCAL_HEADER_LIBRARIES := \ - libhardware_headers - -LOCAL_SHARED_LIBRARIES := \ - libbase \ - liblog \ - libutils \ - libcutils - -LOCAL_VENDOR_MODULE := true - -# See b/67109557 -ifeq (true, $(TARGET_TRANSLATE_2ND_ARCH)) -LOCAL_MULTILIB := first -endif - -include $(BUILD_SHARED_LIBRARY) diff --git a/guest/hals/gralloc/legacy/gralloc.cpp b/guest/hals/gralloc/legacy/gralloc.cpp deleted file mode 100644 index 28e71eb9..00000000 --- a/guest/hals/gralloc/legacy/gralloc.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <atomic> -#include <limits.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> - -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/ioctl.h> - -#include <cutils/ashmem.h> -#include <log/log.h> -#include <cutils/atomic.h> -#include <utils/String8.h> - -#include <hardware/hardware.h> -#include <hardware/gralloc.h> - -#include "gralloc_vsoc_priv.h" -#include "region_registry.h" - -using vsoc::screen::ScreenRegionView; - -/*****************************************************************************/ - -static inline size_t roundUpToPageSize(size_t x) { - return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); -} - -static int gralloc_alloc_buffer( - alloc_device_t* /*dev*/, int format, int w, int h, - buffer_handle_t* pHandle, int* pStrideInPixels) { - int err = 0; - int fd = -1; - static std::atomic<int> sequence; - - int bytes_per_pixel = formatToBytesPerPixel(format); - int bytes_per_line; - int stride_in_pixels; - int size = 0; - // SwiftShader can't handle RGB_888, so fail fast and hard if we try to create - // a gralloc buffer in this format. - ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888); - if (format == HAL_PIXEL_FORMAT_YV12) { - bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w); - } else { - bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w); - } - size = roundUpToPageSize(size + formatToBytesPerFrame(format, w, h)); - size += PAGE_SIZE; - fd = ashmem_create_region( - android::String8::format( - "gralloc-%d.%d", getpid(), sequence++).string(), - size); - if (fd < 0) { - ALOGE("couldn't create ashmem (%s)", strerror(-errno)); - err = -errno; - } - - if (err == 0) { - stride_in_pixels = bytes_per_line / bytes_per_pixel; - private_handle_t* hnd = - new private_handle_t(fd, size, format, w, h, stride_in_pixels, 0); - void* base = reference_region(__FUNCTION__, hnd); - if (base) { - *pHandle = hnd; - *pStrideInPixels = stride_in_pixels; - } else { - err = -EIO; - } - } - - ALOGE_IF(err, "gralloc failed err=%s", strerror(-err)); - - return err; -} - -/*****************************************************************************/ - -static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, - int /*usage*/, buffer_handle_t* pHandle, - int* pStrideInPixels) { - if (!pHandle || !pStrideInPixels) - return -EINVAL; - - int err = gralloc_alloc_buffer(dev, format, w, h, pHandle, pStrideInPixels); - - if (err < 0) { - return err; - } - return 0; -} - -static int gralloc_free(alloc_device_t* /*dev*/, buffer_handle_t handle) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - - private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>( - handle); - int retval = unreference_region(__FUNCTION__, hnd); - - close(hnd->fd); - delete hnd; - return retval; -} - -/*****************************************************************************/ - -static int gralloc_close(struct hw_device_t *dev) { - priv_alloc_device_t* ctx = reinterpret_cast<priv_alloc_device_t*>(dev); - if (ctx) { - /* TODO: keep a list of all buffer_handle_t created, and free them - * all here. - */ - free(ctx); - } - return 0; -} - -static int gralloc_device_open( - const hw_module_t* module, const char* name, hw_device_t** device) { - int status = -EINVAL; - if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { - priv_alloc_device_t *dev; - dev = (priv_alloc_device_t*) malloc(sizeof(*dev)); - LOG_FATAL_IF(!dev, "%s: malloc returned NULL.", __FUNCTION__); - - /* initialize our state here */ - memset(dev, 0, sizeof(*dev)); - - /* initialize the procs */ - dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = 0; - dev->device.common.module = const_cast<hw_module_t*>(module); - dev->device.common.close = gralloc_close; - - dev->device.alloc = gralloc_alloc; - dev->device.free = gralloc_free; - - *device = &dev->device.common; - status = 0; - } else { - ALOGE("Need to create framebuffer, but it is unsupported"); - } - return status; -} - -/*****************************************************************************/ - -static struct hw_module_methods_t gralloc_module_methods = { - .open = gralloc_device_open -}; - -struct private_module_t HAL_MODULE_INFO_SYM = { - .base = { - .common = { - .tag = HARDWARE_MODULE_TAG, -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - .version_major = GRALLOC_MODULE_API_VERSION_0_2, -#else - .version_major = 1, -#endif - .version_minor = 0, - .id = GRALLOC_HARDWARE_MODULE_ID, - .name = "VSOC X86 Graphics Memory Allocator Module", - .author = "The Android Open Source Project", - .methods = &gralloc_module_methods, - .dso = NULL, - .reserved = {0}, - }, - .registerBuffer = gralloc_register_buffer, - .unregisterBuffer = gralloc_unregister_buffer, - .lock = gralloc_lock, - .unlock = gralloc_unlock, -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - .perform = NULL, - .lock_ycbcr = gralloc_lock_ycbcr, -#endif - .getTransportSize = gralloc_get_transport_size, - .validateBufferSize = gralloc_validate_buffer_size, - }, -}; diff --git a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h deleted file mode 100644 index 390c6545..00000000 --- a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h +++ /dev/null @@ -1,340 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <stdint.h> -#include <limits.h> -#include <string.h> -#include <sys/cdefs.h> -#include <sys/mman.h> -#include <hardware/gralloc.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> - -#include <cutils/native_handle.h> -#include <log/log.h> - -#include <linux/fb.h> - -#ifndef GRALLOC_MODULE_API_VERSION_0_2 -// This structure will be defined in later releases of Android. Declare it -// here to allow us to structure the code well. -struct android_ycbcr { - void* y; - void* cb; - void* cr; - size_t ystride; - size_t cstride; - size_t chroma_step; - uint32_t reserved[8]; -}; -#endif - -namespace vsoc { -namespace screen { - -struct ScreenRegionView { - static int align(int input) { - auto constexpr alignment = 16; - return (input + alignment - 1) & -alignment; - } - static constexpr int kSwiftShaderPadding = 4; -}; - -} -} - -/*****************************************************************************/ - -struct private_handle_t; - -struct private_module_t { - gralloc_module_t base; -}; - -/*****************************************************************************/ - -struct priv_alloc_device_t { - alloc_device_t device; -}; - -/*****************************************************************************/ - -struct private_handle_t : public native_handle { - // file-descriptors - int fd; - // ints - int magic; - int flags; - int format; - int x_res; - int y_res; - int stride_in_pixels; - // Use to indicate which frame we're using. - int frame_offset; - int total_size; - int lock_level; - - static inline int sNumInts() { - return (((sizeof(private_handle_t) - sizeof(native_handle_t))/sizeof(int)) - sNumFds); - } - static const int sNumFds = 1; - static const int sMagic = 0x3141592; - - private_handle_t(int fd, int size, int format, int x_res, int y_res, - int stride_in_pixels, int flags, int frame_offset = 0) - : fd(fd), - magic(sMagic), - flags(flags), - format(format), - x_res(x_res), - y_res(y_res), - stride_in_pixels(stride_in_pixels), - frame_offset(frame_offset), - total_size(size), - lock_level(0) { - version = sizeof(native_handle); - numInts = sNumInts(); - numFds = sNumFds; - } - - ~private_handle_t() { - magic = 0; - } - - static int validate(const native_handle* h) { - const private_handle_t* hnd = (const private_handle_t*)h; - if (!h) { - ALOGE("invalid gralloc handle (at %p): NULL pointer", h); - return -EINVAL; - } - if (h->version != sizeof(native_handle)) { - ALOGE( - "invalid gralloc handle (at %p): Wrong version(observed: %d, " - "expected: %zu)", - h, - h->version, - sizeof(native_handle)); - return -EINVAL; - } - if (h->numInts != sNumInts()) { - ALOGE( - "invalid gralloc handle (at %p): Wrong number of ints(observed: %d, " - "expected: %d)", - h, - h->numInts, - sNumInts()); - return -EINVAL; - } - if (h->numFds != sNumFds) { - ALOGE( - "invalid gralloc handle (at %p): Wrong number of file " - "descriptors(observed: %d, expected: %d)", - h, - h->numFds, - sNumFds); - return -EINVAL; - } - if (hnd->magic != sMagic) { - ALOGE( - "invalid gralloc handle (at %p): Wrong magic number(observed: %d, " - "expected: %d)", - h, - hnd->magic, - sMagic); - return -EINVAL; - } - return 0; - } -}; - - -static inline int formatToBytesPerPixel(int format) { - switch (format) { - case HAL_PIXEL_FORMAT_RGBA_FP16: - return 8; - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - // The camera 3.0 implementation assumes that IMPLEMENTATION_DEFINED - // means HAL_PIXEL_FORMAT_RGBA_8888 - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - return 4; - case HAL_PIXEL_FORMAT_RGB_888: - return 3; - case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_YV12: -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - case HAL_PIXEL_FORMAT_YCbCr_420_888: -#endif - return 2; - case HAL_PIXEL_FORMAT_BLOB: - return 1; - default: - ALOGE("%s: unknown format=%d", __FUNCTION__, format); - return 8; - } -} - -inline const char* pixel_format_to_string(int format) { - switch (format) { - // Formats that are universal across versions - case HAL_PIXEL_FORMAT_RGBA_8888: - return "RGBA_8888"; - case HAL_PIXEL_FORMAT_RGBX_8888: - return "RGBX_8888"; - case HAL_PIXEL_FORMAT_BGRA_8888: - return "BGRA_8888"; - case HAL_PIXEL_FORMAT_RGB_888: - return "RGB_888"; - case HAL_PIXEL_FORMAT_RGB_565: - return "RGB_565"; - case HAL_PIXEL_FORMAT_YV12: - return "YV12"; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - return "YCrCb_420_SP"; - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - return "YCbCr_422_SP"; - case HAL_PIXEL_FORMAT_YCbCr_422_I: - return "YCbCr_422_I"; - - // First supported on JBMR1 (API 17) - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - return "IMPLEMENTATION_DEFINED"; - case HAL_PIXEL_FORMAT_BLOB: - return "BLOB"; - // First supported on JBMR2 (API 18) - case HAL_PIXEL_FORMAT_YCbCr_420_888: - return "YCbCr_420_888"; - case HAL_PIXEL_FORMAT_Y8: - return "Y8"; - case HAL_PIXEL_FORMAT_Y16: - return "Y16"; - // Support was added in L (API 21) - case HAL_PIXEL_FORMAT_RAW_OPAQUE: - return "RAW_OPAQUE"; - // This is an alias for RAW_SENSOR in L and replaces it in M. - case HAL_PIXEL_FORMAT_RAW16: - return "RAW16"; - case HAL_PIXEL_FORMAT_RAW10: - return "RAW10"; - case HAL_PIXEL_FORMAT_YCbCr_444_888: - return "YCbCr_444_888"; - case HAL_PIXEL_FORMAT_YCbCr_422_888: - return "YCbCr_422_888"; - case HAL_PIXEL_FORMAT_RAW12: - return "RAW12"; - case HAL_PIXEL_FORMAT_FLEX_RGBA_8888: - return "FLEX_RGBA_8888"; - case HAL_PIXEL_FORMAT_FLEX_RGB_888: - return "FLEX_RGB_888"; - case HAL_PIXEL_FORMAT_RGBA_FP16: - return "RGBA_FP16"; - } - return "UNKNOWN"; -} - - -static inline void formatToYcbcr( - int format, int width, int height, void* base_v, android_ycbcr* out) { - char* it = static_cast<char*>(base_v); - // Clear reserved fields; - memset(out, 0, sizeof(*out)); - switch (format) { - case HAL_PIXEL_FORMAT_YV12: -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - case HAL_PIXEL_FORMAT_YCbCr_420_888: -#endif - out->ystride = vsoc::screen::ScreenRegionView::align(width); - out->cstride = - vsoc::screen::ScreenRegionView::align(out->ystride / 2); - out->chroma_step = 1; - out->y = it; - it += out->ystride * height; - out->cr = it; - it += out->cstride * height / 2; - out->cb = it; - break; - default: - ALOGE("%s: can't deal with format=0x%x (%s)", - __FUNCTION__, format, pixel_format_to_string(format)); - } -} - -static inline int formatToBytesPerFrame(int format, int w, int h) { - int bytes_per_pixel = formatToBytesPerPixel(format); - int w16, h16; - int y_size, c_size; - - switch (format) { - // BLOB is used to allocate buffers for JPEG formatted data. Bytes per pixel - // is 1, the desired buffer size is in w, and h should be 1. We refrain from - // adding additional padding, although the caller is likely to round - // up to a page size. - case HAL_PIXEL_FORMAT_BLOB: - return bytes_per_pixel * w * h; - case HAL_PIXEL_FORMAT_YV12: -#ifdef GRALLOC_MODULE_API_VERSION_0_2 - case HAL_PIXEL_FORMAT_YCbCr_420_888: -#endif - android_ycbcr strides; - formatToYcbcr(format, w, h, NULL, &strides); - y_size = strides.ystride * h; - c_size = strides.cstride * h / 2; - return (y_size + 2 * c_size + - vsoc::screen::ScreenRegionView::kSwiftShaderPadding); - /*case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_888: - case HAL_PIXEL_FORMAT_RGB_565:*/ - default: - w16 = vsoc::screen::ScreenRegionView::align(w); - h16 = vsoc::screen::ScreenRegionView::align(h); - return bytes_per_pixel * w16 * h16 + - vsoc::screen::ScreenRegionView::kSwiftShaderPadding; - } -} - -int gralloc_lock( - gralloc_module_t const* module, - buffer_handle_t handle, int usage, - int l, int t, int w, int h, - void** vaddr); - -int gralloc_unlock( - gralloc_module_t const* module, buffer_handle_t handle); - -int gralloc_register_buffer( - gralloc_module_t const* module, buffer_handle_t handle); - -int gralloc_unregister_buffer( - gralloc_module_t const* module, buffer_handle_t handle); - -int gralloc_lock_ycbcr( - struct gralloc_module_t const* module, - buffer_handle_t handle, int usage, - int l, int t, int w, int h, - struct android_ycbcr *ycbcr); - -int32_t gralloc_get_transport_size( - struct gralloc_module_t const* module, buffer_handle_t handle, - uint32_t *outNumFds, uint32_t *outNumInts); - -int32_t gralloc_validate_buffer_size( - struct gralloc_module_t const* device, buffer_handle_t handle, - uint32_t w, uint32_t h, int32_t format, int usage, - uint32_t stride); diff --git a/guest/hals/gralloc/legacy/mapper.cpp b/guest/hals/gralloc/legacy/mapper.cpp deleted file mode 100644 index eb0facc3..00000000 --- a/guest/hals/gralloc/legacy/mapper.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <limits.h> -#include <errno.h> -#include <pthread.h> -#include <unistd.h> -#include <string.h> - -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <cutils/hashmap.h> -#include <log/log.h> -#include <cutils/atomic.h> - -#include <hardware/hardware.h> -#include <hardware/gralloc.h> -#include <system/graphics.h> - -#include "gralloc_vsoc_priv.h" -#include "region_registry.h" - -#define DEBUG_REFERENCES 1 -#define DEBUG_MAX_LOCK_LEVEL 20 - -/*****************************************************************************/ - -int gralloc_register_buffer(gralloc_module_t const* /*module*/, - buffer_handle_t handle) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - - private_handle_t* hnd = (private_handle_t*)handle; - if (reference_region(__FUNCTION__, hnd)) { - return 0; - } else { - return -EIO; - } -} - -int gralloc_unregister_buffer(gralloc_module_t const* /*module*/, - buffer_handle_t handle) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - private_handle_t* hnd = (private_handle_t*)handle; - return unreference_region("gralloc_unregister_buffer", hnd); -} - -int gralloc_lock( - gralloc_module_t const* /*module*/, buffer_handle_t handle, int /*usage*/, - int /*l*/, int /*t*/, int /*w*/, int /*h*/, - void** vaddr) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - if (!vaddr) { - return -EINVAL; - } - private_handle_t* hnd = (private_handle_t*)handle; -#if DEBUG_REFERENCES - if (hnd->lock_level > DEBUG_MAX_LOCK_LEVEL) { - LOG_FATAL("%s: unbalanced lock detected. lock level = %d", - __FUNCTION__, hnd->lock_level); - } - ++hnd->lock_level; -#endif - void* base = reference_region("gralloc_lock", hnd); - *vaddr = reinterpret_cast<unsigned char*>(base) - + hnd->frame_offset; - return 0; -} - -int gralloc_unlock( - gralloc_module_t const* /*module*/, buffer_handle_t handle) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - private_handle_t* hnd = (private_handle_t*) handle; -#if DEBUG_REFERENCES - if (hnd->lock_level <= 0) { - LOG_FATAL("%s unbalanced unlock detected. lock level = %d", - __FUNCTION__, hnd->lock_level); - } - --hnd->lock_level; -#endif - unreference_region("gralloc_unlock", hnd); - return 0; -} - -int gralloc_lock_ycbcr( - gralloc_module_t const* /*module*/, buffer_handle_t handle, int /*usage*/, - int /*l*/, int /*t*/, int /*w*/, int /*h*/, - struct android_ycbcr* ycbcr) { - if (private_handle_t::validate(handle) < 0) { - return -EINVAL; - } - private_handle_t* hnd = (private_handle_t*)handle; -#if DEBUG_REFERENCES - if (hnd->lock_level > DEBUG_MAX_LOCK_LEVEL) { - LOG_FATAL("%s: unbalanced lock detected. lock level = %d", - __FUNCTION__, hnd->lock_level); - } - ++hnd->lock_level; -#endif - void* base = reference_region("gralloc_lock_ycbcr", hnd); - formatToYcbcr(hnd->format, hnd->x_res, hnd->y_res, base, ycbcr); - return 0; -} - -int32_t gralloc_get_transport_size(struct gralloc_module_t const* /*module*/, - buffer_handle_t handle, - uint32_t *outNumFds, - uint32_t *outNumInts) { - if (private_handle_t::validate(handle) < 0) { - return 2; // GRALLOC1_ERROR_BAD_HANDLE - } - private_handle_t* hnd = (private_handle_t*)handle; - *outNumFds = hnd->numFds; - *outNumInts = hnd->numInts; - return 0; -} - -int32_t gralloc_validate_buffer_size(struct gralloc_module_t const* /*device*/, - buffer_handle_t handle, - uint32_t w, - uint32_t h, - int32_t format, - int /*usage*/, - uint32_t stride) { - if (private_handle_t::validate(handle) < 0) { - return 2; // GRALLOC1_ERROR_BAD_HANDLE - } - private_handle_t* hnd = (private_handle_t*)handle; - if (format != hnd->format || - w > hnd->x_res || - h > hnd->y_res || - stride > hnd->stride_in_pixels) { - return 3; // GRALLOC1_ERROR_BAD_VALUE - } - return 0; -} diff --git a/guest/hals/gralloc/legacy/region_registry.cpp b/guest/hals/gralloc/legacy/region_registry.cpp deleted file mode 100644 index 9829d461..00000000 --- a/guest/hals/gralloc/legacy/region_registry.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "VSoCGrallocRegionRegistry" -// Ensure verbose messages appear even on release builds -#define LOG_NDEBUG 0 - -#include <limits.h> -#include <errno.h> -#include <pthread.h> -#include <unistd.h> -#include <string.h> - -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <cutils/hashmap.h> -#include <log/log.h> -#include <cutils/atomic.h> - -#include <linux/ashmem.h> - -#include <hardware/hardware.h> -#include <hardware/gralloc.h> -#include <system/graphics.h> - -#include "gralloc_vsoc_priv.h" - -#include <deque> -#include <map> -#include <mutex> - -static const bool g_log_maps = false; -static const bool g_log_refs = false; - -struct GrallocRegion { - void* base_; - int num_references_; - - GrallocRegion() : base_(0), num_references_(0) { } - // Copy constructors are ok. -}; - - -static const char* get_buffer_name( - const private_handle_t* hnd, char output[ASHMEM_NAME_LEN]) { - output[0] = '\0'; - if (!hnd) { - ALOGE("Attempted to log gralloc name hnd=NULL"); - return output; - } - if (hnd->fd == -1) { - ALOGE("Attempted to log gralloc name hnd=%p with fd == -1", hnd); - return output; - } - int rval = ioctl(hnd->fd, ASHMEM_GET_NAME, output); - if (rval == -1) { - output[0] = '\0'; - } - return output; -} - - -static int str_hash(void* str) { - return hashmapHash(str, strlen(reinterpret_cast<const char*>(str))); -} - - -static bool str_equal(void* a, void* b) { - return strcmp( - reinterpret_cast<const char*>(a), - reinterpret_cast<const char*>(b)) == 0; -} - - -static Hashmap* get_regions() { - static Hashmap* regionMap = hashmapCreate(19, str_hash, str_equal); - return regionMap; -} - - -static GrallocRegion* lock_region_for_handle( - const private_handle_t* hnd, char region_name[ASHMEM_NAME_LEN]) { - region_name[0] = '\0'; - get_buffer_name(hnd, region_name); - Hashmap* hash = get_regions(); - hashmapLock(hash); - GrallocRegion* region = reinterpret_cast<GrallocRegion*>( - hashmapGet(hash, region_name)); - if (!region) { - region = new GrallocRegion; - hashmapPut(hash, strdup(region_name), region); - } - return region; -} - - -/* The current implementation uses only a single lock for all regions. - * This method takes a region to simplfy the refactoring if we go to - * finer-grained locks. - */ -static inline void unlock_region(GrallocRegion* ) { - hashmapUnlock(get_regions()); -} - - -/* - * surface_flinger can drop its last reference to a gralloc buffer (from the - * gralloc HAL's point of view) even though it also has work in flight to the - * GPU for that target. This causes segfaults in the swiftshader code. - * - * We create a compromise solution. On unmap we release the pages by mmaping - * anonymous memory over the range, but we don't release the address space. - * Instead we mark the address space for recycling into a new gralloc buffer. - * This means that the shaders can still write, that the writes won't land in - * the gralloc buffer, and the gralloc buffer memory can be released. - * - * When we're preparing to mmap a new gralloc buffer we see if we can recycle - * address space from a prior gralloc buffer. - * - * The protects the application layer from stray memory writes and pointer - * references to freed memory. It does mean that bad pixel data can land in - * a buffer in the case of a fast map-unmap-map sequence. However, that - * could also happen on a physical GPU. - * - * The alternative to this would be to create an elaborate reference counting - * mechanism below both gralloc and SwiftShader. However, we want to keep the - * SwiftShader code clean, so that seems undesirable. - * - * This problem also comes up for physical GPUs b/62267886. Background fo rthis - * solution is in b/118777601 - */ - -static std::map<size_t, std::deque<void*>> g_recycled_addrs; -std::mutex g_recycled_addrs_mutex; - - - -static void* recycle_mmap(void *addr, size_t length, int prot, int flags, - int fd, off_t offset) { - if (!addr) { - std::lock_guard<std::mutex> guard(g_recycled_addrs_mutex); - auto it = g_recycled_addrs.find(length); - if (it != g_recycled_addrs.end()) { - if (it->second.size()) { - addr = it->second.front(); - flags |= MAP_FIXED; - it->second.pop_front(); - } - } - } - return mmap(addr, length, prot, flags, fd, offset); -} - - -static int recycle_munmap(void *addr, size_t length) { - // Do this first so we don't hold the mutex during the syscall - if (addr != mmap(addr, length, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)) { - // Be conservative. Don't recycle here. - return -1; - } - std::lock_guard<std::mutex> guard(g_recycled_addrs_mutex); - g_recycled_addrs[length].push_back(addr); - return 0; -} - - -void* reference_region(const char* op, const private_handle_t* hnd) { - char name_buf[ASHMEM_NAME_LEN]; - GrallocRegion* region = lock_region_for_handle(hnd, name_buf); - if (!region->base_) { - void* mappedAddress = recycle_mmap( - 0, hnd->total_size, PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0); - if (mappedAddress == MAP_FAILED) { - ALOGE("Could not mmap %s", strerror(errno)); - unlock_region(region); - return NULL; - } - // Set up the guard pages. The last page is always a guard - uintptr_t base = uintptr_t(mappedAddress); - uintptr_t addr = base + hnd->total_size - PAGE_SIZE; - if (mprotect((void*)addr, PAGE_SIZE, PROT_NONE) == -1) { - ALOGE("mprotect base=%p, pg=%p failed (%s)", (void*)base, (void*)addr, - strerror(errno)); - } - region->base_ = mappedAddress; - ALOGV_IF(g_log_maps, "Mapped %s hnd=%p fd=%d base=%p format=%s(0x%x) " - "width=%d height=%d stride_in_pixels=%d total_size=%d", - name_buf, hnd, hnd->fd, region->base_, - pixel_format_to_string(hnd->format), hnd->format, - hnd->x_res, hnd->y_res, hnd->stride_in_pixels, hnd->total_size); - } - - void* rval = region->base_; - ++region->num_references_; - ALOGV_IF(g_log_refs, "Referencing name=%s op=%s addr=%p new numRefs=%d", - name_buf, op, region->base_, region->num_references_); - unlock_region(region); - return rval; -} - - -int unreference_region(const char* op, const private_handle_t* hnd) { - char name_buf[ASHMEM_NAME_LEN]; - - GrallocRegion* region = lock_region_for_handle(hnd, name_buf); - if (!region->base_) { - ALOGE("Unmapping region with no map hnd=%p", hnd); - unlock_region(region); - return -1; - } - if (region->num_references_ < 1) { - ALOGE( - "unmap with hnd=%p, numReferences=%d", hnd, region->num_references_); - unlock_region(region); - return -1; - } - --region->num_references_; - if (!region->num_references_) { - ALOGV_IF(g_log_maps, "Unmapped %s hnd=%p fd=%d base=%p", name_buf, hnd, - hnd->fd, region->base_); - if (recycle_munmap(region->base_, hnd->total_size) < 0) { - ALOGE("Could not unmap %s", strerror(errno)); - } - region->base_ = 0; - } - ALOGV_IF(g_log_refs, "Unreferencing name=%s op=%s addr=%p new numRefs=%d", - name_buf, op, region->base_, region->num_references_); - unlock_region(region); - return 0; -} diff --git a/guest/hals/gralloc/legacy/region_registry.h b/guest/hals/gralloc/legacy/region_registry.h deleted file mode 100644 index 210ba9a2..00000000 --- a/guest/hals/gralloc/legacy/region_registry.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 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. - */ -struct private_handle_t; - -/** - * Map the memory associated with hnd->fd or, if already mapped, increment - * its reference count. - */ -void* reference_region( - const char* op, const private_handle_t* hnd); - -/** - * Decrement the reference count associated with hnd->fd, unmapping its - * memory iff the reference count reaches 0. - */ -int unreference_region(const char* op, const private_handle_t* hnd); diff --git a/guest/hals/health/Android.bp b/guest/hals/health/Android.bp deleted file mode 100644 index 3f214257..00000000 --- a/guest/hals/health/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ -cc_library_shared { - name: "android.hardware.health@2.1-impl-cuttlefish", - stem: "android.hardware.health@2.0-impl-2.1-cuttlefish", - proprietary: true, - recovery_available: true, - - relative_install_path: "hw", - - srcs: [ - "health.cpp", - ], - - cflags: [ - "-Wall", - "-Werror", - ], - - static_libs: [ - "android.hardware.health@1.0-convert", - "libbatterymonitor", - "libhealthloop", - "libhealth2impl", - ], - - shared_libs: [ - "libbase", - "libcutils", - "libhidlbase", - "libutils", - "android.hardware.health@2.0", - "android.hardware.health@2.1", - ], - - defaults: ["enabled_on_p_and_later"], -} diff --git a/guest/hals/health/health.cpp b/guest/hals/health/health.cpp deleted file mode 100644 index adec0853..00000000 --- a/guest/hals/health/health.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ -#define LOG_TAG "android.hardware.health@2.0-service.cuttlefish" - -#include <memory> -#include <string_view> - -#include <android-base/logging.h> -#include <health/utils.h> -#include <health2impl/Health.h> - -using ::android::sp; -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::health::InitHealthdConfig; -using ::android::hardware::health::V2_1::IHealth; -using namespace std::literals; - -namespace android { -namespace hardware { -namespace health { -namespace V2_1 { -namespace implementation { -class HealthImpl : public Health { - public: - HealthImpl(std::unique_ptr<healthd_config>&& config) - : Health(std::move(config)) {} - protected: - void UpdateHealthInfo(HealthInfo* health_info) override; -}; - -void HealthImpl::UpdateHealthInfo(HealthInfo* health_info) { - auto* battery_props = &health_info->legacy.legacy; - battery_props->chargerAcOnline = true; - battery_props->chargerUsbOnline = true; - battery_props->chargerWirelessOnline = false; - battery_props->maxChargingCurrent = 500000; - battery_props->maxChargingVoltage = 5000000; - battery_props->batteryStatus = V1_0::BatteryStatus::CHARGING; - battery_props->batteryHealth = V1_0::BatteryHealth::GOOD; - battery_props->batteryPresent = true; - battery_props->batteryLevel = 85; - battery_props->batteryVoltage = 3600; - battery_props->batteryTemperature = 350; - battery_props->batteryCurrent = 400000; - battery_props->batteryCycleCount = 32; - battery_props->batteryFullCharge = 4000000; - battery_props->batteryChargeCounter = 1900000; - battery_props->batteryTechnology = "Li-ion"; -} - -} // namespace implementation -} // namespace V2_1 -} // namespace health -} // namespace hardware -} // namespace android - - -extern "C" IHealth* HIDL_FETCH_IHealth(const char* instance) { - using ::android::hardware::health::V2_1::implementation::HealthImpl; - if (instance != "default"sv) { - return nullptr; - } - auto config = std::make_unique<healthd_config>(); - InitHealthdConfig(config.get()); - - return new HealthImpl(std::move(config)); -} diff --git a/guest/hals/health/storage/Android.bp b/guest/hals/health/storage/Android.bp deleted file mode 100644 index 74b36ad7..00000000 --- a/guest/hals/health/storage/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -cc_binary { - name: "android.hardware.health.storage@1.0-service.cuttlefish", - vendor: true, - defaults: ["hidl_defaults", "cuttlefish_health_storage"], - relative_install_path: "hw", - init_rc: ["android.hardware.health.storage@1.0-service.cuttlefish.rc"], - srcs: [ - "Storage.cpp", - "service.cpp", - ], - - cflags: [ - "-Wall", - "-Werror", - ], - - shared_libs: [ - "android.hardware.health.storage@1.0", - "libbase", - "libhidlbase", - "libutils", - ], -} diff --git a/guest/hals/health/storage/Storage.cpp b/guest/hals/health/storage/Storage.cpp deleted file mode 100644 index 6b7671a2..00000000 --- a/guest/hals/health/storage/Storage.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "Storage.h" - -#include <android-base/logging.h> - -namespace android { -namespace hardware { -namespace health { -namespace storage { -namespace V1_0 { -namespace implementation { - -Return<void> Storage::garbageCollect(uint64_t /*timeoutSeconds*/, - const sp<IGarbageCollectCallback>& cb) { - LOG(INFO) << "IStorage::garbageCollect() is called. Nothing to do."; - if (cb != nullptr) { - auto ret = cb->onFinish(Result::SUCCESS); - if (!ret.isOk()) { - LOG(WARNING) << "Cannot return result to callback: " << ret.description(); - } - } - return Void(); -} - - -} // namespace implementation -} // namespace V1_0 -} // namespace storage -} // namespace health -} // namespace hardware -} // namespace android diff --git a/guest/hals/health/storage/Storage.h b/guest/hals/health/storage/Storage.h deleted file mode 100644 index 08ff3f27..00000000 --- a/guest/hals/health/storage/Storage.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -#ifndef ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H -#define ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H - -#include <android/hardware/health/storage/1.0/IStorage.h> -#include <hidl/Status.h> - -namespace android { -namespace hardware { -namespace health { -namespace storage { -namespace V1_0 { -namespace implementation { - -using ::android::sp; -using ::android::hardware::hidl_handle; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::Return; - -struct Storage : public IStorage { - Return<void> garbageCollect(uint64_t timeoutSeconds, - const sp<IGarbageCollectCallback>& cb) override; -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace storage -} // namespace health -} // namespace hardware -} // namespace android - -#endif // ANDROID_HARDWARE_HEALTH_FILESYSTEM_V1_0_FILESYSTEM_H diff --git a/guest/hals/health/storage/android.hardware.health.storage@1.0-service.cuttlefish.rc b/guest/hals/health/storage/android.hardware.health.storage@1.0-service.cuttlefish.rc deleted file mode 100644 index 44eccf33..00000000 --- a/guest/hals/health/storage/android.hardware.health.storage@1.0-service.cuttlefish.rc +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2019 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. -# - -service vendor.health-storage-hal-1-0 /vendor/bin/hw/android.hardware.health.storage@1.0-service.cuttlefish - interface android.hardware.health.storage@1.0::IStorage default - oneshot - disabled - class hal - user system - group system diff --git a/guest/hals/health/storage/manifest_android.hardware.health.storage@1.0.cuttlefish.xml b/guest/hals/health/storage/manifest_android.hardware.health.storage@1.0.cuttlefish.xml deleted file mode 100644 index 62b23e04..00000000 --- a/guest/hals/health/storage/manifest_android.hardware.health.storage@1.0.cuttlefish.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 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. ---> -<manifest version="1.0" type="device"> - <hal> - <name>android.hardware.health.storage</name> - <transport>hwbinder</transport> - <version>1.0</version> - <interface> - <name>IStorage</name> - <instance>default</instance> - </interface> - </hal> -</manifest> diff --git a/guest/hals/health/storage/service.cpp b/guest/hals/health/storage/service.cpp deleted file mode 100644 index 39ff08b1..00000000 --- a/guest/hals/health/storage/service.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <hidl/HidlLazyUtils.h> -#include <hidl/HidlTransportSupport.h> -#include "Storage.h" - -using android::OK; -using android::sp; -using android::status_t; -using android::UNKNOWN_ERROR; -using android::hardware::configureRpcThreadpool; -using android::hardware::joinRpcThreadpool; -using android::hardware::LazyServiceRegistrar; -using android::hardware::health::storage::V1_0::IStorage; -using android::hardware::health::storage::V1_0::implementation::Storage; - -int main() { - configureRpcThreadpool(1, true); - - sp<IStorage> service = new Storage(); - auto serviceRegistrar = LazyServiceRegistrar::getInstance(); - status_t result = serviceRegistrar.registerService(service); - - if (result != OK) { - return result; - } - - joinRpcThreadpool(); - return UNKNOWN_ERROR; -} diff --git a/guest/hals/hwcomposer/common/Android.bp b/guest/hals/hwcomposer/common/Android.bp deleted file mode 100644 index 25d02f87..00000000 --- a/guest/hals/hwcomposer/common/Android.bp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2019 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. - - -cc_library_static { - name: "hwcomposer_common", - defaults: ["cuttlefish_guest_only"], - vendor: true, - srcs: [ - "hwcomposer.cpp", - "screen_view.cpp", - "base_composer.cpp", - "geometry_utils.cpp", - "cpu_composer.cpp", - "stats_keeper.cpp", - ], - static_libs: [ - "libyuv_static", - ], - shared_libs: [ - "liblog", - "libhardware", - "libbase", - "libcutils", - "libutils", - "libsync", - "libhardware", - "libjpeg", - "libcuttlefish_utils", - "libcuttlefish_fs", - ], -} diff --git a/guest/hals/hwcomposer/common/base_composer.cpp b/guest/hals/hwcomposer/common/base_composer.cpp deleted file mode 100644 index 01138490..00000000 --- a/guest/hals/hwcomposer/common/base_composer.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/base_composer.h" - -#include <string.h> - -#include <cutils/properties.h> -#include <hardware/gralloc.h> -#include <log/log.h> - -#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" - -namespace cvd { - -BaseComposer::BaseComposer(std::unique_ptr<ScreenView> screen_view) - : screen_view_(std::move(screen_view)) { - hw_get_module(GRALLOC_HARDWARE_MODULE_ID, - reinterpret_cast<const hw_module_t**>(&gralloc_module_)); -} - -void BaseComposer::Dump(char* buff __unused, int buff_len __unused) {} - -int BaseComposer::PostFrameBufferTarget(buffer_handle_t buffer_handle) { - auto buffer_id = screen_view_->NextBuffer(); - void* frame_buffer = screen_view_->GetBuffer(buffer_id); - const private_handle_t* p_handle = - reinterpret_cast<const private_handle_t*>(buffer_handle); - void* buffer; - int retval = gralloc_module_->lock(gralloc_module_, buffer_handle, - GRALLOC_USAGE_SW_READ_OFTEN, 0, 0, - p_handle->x_res, p_handle->y_res, &buffer); - if (retval != 0) { - ALOGE("Got error code %d from lock function", retval); - return -1; - } - memcpy(frame_buffer, buffer, screen_view_->buffer_size()); - screen_view_->Broadcast(buffer_id); - return 0; -} // namespace cvd - -int BaseComposer::PrepareLayers(size_t num_layers, hwc_layer_1_t* layers) { - // find unsupported overlays - for (size_t i = 0; i < num_layers; i++) { - if (IS_TARGET_FRAMEBUFFER(layers[i].compositionType)) { - continue; - } - layers[i].compositionType = HWC_FRAMEBUFFER; - } - return 0; -} - -int BaseComposer::SetLayers(size_t num_layers, hwc_layer_1_t* layers) { - for (size_t idx = 0; idx < num_layers; idx++) { - if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) { - return PostFrameBufferTarget(layers[idx].handle); - } - } - return -1; -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/base_composer.h b/guest/hals/hwcomposer/common/base_composer.h deleted file mode 100644 index 69e618ab..00000000 --- a/guest/hals/hwcomposer/common/base_composer.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <memory> - -#include "guest/hals/hwcomposer/common/hwcomposer.h" -#include "guest/hals/hwcomposer/common/screen_view.h" - -namespace cvd { - -class BaseComposer { - public: - BaseComposer(std::unique_ptr<ScreenView> screen_view); - virtual ~BaseComposer() = default; - - // Sets the composition type of each layer and returns the number of layers - // to be composited by the hwcomposer. - virtual int PrepareLayers(size_t num_layers, hwc_layer_1_t* layers); - // Returns 0 if successful. - virtual int SetLayers(size_t num_layers, hwc_layer_1_t* layers); - virtual void Dump(char* buff, int buff_len); - - int32_t x_res() { return screen_view_->x_res(); } - int32_t y_res() { return screen_view_->y_res(); } - int32_t dpi() { return screen_view_->dpi(); } - int32_t refresh_rate() { return screen_view_->refresh_rate(); } - - protected: - std::unique_ptr<ScreenView> screen_view_; - const gralloc_module_t* gralloc_module_; - - private: - // Returns buffer offset or negative on error. - int PostFrameBufferTarget(buffer_handle_t handle); -}; -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/cpu_composer.cpp b/guest/hals/hwcomposer/common/cpu_composer.cpp deleted file mode 100644 index 35bc7019..00000000 --- a/guest/hals/hwcomposer/common/cpu_composer.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/cpu_composer.h" - -#include <algorithm> -#include <cstdlib> -#include <utility> -#include <vector> - -#include <hardware/hwcomposer.h> -#include <hardware/hwcomposer_defs.h> -#include <libyuv.h> -#include <log/log.h> -#include <system/graphics.h> - -#include "common/libs/utils/size_utils.h" -#include "guest/hals/hwcomposer/common/geometry_utils.h" - -namespace cvd { - -namespace { - -bool LayerNeedsScaling(const hwc_layer_1_t& layer) { - int from_w = layer.sourceCrop.right - layer.sourceCrop.left; - int from_h = layer.sourceCrop.bottom - layer.sourceCrop.top; - int to_w = layer.displayFrame.right - layer.displayFrame.left; - int to_h = layer.displayFrame.bottom - layer.displayFrame.top; - - bool not_rot_scale = from_w != to_w || from_h != to_h; - bool rot_scale = from_w != to_h || from_h != to_w; - - bool needs_rot = layer.transform & HAL_TRANSFORM_ROT_90; - - return needs_rot ? rot_scale : not_rot_scale; -} - -bool LayerNeedsBlending(const hwc_layer_1_t& layer) { - return layer.blending != HWC_BLENDING_NONE; -} - -bool LayerNeedsAttenuation(const hwc_layer_1_t& layer) { - return layer.blending == HWC_BLENDING_COVERAGE; -} - -struct BufferSpec; -typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst, - bool v_flip); -int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip); -int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip); -ConverterFunction GetConverter(uint32_t format) { - switch (format) { - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: - return &DoCopy; - - case HAL_PIXEL_FORMAT_YV12: - return &ConvertFromYV12; - - // Unsupported formats - // TODO(jemoreira): Conversion from these formats should be implemented as - // we find evidence of its usage. - // case HAL_PIXEL_FORMAT_BGRA_8888: - - // case HAL_PIXEL_FORMAT_RGB_888: - // case HAL_PIXEL_FORMAT_RGB_565: - - // case HAL_PIXEL_FORMAT_sRGB_A_8888: - // case HAL_PIXEL_FORMAT_sRGB_X_8888: - - // case HAL_PIXEL_FORMAT_Y8: - // case HAL_PIXEL_FORMAT_Y16: - - // case HAL_PIXEL_FORMAT_RAW_SENSOR: - // case HAL_PIXEL_FORMAT_BLOB: - - // case HAL_PIXEL_FORMAT_YCbCr_420_888: - // case HAL_PIXEL_FORMAT_YCbCr_422_SP: - // case HAL_PIXEL_FORMAT_YCrCb_420_SP: - // case HAL_PIXEL_FORMAT_YCbCr_422_I: - default: - ALOGW("Unsupported format: 0x%04x, returning null converter function", - format); - } - return NULL; -} - -// Whether we support a given format -bool IsFormatSupported(uint32_t format) { return GetConverter(format) != NULL; } - -bool CanCompositeLayer(const hwc_layer_1_t& layer) { - if (layer.handle == NULL) { - ALOGW("%s received a layer with a null handler", __FUNCTION__); - return false; - } - int format = reinterpret_cast<const private_handle_t*>(layer.handle)->format; - if (!IsFormatSupported(format)) { - ALOGD("Unsupported pixel format: 0x%x, doing software composition instead", - format); - return false; - } - return true; -} - -/******************************************************************************* -Libyuv's convert functions only allow the combination of any rotation (multiple -of 90 degrees) and a vertical flip, but not horizontal flips. -Surfaceflinger's transformations are expressed in terms of a vertical flip, a -horizontal flip and/or a single 90 degrees clockwise rotation (see -NATIVE_WINDOW_TRANSFORM_HINT documentation on system/window.h for more insight). -The following code allows to turn a horizontal flip into a 180 degrees rotation -and a vertical flip. -*******************************************************************************/ -libyuv::RotationMode GetRotationFromTransform(uint32_t transform) { - uint32_t rotation = - (transform & HAL_TRANSFORM_ROT_90) ? 1 : 0; // 1 * ROT90 bit - rotation += (transform & HAL_TRANSFORM_FLIP_H) ? 2 : 0; // 2 * VFLIP bit - return static_cast<libyuv::RotationMode>(90 * rotation); -} - -bool GetVFlipFromTransform(uint32_t transform) { - // vertical flip xor horizontal flip - return ((transform & HAL_TRANSFORM_FLIP_V) >> 1) ^ - (transform & HAL_TRANSFORM_FLIP_H); -} - -struct BufferSpec { - uint8_t* buffer; - size_t size; - int width; - int height; - int stride; - int crop_x; - int crop_y; - int crop_width; - int crop_height; - uint32_t format; - - BufferSpec(uint8_t* buffer, size_t size, int width, int height, int stride) - : buffer(buffer), - size(size), - width(width), - height(height), - stride(stride), - crop_x(0), - crop_y(0), - crop_width(width), - crop_height(height), - format(HAL_PIXEL_FORMAT_RGBA_8888) {} -}; - -int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - // use the stride in pixels as the source width - int stride_in_pixels = src.stride / formatToBytesPerPixel(src.format); - - // The following calculation of plane offsets and alignments are based on - // swiftshader's Sampler::setTextureLevel() implementation - // (Renderer/Sampler.cpp:225) - uint8_t* src_y = src.buffer; - int stride_y = stride_in_pixels; - uint8_t* src_v = src_y + stride_y * src.height; - int stride_v = cvd::AlignToPowerOf2(stride_y / 2, 4); - uint8_t* src_u = src_v + stride_v * src.height / 2; - int stride_u = cvd::AlignToPowerOf2(stride_y / 2, 4); - - // Adjust for crop - src_y += src.crop_y * stride_y + src.crop_x; - src_v += (src.crop_y / 2) * stride_v + (src.crop_x / 2); - src_u += (src.crop_y / 2) * stride_u + (src.crop_x / 2); - uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride + - dst.crop_x * formatToBytesPerPixel(dst.format); - - // YV12 is the same as I420, with the U and V planes swapped - return libyuv::I420ToARGB(src_y, stride_y, src_v, stride_v, src_u, stride_u, - dst_buffer, dst.stride, dst.crop_width, - v_flip ? -dst.crop_height : dst.crop_height); -} - -int DoConversion(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - return (*GetConverter(src.format))(src, dst, v_flip); -} - -int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - // Point to the upper left corner of the crop rectangle - uint8_t* src_buffer = src.buffer + src.crop_y * src.stride + - src.crop_x * formatToBytesPerPixel(src.format); - uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride + - dst.crop_x * formatToBytesPerPixel(dst.format); - int width = src.crop_width; - int height = src.crop_height; - - if (v_flip) { - height = -height; - } - - // HAL formats are named based on the order of the pixel componets on the - // byte stream, while libyuv formats are named based on the order of those - // pixel components in an integer written from left to right. So - // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888. - return libyuv::ARGBCopy(src_buffer, src.stride, dst_buffer, dst.stride, width, - height); -} - -int DoRotation(const BufferSpec& src, const BufferSpec& dst, - libyuv::RotationMode rotation, bool v_flip) { - // Point to the upper left corner of the crop rectangles - uint8_t* src_buffer = src.buffer + src.crop_y * src.stride + - src.crop_x * formatToBytesPerPixel(src.format); - uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride + - dst.crop_x * formatToBytesPerPixel(dst.format); - int width = src.crop_width; - int height = src.crop_height; - - if (v_flip) { - height = -height; - } - - return libyuv::ARGBRotate(src_buffer, src.stride, dst_buffer, dst.stride, - width, height, rotation); -} - -int DoScaling(const BufferSpec& src, const BufferSpec& dst, bool v_flip) { - // Point to the upper left corner of the crop rectangles - uint8_t* src_buffer = src.buffer + src.crop_y * src.stride + - src.crop_x * formatToBytesPerPixel(src.format); - uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride + - dst.crop_x * formatToBytesPerPixel(dst.format); - int src_width = src.crop_width; - int src_height = src.crop_height; - int dst_width = dst.crop_width; - int dst_height = dst.crop_height; - - if (v_flip) { - src_height = -src_height; - } - - return libyuv::ARGBScale(src_buffer, src.stride, src_width, src_height, - dst_buffer, dst.stride, dst_width, dst_height, - libyuv::kFilterBilinear); -} - -int DoAttenuation(const BufferSpec& src, const BufferSpec& dest, bool v_flip) { - // Point to the upper left corner of the crop rectangles - uint8_t* src_buffer = src.buffer + src.crop_y * src.stride + - src.crop_x * formatToBytesPerPixel(src.format); - uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride + - dest.crop_x * formatToBytesPerPixel(dest.format); - int width = dest.crop_width; - int height = dest.crop_height; - - if (v_flip) { - height = -height; - } - - return libyuv::ARGBAttenuate(src_buffer, src.stride, dst_buffer, dest.stride, - width, height); -} - -int DoBlending(const BufferSpec& src, const BufferSpec& dest, bool v_flip) { - // Point to the upper left corner of the crop rectangles - uint8_t* src_buffer = src.buffer + src.crop_y * src.stride + - src.crop_x * formatToBytesPerPixel(src.format); - uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride + - dest.crop_x * formatToBytesPerPixel(dest.format); - int width = dest.crop_width; - int height = dest.crop_height; - - if (v_flip) { - height = -height; - } - - // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares - // for the position of alpha in the pixel and not the position of the colors - // this function is perfectly usable. - return libyuv::ARGBBlend(src_buffer, src.stride, dst_buffer, dest.stride, - dst_buffer, dest.stride, width, height); -} - -} // namespace - -void CpuComposer::CompositeLayer(hwc_layer_1_t* src_layer, int buffer_idx) { - libyuv::RotationMode rotation = - GetRotationFromTransform(src_layer->transform); - - const private_handle_t* src_priv_handle = - reinterpret_cast<const private_handle_t*>(src_layer->handle); - - // TODO(jemoreira): Remove the hardcoded fomat. - bool needs_conversion = src_priv_handle->format != HAL_PIXEL_FORMAT_RGBX_8888; - bool needs_scaling = LayerNeedsScaling(*src_layer); - bool needs_rotation = rotation != libyuv::kRotate0; - bool needs_transpose = needs_rotation && rotation != libyuv::kRotate180; - bool needs_vflip = GetVFlipFromTransform(src_layer->transform); - bool needs_attenuation = LayerNeedsAttenuation(*src_layer); - bool needs_blending = LayerNeedsBlending(*src_layer); - bool needs_copy = !(needs_conversion || needs_scaling || needs_rotation || - needs_vflip || needs_attenuation || needs_blending); - - uint8_t* src_buffer; - uint8_t* dst_buffer = - reinterpret_cast<uint8_t*>(screen_view_->GetBuffer(buffer_idx)); - int retval = gralloc_module_->lock( - gralloc_module_, src_layer->handle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0, - src_priv_handle->x_res, src_priv_handle->y_res, - reinterpret_cast<void**>(&src_buffer)); - if (retval) { - ALOGE("Got error code %d from lock function", retval); - return; - } - if (retval) { - ALOGE("Got error code %d from lock function", retval); - // TODO(jemoreira): Use a lock_guard-like object. - gralloc_module_->unlock(gralloc_module_, src_priv_handle); - return; - } - - BufferSpec src_layer_spec(src_buffer, src_priv_handle->total_size, - src_priv_handle->x_res, src_priv_handle->y_res, - src_priv_handle->stride_in_pixels * - formatToBytesPerPixel(src_priv_handle->format)); - src_layer_spec.crop_x = src_layer->sourceCrop.left; - src_layer_spec.crop_y = src_layer->sourceCrop.top; - src_layer_spec.crop_width = - src_layer->sourceCrop.right - src_layer->sourceCrop.left; - src_layer_spec.crop_height = - src_layer->sourceCrop.bottom - src_layer->sourceCrop.top; - src_layer_spec.format = src_priv_handle->format; - - BufferSpec dst_layer_spec(dst_buffer, screen_view_->buffer_size(), - screen_view_->x_res(), screen_view_->y_res(), - screen_view_->line_length()); - dst_layer_spec.crop_x = src_layer->displayFrame.left; - dst_layer_spec.crop_y = src_layer->displayFrame.top; - dst_layer_spec.crop_width = - src_layer->displayFrame.right - src_layer->displayFrame.left; - dst_layer_spec.crop_height = - src_layer->displayFrame.bottom - src_layer->displayFrame.top; - // TODO(jemoreira): Remove the hardcoded fomat. - dst_layer_spec.format = HAL_PIXEL_FORMAT_RGBX_8888; - - // Add the destination layer to the bottom of the buffer stack - std::vector<BufferSpec> dest_buffer_stack(1, dst_layer_spec); - - // If more than operation is to be performed, a temporary buffer is needed for - // each additional operation - - // N operations need N destination buffers, the destination layer (the - // framebuffer) is one of them, so only N-1 temporary buffers are needed. - // Vertical flip is not taken into account because it can be done together - // with any other operation. - int needed_tmp_buffers = (needs_conversion ? 1 : 0) + - (needs_scaling ? 1 : 0) + (needs_rotation ? 1 : 0) + - (needs_attenuation ? 1 : 0) + - (needs_blending ? 1 : 0) + (needs_copy ? 1 : 0) - 1; - - int x_res = src_layer->displayFrame.right - src_layer->displayFrame.left; - int y_res = src_layer->displayFrame.bottom - src_layer->displayFrame.top; - size_t output_frame_size = - x_res * cvd::AlignToPowerOf2(y_res * screen_view_->bytes_per_pixel(), 4); - while (needed_tmp_buffers > 0) { - BufferSpec tmp( - RotateTmpBuffer(needed_tmp_buffers), output_frame_size, x_res, y_res, - cvd::AlignToPowerOf2(x_res * screen_view_->bytes_per_pixel(), 4)); - dest_buffer_stack.push_back(tmp); - needed_tmp_buffers--; - } - - // Conversion and scaling should always be the first operations, so that every - // other operation works on equally sized frames (garanteed to fit in the tmp - // buffers) - - // TODO(jemoreira): We are converting to ARGB as the first step under the - // assumption that scaling ARGB is faster than scaling I420 (the most common). - // This should be confirmed with testing. - if (needs_conversion) { - BufferSpec& dst_buffer_spec = dest_buffer_stack.back(); - if (needs_scaling || needs_transpose) { - // If a rotation or a scaling operation are needed the dimensions at the - // top of the buffer stack are wrong (wrong sizes for scaling, swapped - // width and height for 90 and 270 rotations). - // Make width and height match the crop sizes on the source - int src_width = src_layer_spec.crop_width; - int src_height = src_layer_spec.crop_height; - int dst_stride = - cvd::AlignToPowerOf2(src_width * screen_view_->bytes_per_pixel(), 4); - size_t needed_size = dst_stride * src_height; - dst_buffer_spec.width = src_width; - dst_buffer_spec.height = src_height; - // Ajust the stride accordingly - dst_buffer_spec.stride = dst_stride; - // Crop sizes also need to be adjusted - dst_buffer_spec.crop_width = src_width; - dst_buffer_spec.crop_height = src_height; - dst_buffer_spec.size = needed_size; - // crop_x and y are fine at 0, format is already set to match destination - - // In case of a scale, the source frame may be bigger than the default tmp - // buffer size - if (needed_size > tmp_buffer_.size() / kNumTmpBufferPieces) { - dst_buffer_spec.buffer = GetSpecialTmpBuffer(needed_size); - } - } - retval = DoConversion(src_layer_spec, dst_buffer_spec, needs_vflip); - if (retval) { - ALOGE("Got error code %d from DoConversion function", retval); - } - needs_vflip = false; - src_layer_spec = dst_buffer_spec; - dest_buffer_stack.pop_back(); - } - - if (needs_scaling) { - BufferSpec& dst_buffer_spec = dest_buffer_stack.back(); - if (needs_transpose) { - // If a rotation is needed, the temporary buffer has the correct size but - // needs to be transposed and have its stride updated accordingly. The - // crop sizes also needs to be transposed, but not the x and y since they - // are both zero in a temporary buffer (and it is a temporary buffer - // because a rotation will be performed next). - std::swap(dst_buffer_spec.width, dst_buffer_spec.height); - std::swap(dst_buffer_spec.crop_width, dst_buffer_spec.crop_height); - // TODO (jemoreira): Aligment (To align here may cause the needed size to - // be bigger than the buffer, so care should be taken) - dst_buffer_spec.stride = - dst_buffer_spec.width * screen_view_->bytes_per_pixel(); - } - retval = DoScaling(src_layer_spec, dst_buffer_spec, needs_vflip); - needs_vflip = false; - if (retval) { - ALOGE("Got error code %d from DoScaling function", retval); - } - src_layer_spec = dst_buffer_spec; - dest_buffer_stack.pop_back(); - } - - if (needs_rotation) { - retval = DoRotation(src_layer_spec, dest_buffer_stack.back(), rotation, - needs_vflip); - needs_vflip = false; - if (retval) { - ALOGE("Got error code %d from DoTransform function", retval); - } - src_layer_spec = dest_buffer_stack.back(); - dest_buffer_stack.pop_back(); - } - - if (needs_attenuation) { - retval = - DoAttenuation(src_layer_spec, dest_buffer_stack.back(), needs_vflip); - needs_vflip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); - } - src_layer_spec = dest_buffer_stack.back(); - dest_buffer_stack.pop_back(); - } - - if (needs_copy) { - retval = DoCopy(src_layer_spec, dest_buffer_stack.back(), needs_vflip); - needs_vflip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); - } - src_layer_spec = dest_buffer_stack.back(); - dest_buffer_stack.pop_back(); - } - - // Blending (if needed) should always be the last operation, so that it reads - // and writes in the destination layer and not some temporary buffer. - if (needs_blending) { - retval = DoBlending(src_layer_spec, dest_buffer_stack.back(), needs_vflip); - needs_vflip = false; - if (retval) { - ALOGE("Got error code %d from DoBlending function", retval); - } - // Don't need to assign destination to source in the last one - dest_buffer_stack.pop_back(); - } - - gralloc_module_->unlock(gralloc_module_, src_priv_handle); -} - -/* static */ const int CpuComposer::kNumTmpBufferPieces = 2; - -CpuComposer::CpuComposer(std::unique_ptr<ScreenView> screen_view) - : BaseComposer(std::move(screen_view)), - tmp_buffer_(kNumTmpBufferPieces * screen_view_->buffer_size()) {} - -int CpuComposer::PrepareLayers(size_t num_layers, hwc_layer_1_t* layers) { - int composited_layers_count = 0; - - // Loop over layers in inverse order of z-index - for (size_t layer_index = num_layers; layer_index > 0;) { - // Decrement here to be able to compare unsigned integer with 0 in the - // loop condition - --layer_index; - if (IS_TARGET_FRAMEBUFFER(layers[layer_index].compositionType)) { - continue; - } - if (layers[layer_index].flags & HWC_SKIP_LAYER) { - continue; - } - if (layers[layer_index].compositionType == HWC_BACKGROUND) { - layers[layer_index].compositionType = HWC_FRAMEBUFFER; - continue; - } - layers[layer_index].compositionType = HWC_OVERLAY; - // Hwcomposer cannot draw below software-composed layers, so we need - // to mark those HWC_FRAMEBUFFER as well. - for (size_t top_idx = layer_index + 1; top_idx < num_layers; ++top_idx) { - // layers marked as skip are in a state that makes them unreliable to - // read, so it's best to assume they cover the whole screen - if (layers[top_idx].flags & HWC_SKIP_LAYER || - (layers[top_idx].compositionType == HWC_FRAMEBUFFER && - LayersOverlap(layers[layer_index], layers[top_idx]))) { - layers[layer_index].compositionType = HWC_FRAMEBUFFER; - break; - } - } - if (layers[layer_index].compositionType == HWC_OVERLAY && - !CanCompositeLayer(layers[layer_index])) { - layers[layer_index].compositionType = HWC_FRAMEBUFFER; - } - if (layers[layer_index].compositionType == HWC_OVERLAY) { - ++composited_layers_count; - } - } - return composited_layers_count; -} - -int CpuComposer::SetLayers(size_t num_layers, hwc_layer_1_t* layers) { - int targetFbs = 0; - int buffer_idx = screen_view_->NextBuffer(); - - // The framebuffer target layer should be composed if at least one layers was - // marked HWC_FRAMEBUFFER or if it's the only layer in the composition - // (unlikely) - bool fb_target = true; - for (size_t idx = 0; idx < num_layers; idx++) { - if (layers[idx].compositionType == HWC_FRAMEBUFFER) { - // At least one was found - fb_target = true; - break; - } - if (layers[idx].compositionType == HWC_OVERLAY) { - // Not the only layer in the composition - fb_target = false; - } - } - - // When the framebuffer target needs to be composed, it has to go first. - if (fb_target) { - for (size_t idx = 0; idx < num_layers; idx++) { - if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) { - CompositeLayer(&layers[idx], buffer_idx); - break; - } - } - } - - for (size_t idx = 0; idx < num_layers; idx++) { - if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) { - ++targetFbs; - } - if (layers[idx].compositionType == HWC_OVERLAY && - !(layers[idx].flags & HWC_SKIP_LAYER)) { - CompositeLayer(&layers[idx], buffer_idx); - } - } - if (targetFbs != 1) { - ALOGW("Saw %zu layers, posted=%d", num_layers, targetFbs); - } - screen_view_->Broadcast(buffer_idx); - return 0; -} - -uint8_t* CpuComposer::RotateTmpBuffer(unsigned int order) { - return &tmp_buffer_[(order % kNumTmpBufferPieces) * tmp_buffer_.size() / - kNumTmpBufferPieces]; -} - -uint8_t* CpuComposer::GetSpecialTmpBuffer(size_t needed_size) { - special_tmp_buffer_.resize(needed_size); - return &special_tmp_buffer_[0]; -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/cpu_composer.h b/guest/hals/hwcomposer/common/cpu_composer.h deleted file mode 100644 index a4ace223..00000000 --- a/guest/hals/hwcomposer/common/cpu_composer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <vector> - -#include <hardware/gralloc.h> - -#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" - -#include "guest/hals/hwcomposer/common/base_composer.h" -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -namespace cvd { - -class CpuComposer : public BaseComposer { - public: - CpuComposer(std::unique_ptr<ScreenView> screen_view); - virtual ~CpuComposer() = default; - - // override - int PrepareLayers(size_t num_layers, hwc_layer_1_t* layers) override; - // override - int SetLayers(size_t num_layers, hwc_layer_1_t* layers) override; - - protected: - static const int kNumTmpBufferPieces; - uint8_t* RotateTmpBuffer(unsigned int order); - uint8_t* GetSpecialTmpBuffer(size_t needed_size); - void CompositeLayer(hwc_layer_1_t* src_layer, int32_t fb_offset); - std::vector<uint8_t> tmp_buffer_; - std::vector<uint8_t> special_tmp_buffer_; -}; - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/geometry_utils.cpp b/guest/hals/hwcomposer/common/geometry_utils.cpp deleted file mode 100644 index ade2d787..00000000 --- a/guest/hals/hwcomposer/common/geometry_utils.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/geometry_utils.h" - -#include <algorithm> -#include <utility> - -namespace cvd { - -bool LayersOverlap(const hwc_layer_1_t& layer1, const hwc_layer_1_t& layer2) { - int left1 = layer1.displayFrame.left; - int right1 = layer1.displayFrame.right; - int top1 = layer1.displayFrame.top; - int bottom1 = layer1.displayFrame.bottom; - - int left2 = layer2.displayFrame.left; - int right2 = layer2.displayFrame.right; - int top2 = layer2.displayFrame.top; - int bottom2 = layer2.displayFrame.bottom; - - bool overlap_x = left1 < right2 && left2 < right1; - bool overlap_y = top1 < bottom2 && top2 < bottom1; - - return overlap_x && overlap_y; -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/geometry_utils.h b/guest/hals/hwcomposer/common/geometry_utils.h deleted file mode 100644 index 5563fa7d..00000000 --- a/guest/hals/hwcomposer/common/geometry_utils.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -namespace cvd { - -bool LayersOverlap(const hwc_layer_1_t& layer1, const hwc_layer_1_t& layer2); - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/hwcomposer.cpp b/guest/hals/hwcomposer/common/hwcomposer.cpp deleted file mode 100644 index d86619d3..00000000 --- a/guest/hals/hwcomposer/common/hwcomposer.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -// Versions of hwcomposer we implement: -// JB: 0.3 -// JB-MR1 to N : 1.1 -// N-MR1 to ... : We report 1.1 but SurfaceFlinger has the option to use an -// adapter to treat our 1.1 hwcomposer as a 2.0. If SF stops using that adapter -// to support 1.1 implementations it can be copied into cuttlefish from -// frameworks/native/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.* - -#define LOG_TAG "hwc.cf_x86" -#define HWC_REMOVE_DEPRECATED_VERSIONS 1 - -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -#include <errno.h> -#include <fcntl.h> -#include <math.h> -#include <poll.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <sync/sync.h> -#include <sys/resource.h> -#include <sys/time.h> - -#include <string> - -#include <cutils/compiler.h> -#include <cutils/properties.h> -#include <hardware/gralloc.h> -#include <hardware/hardware.h> -#include <hardware/hwcomposer.h> -#include <hardware/hwcomposer_defs.h> -#include <log/log.h> -#include <utils/String8.h> -#include <utils/Vector.h> - -#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h" - -#include "guest/hals/hwcomposer/common/base_composer.h" -#include "guest/hals/hwcomposer/common/cpu_composer.h" -#include "guest/hals/hwcomposer/common/geometry_utils.h" -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -#ifdef USE_OLD_HWCOMPOSER -typedef cvd::BaseComposer ComposerType; -#else -typedef cvd::CpuComposer ComposerType; -#endif - -struct hwc_composer_device_data_t { - const hwc_procs_t* procs; - pthread_t vsync_thread; - int64_t vsync_base_timestamp; - int32_t vsync_period_ns; -}; - -struct cvd_hwc_composer_device_1_t { - hwc_composer_device_1_t base; - hwc_composer_device_data_t vsync_data; - cvd::BaseComposer* composer; -}; - -namespace { - -void* hwc_vsync_thread(void* data) { - struct hwc_composer_device_data_t* pdev = - (struct hwc_composer_device_data_t*)data; - setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); - - int64_t base_timestamp = pdev->vsync_base_timestamp; - int64_t last_logged = base_timestamp / 1e9; - int sent = 0; - int last_sent = 0; - static const int log_interval = 60; - void (*vsync_proc)(const struct hwc_procs*, int, int64_t) = nullptr; - bool log_no_procs = true, log_no_vsync = true; - while (true) { - struct timespec rt; - if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { - LOG_ALWAYS_FATAL("%s:%d error in vsync thread clock_gettime: %s", - __FILE__, __LINE__, strerror(errno)); - } - - int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; - // Given now's timestamp calculate the time of the next timestamp. - timestamp += pdev->vsync_period_ns - - (timestamp - base_timestamp) % pdev->vsync_period_ns; - - rt.tv_sec = timestamp / 1e9; - rt.tv_nsec = timestamp % static_cast<int32_t>(1e9); - int err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rt, NULL); - if (err == -1) { - ALOGE("error in vsync thread: %s", strerror(errno)); - if (errno == EINTR) { - continue; - } - } - - // The vsync thread is started on device open, it may run before the - // registerProcs callback has a chance to be called, so we need to make sure - // procs is not NULL before dereferencing it. - if (pdev && pdev->procs) { - vsync_proc = pdev->procs->vsync; - } else if (log_no_procs) { - log_no_procs = false; - ALOGI("procs is not set yet, unable to deliver vsync event"); - } - if (vsync_proc) { - vsync_proc(const_cast<hwc_procs_t*>(pdev->procs), 0, timestamp); - ++sent; - } else if (log_no_vsync) { - log_no_vsync = false; - ALOGE("vsync callback is null (but procs was already set)"); - } - if (rt.tv_sec - last_logged > log_interval) { - ALOGI("Sent %d syncs in %ds", sent - last_sent, log_interval); - last_logged = rt.tv_sec; - last_sent = sent; - } - } - - return NULL; -} - -std::string CompositionString(int type) { - switch (type) { - case HWC_FRAMEBUFFER: - return "Framebuffer"; - case HWC_OVERLAY: - return "Overlay"; - case HWC_BACKGROUND: - return "Background"; - case HWC_FRAMEBUFFER_TARGET: - return "FramebufferTarget"; - case HWC_SIDEBAND: - return "Sideband"; - case HWC_CURSOR_OVERLAY: - return "CursorOverlay"; - default: - return std::string("Unknown (") + std::to_string(type) + ")"; - } -} - -void LogLayers(int num_layers, hwc_layer_1_t* layers, int invalid) { - ALOGE("Layers:"); - for (int idx = 0; idx < num_layers; ++idx) { - std::string log_line; - if (idx == invalid) { - log_line = "Invalid layer: "; - } - log_line += - "Composition Type: " + CompositionString(layers[idx].compositionType); - ALOGE("%s", log_line.c_str()); - } -} - -// Ensures that the layer does not include any inconsistencies -bool IsValidLayer(const hwc_layer_1_t& layer) { - if (layer.flags & HWC_SKIP_LAYER) { - // A layer we are asked to skip validate should not be marked as skip - ALOGE("%s: Layer is marked as skip", __FUNCTION__); - return false; - } - // Check displayFrame - if (layer.displayFrame.left > layer.displayFrame.right || - layer.displayFrame.top > layer.displayFrame.bottom) { - ALOGE( - "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = " - "%d, bottom = %d]", - __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right, - layer.displayFrame.top, layer.displayFrame.bottom); - return false; - } - // Validate the handle - if (private_handle_t::validate(layer.handle) != 0) { - ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__); - return false; - } - const private_handle_t* p_handle = - reinterpret_cast<const private_handle_t*>(layer.handle); - // Check sourceCrop - if (layer.sourceCrop.left > layer.sourceCrop.right || - layer.sourceCrop.top > layer.sourceCrop.bottom) { - ALOGE( - "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = " - "%d, bottom = %d]", - __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, - layer.sourceCrop.top, layer.sourceCrop.bottom); - return false; - } - if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 || - layer.sourceCrop.right > p_handle->x_res || - layer.sourceCrop.bottom > p_handle->y_res) { - ALOGE( - "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, " - "right = %d, top = %d, bottom = %d], handle = [width = %d, height = " - "%d]", - __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right, - layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res, - p_handle->y_res); - return false; - } - return true; -} - -bool IsValidComposition(int num_layers, hwc_layer_1_t* layers, bool on_set) { - if (num_layers == 0) { - ALOGE("Composition requested with 0 layers"); - return false; - } - // Sometimes the hwcomposer receives a prepare and set calls with no other - // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case - // independently as a valid composition, but issue a warning about it. - if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET && - layers[0].handle == NULL) { - ALOGW("Received request for empty composition, treating as valid noop"); - return true; - } - // The FRAMEBUFFER_TARGET layer needs to be sane only if - // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer - // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer - // marked overlay or framebuffer means that surfaceflinger decided to go for - // OpenGL without asking the hwcomposer first) - bool check_fb_target = true; - for (int idx = 0; idx < num_layers; ++idx) { - if (layers[idx].compositionType == HWC_FRAMEBUFFER) { - // There is at least one, so it needs to be checked. - // It may have been set to false before, so ensure it's set to true. - check_fb_target = true; - break; - } - if (layers[idx].compositionType == HWC_OVERLAY) { - // At least one overlay, we may not need to. - check_fb_target = false; - } - } - - for (int idx = 0; idx < num_layers; ++idx) { - switch (layers[idx].compositionType) { - case HWC_FRAMEBUFFER_TARGET: - // In the call to prepare() the framebuffer target does not have a valid - // buffer_handle, so we don't validate it yet. - if (on_set && check_fb_target && !IsValidLayer(layers[idx])) { - ALOGE("%s: Invalid layer found", __FUNCTION__); - LogLayers(num_layers, layers, idx); - return false; - } - break; - case HWC_OVERLAY: - if (!(layers[idx].flags & HWC_SKIP_LAYER) && - !IsValidLayer(layers[idx])) { - ALOGE("%s: Invalid layer found", __FUNCTION__); - LogLayers(num_layers, layers, idx); - return false; - } - break; - } - } - return true; -} - -} // namespace - -static int cvd_hwc_prepare(hwc_composer_device_1_t* dev, size_t numDisplays, - hwc_display_contents_1_t** displays) { - if (!numDisplays || !displays) return 0; - - hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY]; - - if (!list) return 0; - if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) { - LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); - return -1; - } - reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers( - list->numHwLayers, &list->hwLayers[0]); - return 0; -} - -static int cvd_hwc_set(hwc_composer_device_1_t* dev, size_t numDisplays, - hwc_display_contents_1_t** displays) { - if (!numDisplays || !displays) return 0; - - hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY]; - if (!contents) return 0; - - hwc_layer_1_t* layers = &contents->hwLayers[0]; - if (contents->numHwLayers == 1 && - layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) { - ALOGW("Received request for empty composition, treating as valid noop"); - return 0; - } - if (!IsValidComposition(contents->numHwLayers, layers, true)) { - LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__); - return -1; - } - int retval = - reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->SetLayers( - contents->numHwLayers, layers); - - int closedFds = 0; - for (size_t index = 0; index < contents->numHwLayers; ++index) { - if (layers[index].acquireFenceFd != -1) { - close(layers[index].acquireFenceFd); - layers[index].acquireFenceFd = -1; - ++closedFds; - } - } - if (closedFds) { - ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds); - } - - // TODO(ghartman): This should be set before returning. On the next set it - // should be signalled when we load the new frame. - contents->retireFenceFd = -1; - return retval; -} - -static void cvd_hwc_register_procs(hwc_composer_device_1_t* dev, - const hwc_procs_t* procs) { - struct cvd_hwc_composer_device_1_t* pdev = - (struct cvd_hwc_composer_device_1_t*)dev; - pdev->vsync_data.procs = procs; -} - -static int cvd_hwc_query(hwc_composer_device_1_t* dev, int what, int* value) { - struct cvd_hwc_composer_device_1_t* pdev = - (struct cvd_hwc_composer_device_1_t*)dev; - - switch (what) { - case HWC_BACKGROUND_LAYER_SUPPORTED: - // we support the background layer - value[0] = 0; - break; - case HWC_VSYNC_PERIOD: - value[0] = pdev->vsync_data.vsync_period_ns; - break; - default: - // unsupported query - ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what); - return -EINVAL; - } - return 0; -} - -static int cvd_hwc_event_control(hwc_composer_device_1_t* /*dev*/, int /*dpy*/, - int event, int /*enabled*/) { - if (event == HWC_EVENT_VSYNC) { - return 0; - } - return -EINVAL; -} - -static int cvd_hwc_blank(hwc_composer_device_1_t* /*dev*/, int disp, int /*blank*/) { - if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL; - return 0; -} - -static void cvd_hwc_dump(hwc_composer_device_1_t* dev, char* buff, int buff_len) { - reinterpret_cast<cvd_hwc_composer_device_1_t*>(dev)->composer->Dump(buff, - buff_len); -} - -static int cvd_hwc_get_display_configs(hwc_composer_device_1_t* /*dev*/, int disp, - uint32_t* configs, size_t* numConfigs) { - if (*numConfigs == 0) return 0; - - if (IS_PRIMARY_DISPLAY(disp)) { - configs[0] = 0; - *numConfigs = 1; - return 0; - } - - return -EINVAL; -} - -static int32_t cvd_hwc_attribute(struct cvd_hwc_composer_device_1_t* pdev, - const uint32_t attribute) { - switch (attribute) { - case HWC_DISPLAY_VSYNC_PERIOD: - return pdev->vsync_data.vsync_period_ns; - case HWC_DISPLAY_WIDTH: - return pdev->composer->x_res(); - case HWC_DISPLAY_HEIGHT: - return pdev->composer->y_res(); - case HWC_DISPLAY_DPI_X: - ALOGI("Reporting DPI_X of %d", pdev->composer->dpi()); - // The number of pixels per thousand inches - return pdev->composer->dpi() * 1000; - case HWC_DISPLAY_DPI_Y: - ALOGI("Reporting DPI_Y of %d", pdev->composer->dpi()); - // The number of pixels per thousand inches - return pdev->composer->dpi() * 1000; - default: - ALOGE("unknown display attribute %u", attribute); - return -EINVAL; - } -} - -static int cvd_hwc_get_display_attributes(hwc_composer_device_1_t* dev, int disp, - uint32_t config __unused, - const uint32_t* attributes, - int32_t* values) { - struct cvd_hwc_composer_device_1_t* pdev = - (struct cvd_hwc_composer_device_1_t*)dev; - - if (!IS_PRIMARY_DISPLAY(disp)) { - ALOGE("unknown display type %u", disp); - return -EINVAL; - } - - for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) { - values[i] = cvd_hwc_attribute(pdev, attributes[i]); - } - - return 0; -} - -static int cvd_hwc_close(hw_device_t* device) { - struct cvd_hwc_composer_device_1_t* dev = - (struct cvd_hwc_composer_device_1_t*)device; - ALOGE("cvd_hwc_close"); - pthread_kill(dev->vsync_data.vsync_thread, SIGTERM); - pthread_join(dev->vsync_data.vsync_thread, NULL); - delete dev->composer; - delete dev; - return 0; -} - -namespace cvd { - -int cvd_hwc_open(std::unique_ptr<ScreenView> screen_view, - const struct hw_module_t* module, const char* name, - struct hw_device_t** device) { - ALOGI("%s", __FUNCTION__); - if (strcmp(name, HWC_HARDWARE_COMPOSER)) { - ALOGE("%s called with bad name %s", __FUNCTION__, name); - return -EINVAL; - } - - cvd_hwc_composer_device_1_t* dev = new cvd_hwc_composer_device_1_t(); - if (!dev) { - ALOGE("%s failed to allocate dev", __FUNCTION__); - return -ENOMEM; - } - - struct timespec rt; - if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) { - ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__, - strerror(errno)); - } - dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec; - dev->vsync_data.vsync_period_ns = 1e9 / screen_view->refresh_rate(); - - dev->base.common.tag = HARDWARE_DEVICE_TAG; - dev->base.common.version = HWC_DEVICE_API_VERSION_1_1; - dev->base.common.module = const_cast<hw_module_t*>(module); - dev->base.common.close = cvd_hwc_close; - - dev->base.prepare = cvd_hwc_prepare; - dev->base.set = cvd_hwc_set; - dev->base.query = cvd_hwc_query; - dev->base.registerProcs = cvd_hwc_register_procs; - dev->base.dump = cvd_hwc_dump; - dev->base.blank = cvd_hwc_blank; - dev->base.eventControl = cvd_hwc_event_control; - dev->base.getDisplayConfigs = cvd_hwc_get_display_configs; - dev->base.getDisplayAttributes = cvd_hwc_get_display_attributes; -#ifdef GATHER_STATS - dev->composer = new cvd::StatsKeepingComposer<ComposerType>( - dev->vsync_data.vsync_base_timestamp, std::move(screen_view)); -#else - dev->composer = new ComposerType(std::move(screen_view)); -#endif - - if (!dev->composer) { - ALOGE("Failed to instantiate the composer object"); - delete dev; - return -1; - } - int ret = pthread_create(&dev->vsync_data.vsync_thread, NULL, - hwc_vsync_thread, &dev->vsync_data); - if (ret) { - ALOGE("failed to start vsync thread: %s", strerror(ret)); - ret = -ret; - delete dev->composer; - delete dev; - } else { - *device = &dev->base.common; - } - - return ret; -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/hwcomposer.h b/guest/hals/hwcomposer/common/hwcomposer.h deleted file mode 100644 index 0d911440..00000000 --- a/guest/hals/hwcomposer/common/hwcomposer.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <memory> - -#include <hardware/hwcomposer.h> -#include <hardware/hwcomposer_defs.h> - -#include "guest/hals/hwcomposer/common/screen_view.h" - -#define IS_TARGET_FRAMEBUFFER(x) ((x) == HWC_FRAMEBUFFER_TARGET) -#define IS_PRIMARY_DISPLAY(x) ((x) == HWC_DISPLAY_PRIMARY) - -namespace cvd { -int cvd_hwc_open(std::unique_ptr<ScreenView> screen_view, - const struct hw_module_t* module, const char* name, - struct hw_device_t** device); -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/screen_view.cpp b/guest/hals/hwcomposer/common/screen_view.cpp deleted file mode 100644 index 48f9fa6b..00000000 --- a/guest/hals/hwcomposer/common/screen_view.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/screen_view.h" - -#include "common/libs/utils/size_utils.h" - -namespace cvd { - -int ScreenView::NextBuffer() { - int num_buffers = this->num_buffers(); - last_buffer_ = num_buffers > 0 ? (last_buffer_ + 1) % num_buffers : -1; - return last_buffer_; -} - -size_t ScreenView::buffer_size() const { - return line_length() * y_res() + 4 /* swiftshader padding */; -} - -size_t ScreenView::line_length() const { - return cvd::AlignToPowerOf2(x_res() * bytes_per_pixel(), 4); -} - -int ScreenView::bytes_per_pixel() const { return 4; } -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/screen_view.h b/guest/hals/hwcomposer/common/screen_view.h deleted file mode 100644 index b985f8ff..00000000 --- a/guest/hals/hwcomposer/common/screen_view.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <stdint.h> -#include <sys/time.h> - -namespace cvd { - -struct CompositionStats { - uint32_t num_prepare_calls; - uint16_t num_layers; - uint16_t num_hwcomposited_layers; - timespec last_vsync; - timespec prepare_start; - timespec prepare_end; - timespec set_start; - timespec set_end; -}; - -class ScreenView { - public: - ScreenView() = default; - ScreenView(const ScreenView&) = delete; - virtual ~ScreenView() = default; - - ScreenView& operator=(const ScreenView&) = delete; - - virtual void Broadcast(int buffer_id, - const CompositionStats* stats = nullptr) = 0; - virtual int NextBuffer(); - virtual void* GetBuffer(int buffer_id) = 0; - - virtual int32_t x_res() const = 0; - virtual int32_t y_res() const = 0; - virtual int32_t dpi() const = 0; - virtual int32_t refresh_rate() const = 0; - - size_t buffer_size() const; - size_t line_length() const; - int bytes_per_pixel() const; - - virtual int num_buffers() const = 0; - - private: - int last_buffer_ = 0; -}; -} // namespace cvd
\ No newline at end of file diff --git a/guest/hals/hwcomposer/common/stats_keeper.cpp b/guest/hals/hwcomposer/common/stats_keeper.cpp deleted file mode 100644 index efff1d8b..00000000 --- a/guest/hals/hwcomposer/common/stats_keeper.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/common/stats_keeper.h" - -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> - -#include <algorithm> -#include <utility> -#include <vector> - -#include <log/log.h> - -#include "guest/hals/hwcomposer/common/geometry_utils.h" - -using cvd::LockGuard; -using cvd::Mutex; -using cvd::time::Microseconds; -using cvd::time::MonotonicTimePoint; -using cvd::time::Nanoseconds; -using cvd::time::Seconds; -using cvd::time::TimeDifference; - -namespace cvd { - -namespace { - -// These functions assume that there is at least one suitable element inside -// the multiset. -template <class T> -void MultisetDeleteOne(std::multiset<T>* mset, const T& key) { - mset->erase(mset->find(key)); -} -template <class T> -const T& MultisetMin(const std::multiset<T>& mset) { - return *mset.begin(); -} -template <class T> -const T& MultisetMax(const std::multiset<T>& mset) { - return *mset.rbegin(); -} - -void TimeDifferenceToTimeSpec(const TimeDifference& td, timespec* ts) { - ts->tv_sec = td.seconds(); - ts->tv_nsec = td.subseconds_in_ns(); -} - -} // namespace - -void StatsKeeper::GetLastCompositionStats(CompositionStats* stats_p) { - if (stats_p) { - TimeDifferenceToTimeSpec(last_composition_stats_.prepare_start.SinceEpoch(), - &stats_p->prepare_start); - TimeDifferenceToTimeSpec(last_composition_stats_.prepare_end.SinceEpoch(), - &stats_p->prepare_end); - TimeDifferenceToTimeSpec(last_composition_stats_.set_start.SinceEpoch(), - &stats_p->set_start); - TimeDifferenceToTimeSpec(last_composition_stats_.set_end.SinceEpoch(), - &stats_p->set_end); - TimeDifferenceToTimeSpec(last_composition_stats_.last_vsync.SinceEpoch(), - &stats_p->last_vsync); - - stats_p->num_prepare_calls = last_composition_stats_.num_prepare_calls; - stats_p->num_layers = last_composition_stats_.num_layers; - stats_p->num_hwcomposited_layers = last_composition_stats_.num_hwc_layers; - } -} - -StatsKeeper::StatsKeeper(TimeDifference timespan, int64_t vsync_base, - int32_t vsync_period) - : period_length_(timespan, 1), - vsync_base_(vsync_base), - vsync_period_(vsync_period), - num_layers_(0), - num_hwcomposited_layers_(0), - num_prepare_calls_(0), - num_set_calls_(0), - prepare_call_total_time_(0), - set_call_total_time_(0), - total_layers_area(0), - total_invisible_area(0) { - last_composition_stats_.num_prepare_calls = 0; -} - -StatsKeeper::~StatsKeeper() {} - -void StatsKeeper::RecordPrepareStart(int num_layers) { - last_composition_stats_.num_layers = num_layers; - last_composition_stats_.num_prepare_calls++; - num_prepare_calls_++; - last_composition_stats_.prepare_start = MonotonicTimePoint::Now(); - // Calculate the (expected) time of last VSYNC event. We can only make a guess - // about it because the vsync thread could run late or surfaceflinger could - // run late and call prepare from a previous vsync cycle. - int64_t last_vsync = - Nanoseconds(last_composition_stats_.set_start.SinceEpoch()).count(); - last_vsync -= (last_vsync - vsync_base_) % vsync_period_; - last_composition_stats_.last_vsync = - MonotonicTimePoint() + Nanoseconds(last_vsync); -} - -void StatsKeeper::RecordPrepareEnd(int num_hwcomposited_layers) { - last_composition_stats_.prepare_end = MonotonicTimePoint::Now(); - last_composition_stats_.num_hwc_layers = num_hwcomposited_layers; -} - -void StatsKeeper::RecordSetStart() { - last_composition_stats_.set_start = MonotonicTimePoint::Now(); -} - -void StatsKeeper::RecordSetEnd() { - last_composition_stats_.set_end = MonotonicTimePoint::Now(); - LockGuard<Mutex> lock(mutex_); - num_set_calls_++; - while (!raw_composition_data_.empty() && - period_length_ < last_composition_stats_.set_end - - raw_composition_data_.front().time_point()) { - const CompositionData& front = raw_composition_data_.front(); - - num_prepare_calls_ -= front.num_prepare_calls(); - --num_set_calls_; - num_layers_ -= front.num_layers(); - num_hwcomposited_layers_ -= front.num_hwcomposited_layers(); - prepare_call_total_time_ = - Nanoseconds(prepare_call_total_time_ - front.prepare_time()); - set_call_total_time_ = - Nanoseconds(set_call_total_time_ - front.set_calls_time()); - - MultisetDeleteOne(&prepare_calls_per_set_calls_, front.num_prepare_calls()); - MultisetDeleteOne(&layers_per_compositions_, front.num_layers()); - MultisetDeleteOne(&prepare_call_times_, front.prepare_time()); - MultisetDeleteOne(&set_call_times_, front.set_calls_time()); - if (front.num_hwcomposited_layers() != 0) { - MultisetDeleteOne( - &set_call_times_per_hwcomposited_layer_ns_, - front.set_calls_time().count() / front.num_hwcomposited_layers()); - } - - raw_composition_data_.pop_front(); - } - Nanoseconds last_prepare_call_time_(last_composition_stats_.prepare_end - - last_composition_stats_.prepare_start); - Nanoseconds last_set_call_total_time_(last_composition_stats_.set_end - - last_composition_stats_.set_start); - raw_composition_data_.push_back( - CompositionData(last_composition_stats_.set_end, - last_composition_stats_.num_prepare_calls, - last_composition_stats_.num_layers, - last_composition_stats_.num_hwc_layers, - last_prepare_call_time_, last_set_call_total_time_)); - - // There may be several calls to prepare before a call to set, but the only - // valid call is the last one, so we need to compute these here: - num_layers_ += last_composition_stats_.num_layers; - num_hwcomposited_layers_ += last_composition_stats_.num_hwc_layers; - prepare_call_total_time_ = - Nanoseconds(prepare_call_total_time_ + last_prepare_call_time_); - set_call_total_time_ = - Nanoseconds(set_call_total_time_ + last_set_call_total_time_); - prepare_calls_per_set_calls_.insert( - last_composition_stats_.num_prepare_calls); - layers_per_compositions_.insert(last_composition_stats_.num_layers); - prepare_call_times_.insert(last_prepare_call_time_); - set_call_times_.insert(last_set_call_total_time_); - if (last_composition_stats_.num_hwc_layers != 0) { - set_call_times_per_hwcomposited_layer_ns_.insert( - last_set_call_total_time_.count() / - last_composition_stats_.num_hwc_layers); - } - - // Reset the counter - last_composition_stats_.num_prepare_calls = 0; -} - -void StatsKeeper::SynchronizedDump(char* buffer, int buffer_size) const { - LockGuard<Mutex> lock(mutex_); - int chars_written = 0; -// Make sure there is enough space to write the next line -#define bprintf(...) \ - (chars_written += (chars_written < buffer_size) \ - ? (snprintf(&buffer[chars_written], \ - buffer_size - chars_written, __VA_ARGS__)) \ - : 0) - - bprintf("HWComposer stats from the %" PRId64 - " seconds just before the last call to " - "set() (which happended %" PRId64 " seconds ago):\n", - Seconds(period_length_).count(), - Seconds(MonotonicTimePoint::Now() - last_composition_stats_.set_end) - .count()); - bprintf(" Layer count: %d\n", num_layers_); - - if (num_layers_ == 0 || num_prepare_calls_ == 0 || num_set_calls_ == 0) { - return; - } - - bprintf(" Layers composited by hwcomposer: %d (%d%%)\n", - num_hwcomposited_layers_, - 100 * num_hwcomposited_layers_ / num_layers_); - bprintf(" Number of calls to prepare(): %d\n", num_prepare_calls_); - bprintf(" Number of calls to set(): %d\n", num_set_calls_); - if (num_set_calls_ > 0) { - bprintf( - " Maximum number of calls to prepare() before a single call to set(): " - "%d\n", - MultisetMax(prepare_calls_per_set_calls_)); - } - bprintf(" Time spent on prepare() (in microseconds):\n max: %" PRId64 - "\n " - "average: %" PRId64 "\n min: %" PRId64 "\n total: %" PRId64 - "\n", - Microseconds(MultisetMax(prepare_call_times_)).count(), - Microseconds(prepare_call_total_time_).count() / num_prepare_calls_, - Microseconds(MultisetMin(prepare_call_times_)).count(), - Microseconds(prepare_call_total_time_).count()); - bprintf(" Time spent on set() (in microseconds):\n max: %" PRId64 - "\n average: " - "%" PRId64 "\n min: %" PRId64 "\n total: %" PRId64 "\n", - Microseconds(MultisetMax(set_call_times_)).count(), - Microseconds(set_call_total_time_).count() / num_set_calls_, - Microseconds(MultisetMin(set_call_times_)).count(), - Microseconds(set_call_total_time_).count()); - if (num_hwcomposited_layers_ > 0) { - bprintf( - " Per layer compostition time:\n max: %" PRId64 - "\n average: %" PRId64 - "\n " - "min: %" PRId64 "\n", - Microseconds(MultisetMax(set_call_times_per_hwcomposited_layer_ns_)) - .count(), - Microseconds(set_call_total_time_).count() / num_hwcomposited_layers_, - Microseconds(MultisetMin(set_call_times_per_hwcomposited_layer_ns_)) - .count()); - } - bprintf("Statistics from last 100 compositions:\n"); - bprintf(" Total area: %" PRId64 " square pixels\n", total_layers_area); - if (total_layers_area != 0) { - bprintf( - " Total invisible area: %" PRId64 " square pixels, %" PRId64 "%%\n", - total_invisible_area, 100 * total_invisible_area / total_layers_area); - } -#undef bprintf -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/common/stats_keeper.h b/guest/hals/hwcomposer/common/stats_keeper.h deleted file mode 100644 index 732bf58d..00000000 --- a/guest/hals/hwcomposer/common/stats_keeper.h +++ /dev/null @@ -1,224 +0,0 @@ -#pragma once -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <deque> -#include <set> - -#include <android-base/thread_annotations.h> - -#include "common/libs/threads/cuttlefish_thread.h" -#include "common/libs/time/monotonic_time.h" - -#include "guest/hals/hwcomposer/common/base_composer.h" -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -namespace cvd { - -class CompositionData { - public: - CompositionData(cvd::time::MonotonicTimePoint time_point, int num_prepares, - int num_layers, int num_hwcomposited_layers, - cvd::time::Nanoseconds prepare_time, - cvd::time::Nanoseconds set_calls_time) - : time_point_(time_point), - num_prepare_calls_(num_prepares), - num_layers_(num_layers), - num_hwcomposited_layers_(num_hwcomposited_layers), - prepare_time_(prepare_time), - set_calls_time_(set_calls_time) {} - - cvd::time::MonotonicTimePoint time_point() const { return time_point_; } - - int num_prepare_calls() const { return num_prepare_calls_; } - - int num_layers() const { return num_layers_; } - - int num_hwcomposited_layers() const { return num_hwcomposited_layers_; } - - cvd::time::Nanoseconds prepare_time() const { return prepare_time_; } - - cvd::time::Nanoseconds set_calls_time() const { return set_calls_time_; } - - private: - cvd::time::MonotonicTimePoint time_point_; - int num_prepare_calls_; - int num_layers_; - int num_hwcomposited_layers_; - cvd::time::Nanoseconds prepare_time_; - cvd::time::Nanoseconds set_calls_time_; -}; - -struct HWCCompositionStats { - cvd::time::MonotonicTimePoint prepare_start; - cvd::time::MonotonicTimePoint prepare_end; - cvd::time::MonotonicTimePoint set_start; - cvd::time::MonotonicTimePoint set_end; - cvd::time::MonotonicTimePoint last_vsync; - // There may be more than one call to prepare, the timestamps are with regards - // to the last one (the one that precedes the set call) - int num_prepare_calls; - int num_layers; - // The number of layers composed by the hwcomposer - int num_hwc_layers; -}; - -class StatsKeeper { - public: - // The timespan parameter indicates for how long we keep stats about the past - // compositions. - StatsKeeper(cvd::time::TimeDifference timespan, int64_t vsync_base, - int32_t vsync_period); - StatsKeeper(); - ~StatsKeeper(); - - // Record the time at which a call to prepare was made, takes the number of - // layers received (excluding the framebuffer) as a parameter. - void RecordPrepareStart(int num_layers); - // Record the time at which a call to prepare (was about to) returned, takes - // the number of layers marked for hardware composition as a parameter. - void RecordPrepareEnd(int num_hwcomposited_layers); - void RecordSetStart(); - void RecordSetEnd() EXCLUDES(mutex_); - - void GetLastCompositionStats(CompositionStats* stats_p); - - // Calls to this function are synchronized with calls to 'RecordSetEnd' with a - // mutex. The other Record* functions do not need such synchronization because - // they access last_* variables only, which are not read by 'Dump'. - void SynchronizedDump(char* buffer, int buffer_size) const EXCLUDES(mutex_); - - private: - cvd::time::TimeDifference period_length_; - - // Base and period of the VSYNC signal, allows to accurately calculate the - // time of the last vsync broadcast. - int64_t vsync_base_; - int32_t vsync_period_; - // Data collected about ongoing composition. These variables are not accessed - // from Dump(), so they don't need to be guarded by a mutex. - HWCCompositionStats last_composition_stats_; - - // Aggregated performance data collected from past compositions. These - // variables are modified when a composition is completed and when old - // compositions need to be discarded in RecordSetEnd(), and is accessed from - // Dump(). Non-aggregated data is kept in the raw_composition_data_ deque to - // be able to discard old values from the aggregated data. - int num_layers_ GUARDED_BY(mutex_); - int num_hwcomposited_layers_ GUARDED_BY(mutex_); - int num_prepare_calls_ GUARDED_BY(mutex_); - int num_set_calls_ GUARDED_BY(mutex_); - cvd::time::Nanoseconds prepare_call_total_time_ GUARDED_BY(mutex_); - cvd::time::Nanoseconds set_call_total_time_ GUARDED_BY(mutex_); - // These are kept in multisets to be able to calculate mins and maxs of - // changing sets of (not necessarily different) values. - std::multiset<int> prepare_calls_per_set_calls_ GUARDED_BY(mutex_); - std::multiset<int> layers_per_compositions_ GUARDED_BY(mutex_); - std::multiset<cvd::time::Nanoseconds> prepare_call_times_ GUARDED_BY(mutex_); - std::multiset<cvd::time::Nanoseconds> set_call_times_ GUARDED_BY(mutex_); - std::multiset<int64_t> set_call_times_per_hwcomposited_layer_ns_ - GUARDED_BY(mutex_); - - // Time-ordered list of compositions, used to update the global aggregated - // performance data when old compositions fall out of the period of interest. - std::deque<CompositionData> raw_composition_data_ GUARDED_BY(mutex_); - - // TODO(jemoreira): Add min/max/average composition times per layer area units - - std::deque<std::pair<int64_t, int64_t> > composition_areas GUARDED_BY(mutex_); - int64_t total_layers_area GUARDED_BY(mutex_); - int64_t total_invisible_area GUARDED_BY(mutex_); - - // Controls access to data from past compositions. - mutable cvd::Mutex mutex_; -}; - -class WrappedScreenView : public ScreenView { - public: - WrappedScreenView(std::unique_ptr<ScreenView> screen_view, - std::function<void(CompositionStats*)> stats_getter) - : screen_view_(std::move(screen_view)), stats_getter_(stats_getter) {} - virtual ~WrappedScreenView() = default; - - void Broadcast(int buffer_id, const CompositionStats*) override { - // The composer object in stats_keeper produces null stats, use the ones - // provided by the stats_keeper instead. - CompositionStats stats; - stats_getter_(&stats); - return screen_view_->Broadcast(buffer_id, &stats); - } - - void* GetBuffer(int buffer_id) override { - return screen_view_->GetBuffer(buffer_id); - } - - int32_t x_res() const override { return screen_view_->x_res(); } - - int32_t y_res() const override { return screen_view_->y_res(); } - - int32_t dpi() const override { return screen_view_->dpi(); } - - int32_t refresh_rate() const override { return screen_view_->refresh_rate(); } - - int num_buffers() const override { return screen_view_->num_buffers(); } - - private: - std::unique_ptr<ScreenView> screen_view_; - std::function<void(CompositionStats*)> stats_getter_; -}; - -template <class Composer> -class StatsKeepingComposer : public BaseComposer { - public: - // Keep stats from the last 10 seconds. - StatsKeepingComposer(int64_t vsync_base_timestamp, - std::unique_ptr<ScreenView> screen_view) - : composer_(std::unique_ptr<ScreenView>( - new WrappedScreenView(std::move(screen_view), - [this](CompositionStats* stats) { - FinalizeStatsAndGet(stats); - }))), - stats_keeper_(cvd::time::TimeDifference(cvd::time::Seconds(10), 1), - vsync_base_timestamp, 1e9 / composer_.refresh_rate()) {} - virtual ~StatsKeepingComposer() = default; - - int PrepareLayers(size_t num_layers, hwc_layer_1_t* layers) override { - stats_keeper_.RecordPrepareStart(num_layers); - int num_hwc_layers = composer_.PrepareLayers(num_layers, layers); - stats_keeper_.RecordPrepareEnd(num_hwc_layers); - return num_hwc_layers; - } - - int SetLayers(size_t num_layers, hwc_layer_1_t* layers) override { - stats_keeper_.RecordSetStart(); - return composer_.SetLayers(num_layers, layers); - } - - void Dump(char* buff, int buff_len) override { - stats_keeper_.SynchronizedDump(buff, buff_len); - } - - void FinalizeStatsAndGet(CompositionStats* stats) { - stats_keeper_.RecordSetEnd(); - stats_keeper_.GetLastCompositionStats(&stats); - } - - private: - Composer composer_; - StatsKeeper stats_keeper_; -}; - -} // namespace cvd diff --git a/guest/hals/hwcomposer/cutf_cvm/Android.bp b/guest/hals/hwcomposer/cutf_cvm/Android.bp deleted file mode 100644 index 5041b70f..00000000 --- a/guest/hals/hwcomposer/cutf_cvm/Android.bp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019 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. - - -cc_library_shared { - name: "hwcomposer.cutf_cvm_ashmem", - relative_install_path: "hw", - defaults: ["cuttlefish_guest_only"], - vendor: true, - srcs: [ - "vsocket_screen_view.cpp", - "hwcomposer.cpp", - ], - include_dirs: [ - "device/google/cuttlefish_common", - ], - export_include_dirs: ["."], - static_libs: [ - "libyuv_static", - "hwcomposer_common" - ], - shared_libs: [ - "liblog", - "libhardware", - "libbase", - "libcutils", - "libutils", - "libsync", - "libjpeg", - "libcuttlefish_utils", - "libcuttlefish_fs", - "libcuttlefish_device_config", - ], -} diff --git a/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp b/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp deleted file mode 100644 index 976a68c6..00000000 --- a/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2016 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. - */ - -#define LOG_TAG "hwc.cutf_cvm" - -#include <cutils/properties.h> -#include <hardware/hardware.h> -#include <hardware/hwcomposer.h> -#include <hardware/hwcomposer_defs.h> -#include <log/log.h> - -#include "guest/hals/hwcomposer/common/hwcomposer.h" - -#include "guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h" - -static int hwc_open(const struct hw_module_t* module, const char* name, - struct hw_device_t** device) { - std::unique_ptr<cvd::ScreenView> screen_view(new cvd::VsocketScreenView()); - if (!screen_view) { - ALOGE("Failed to instantiate screen view"); - return -1; - } - - return cvd::cvd_hwc_open(std::move(screen_view), module, name, device); -} - -static struct hw_module_methods_t hwc_module_methods = { - hwc_open, -}; - -hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG, - HWC_MODULE_API_VERSION_0_1, - HARDWARE_HAL_API_VERSION, - HWC_HARDWARE_MODULE_ID, - "VSOCKET hwcomposer module", - "Google", - &hwc_module_methods, - NULL, - {0}}}; diff --git a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp b/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp deleted file mode 100644 index 2e2683f1..00000000 --- a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h" - -#include <cutils/properties.h> -#include <log/log.h> - -#include "common/libs/device_config/device_config.h" - -namespace cvd { - -VsocketScreenView::VsocketScreenView() - : broadcast_thread_([this]() { BroadcastLoop(); }) { - GetScreenParameters(); - // inner_buffer needs to be initialized after the final values of the screen - // parameters are set (either from the config server or default). - inner_buffer_ = std::vector<char>(buffer_size() * 8); -} - -VsocketScreenView::~VsocketScreenView() { - running_ = false; - broadcast_thread_.join(); -} - -void VsocketScreenView::GetScreenParameters() { - auto device_config = cvd::DeviceConfig::Get(); - if (!device_config) { - ALOGI( - "Failed to obtain device configuration from server, running in " - "headless mode"); - // It is impossible to ensure host and guest agree on the screen parameters - // if these could not be read from the host configuration server. It's best - // to not attempt to send frames in this case. - running_ = false; - // Do a phony Broadcast to ensure the broadcaster thread exits. - Broadcast(-1); - return; - } - x_res_ = device_config->screen_x_res(); - y_res_ = device_config->screen_y_res(); - dpi_ = device_config->screen_dpi(); - refresh_rate_ = device_config->screen_refresh_rate(); -} - -bool VsocketScreenView::ConnectToScreenServer() { - auto vsock_frames_port = property_get_int32("ro.boot.vsock_frames_port", -1); - if (vsock_frames_port <= 0) { - ALOGI("No screen server configured, operating on headless mode"); - return false; - } - - screen_server_ = - cvd::SharedFD::VsockClient(2, vsock_frames_port, SOCK_STREAM); - if (!screen_server_->IsOpen()) { - ALOGE("Unable to connect to screen server: %s", screen_server_->StrError()); - return false; - } - - return true; -} - -void VsocketScreenView::BroadcastLoop() { - auto connected = ConnectToScreenServer(); - if (!connected) { - ALOGE( - "Broadcaster thread exiting due to no connection to screen server. " - "Compositions will occur, but frames won't be sent anywhere"); - return; - } - int current_seq = 0; - int current_offset; - ALOGI("Broadcaster thread loop starting"); - while (true) { - { - std::unique_lock<std::mutex> lock(mutex_); - while (running_ && current_seq == current_seq_) { - cond_var_.wait(lock); - } - if (!running_) { - ALOGI("Broadcaster thread exiting"); - return; - } - current_offset = current_offset_; - current_seq = current_seq_; - } - int32_t size = buffer_size(); - screen_server_->Write(&size, sizeof(size)); - auto buff = static_cast<char*>(GetBuffer(current_offset)); - while (size > 0) { - auto written = screen_server_->Write(buff, size); - size -= written; - buff += written; - } - } -} - -void VsocketScreenView::Broadcast(int offset, const CompositionStats*) { - std::lock_guard<std::mutex> lock(mutex_); - current_offset_ = offset; - current_seq_++; - cond_var_.notify_all(); -} - -void* VsocketScreenView::GetBuffer(int buffer_id) { - return &inner_buffer_[buffer_size() * buffer_id]; -} - -int32_t VsocketScreenView::x_res() const { return x_res_; } -int32_t VsocketScreenView::y_res() const { return y_res_; } -int32_t VsocketScreenView::dpi() const { return dpi_; } -int32_t VsocketScreenView::refresh_rate() const { return refresh_rate_; } - -int VsocketScreenView::num_buffers() const { - return inner_buffer_.size() / buffer_size(); -} - -} // namespace cvd diff --git a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h b/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h deleted file mode 100644 index 0d6d90af..00000000 --- a/guest/hals/hwcomposer/cutf_cvm/vsocket_screen_view.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <condition_variable> -#include <functional> -#include <mutex> -#include <thread> -#include <vector> - -#include "common/libs/fs/shared_fd.h" -#include "guest/hals/hwcomposer/common/screen_view.h" - -namespace cvd { - -class VsocketScreenView : public ScreenView { - public: - VsocketScreenView(); - virtual ~VsocketScreenView(); - - void Broadcast(int buffer_id, - const CompositionStats* stats = nullptr) override; - void* GetBuffer(int fb_index) override; - - int32_t x_res() const override; - int32_t y_res() const override; - int32_t dpi() const override; - int32_t refresh_rate() const override; - - int num_buffers() const override; - - private: - bool ConnectToScreenServer(); - void GetScreenParameters(); - void BroadcastLoop(); - - std::vector<char> inner_buffer_; - cvd::SharedFD screen_server_; - std::thread broadcast_thread_; - int current_offset_ = 0; - int current_seq_ = 0; - std::mutex mutex_; - std::condition_variable cond_var_; - bool running_ = true; - int32_t x_res_{720}; - int32_t y_res_{1280}; - int32_t dpi_{160}; - int32_t refresh_rate_{60}; -}; - -} // namespace cvd diff --git a/guest/hals/lights/Android.mk b/guest/hals/lights/Android.mk deleted file mode 100644 index 8c292dcc..00000000 --- a/guest/hals/lights/Android.mk +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (C) 2017 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. - -LOCAL_PATH := $(call my-dir) - -# HAL module implemenation, not prelinked and stored in -# hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so -include $(CLEAR_VARS) -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?)) -LOCAL_MODULE_RELATIVE_PATH := hw -else -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -endif -LOCAL_MULTILIB := first -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES := device/google/cuttlefish_common -LOCAL_HEADER_LIBRARIES := libhardware_headers -LOCAL_SHARED_LIBRARIES := liblog libcutils -LOCAL_SRC_FILES := lights_vsoc.c -LOCAL_MODULE := lights.cutf -LOCAL_CFLAGS += -DLIGHT_BACKLIGHT -DLOG_TAG=\"VSoC-lights\" $(VSOC_VERSION_CFLAGS) -LOCAL_VENDOR_MODULE := true -include $(BUILD_SHARED_LIBRARY) - diff --git a/guest/hals/lights/lights_vsoc.c b/guest/hals/lights/lights_vsoc.c deleted file mode 100644 index 3cdb6c2d..00000000 --- a/guest/hals/lights/lights_vsoc.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <log/log.h> -#include <errno.h> -#include <fcntl.h> -#include <hardware/lights.h> -#include <pthread.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <unistd.h> - -static int set_light(struct light_device_t* dev, - struct light_state_t const* state) { - ALOGI("%s: dev %p state %p", __FUNCTION__, dev, state); - if (state) { - ALOGI("%s: state value %d\n", __FUNCTION__, state->color); - } - return 0; -} - -static int close_lights(struct light_device_t* dev) { - free(dev); - return 0; -} - -static int open_lights(const struct hw_module_t* module, - char const* name __unused, struct hw_device_t** device) { - struct light_device_t* dev = malloc(sizeof(struct light_device_t)); - if (dev == NULL) { - return -EINVAL; - } - memset(dev, 0, sizeof(*dev)); - - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t*)module; - dev->common.close = (int (*)(struct hw_device_t*))close_lights; - dev->set_light = set_light; - *device = (struct hw_device_t*)dev; - return 0; -} - -static struct hw_module_methods_t lights_module_methods = { - .open = open_lights, -}; - -struct hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = LIGHTS_HARDWARE_MODULE_ID, - .name = "Android GCE lights Module", - .author = "Google", - .methods = & lights_module_methods, -}; diff --git a/guest/hals/power/Android.bp b/guest/hals/power/Android.bp deleted file mode 100644 index ae62b686..00000000 --- a/guest/hals/power/Android.bp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2017 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. - -// HAL module implementation stored in -// hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so -cc_library_shared { - name: "power.cutf", - srcs: ["power.c"], - relative_install_path: "hw", - header_libs: [ - "libhardware_headers", - "libutils_headers", - ], - shared_libs: [ - "liblog", - "libcutils", - ], - defaults: ["cuttlefish_guest_only"], -} diff --git a/guest/hals/power/power.c b/guest/hals/power/power.c deleted file mode 100644 index 35d5a115..00000000 --- a/guest/hals/power/power.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2017 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. - * - * Based on the HiKeyPowerHAL - */ - -#include <pthread.h> -#include <semaphore.h> -#include <cutils/properties.h> - -#define LOG_TAG "VSoCPowerHAL" -#include <utils/Log.h> - -#include <hardware/hardware.h> -#include <hardware/power.h> - -struct vsoc_power_module { - struct power_module base; - pthread_mutex_t lock; -}; - -static void vsoc_power_set_feature(struct power_module __unused *module, - feature_t __unused hint, - int __unused state) { - return; -} - -static void vsoc_power_hint(struct power_module __unused *module, - power_hint_t __unused hint, - void __unused *data) { - return; -} - -static void vsoc_power_set_interactive(struct power_module __unused *module, - int __unused on) { - return; -} - -static void vsoc_power_init(struct power_module __unused *module) { - return; -} - - -/* - * The power module wasn't opened at all in versions prior to 'O'. The module - * pointer was reinterpretd as a device pointer. 'O' retains this behavior when - * open is set to NULL. This code is using that mode. - * For reference, - * 'O': hardware/interfaces/power/1.0/default/Power.cpp - * prior: frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp - */ -static struct hw_module_methods_t power_module_methods = { - .open = NULL -}; - - -struct vsoc_power_module HAL_MODULE_INFO_SYM = { - .base = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = POWER_MODULE_API_VERSION_0_2, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = POWER_HARDWARE_MODULE_ID, - .name = "VSoC Power HAL", - .author = "The Android Open Source Project", - .methods = &power_module_methods, - }, - .init = vsoc_power_init, - .setInteractive = vsoc_power_set_interactive, - .powerHint = vsoc_power_hint, - // Before L_MR1 we don't have setFeature - .setFeature = vsoc_power_set_feature, - }, - - .lock = PTHREAD_MUTEX_INITIALIZER, -}; - diff --git a/guest/hals/ril/Android.mk b/guest/hals/ril/Android.mk deleted file mode 100644 index b37e257b..00000000 --- a/guest/hals/ril/Android.mk +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - cuttlefish_ril.cpp - -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - ${CUTTLEFISH_LIBRIL_NAME} \ - libcuttlefish_fs \ - cuttlefish_net \ - libbase \ - libcuttlefish_device_config \ - -LOCAL_C_INCLUDES := \ - device/google/cuttlefish_common \ - device/google/cuttlefish_kernel - -LOCAL_CFLAGS += \ - -Wall \ - -Werror \ - $(VSOC_VERSION_CFLAGS) - -LOCAL_MODULE:= libcuttlefish-ril -LOCAL_MODULE_TAGS := optional -LOCAL_VENDOR_MODULE := true - -# See b/67109557 -ifeq (true, $(TARGET_TRANSLATE_2ND_ARCH)) -LOCAL_MULTILIB := first -endif - -include $(BUILD_SHARED_LIBRARY) - -include $(call first-makefiles-under,$(LOCAL_PATH)) diff --git a/guest/hals/ril/cuttlefish_ril.cpp b/guest/hals/ril/cuttlefish_ril.cpp deleted file mode 100644 index 47cb5c55..00000000 --- a/guest/hals/ril/cuttlefish_ril.cpp +++ /dev/null @@ -1,2638 +0,0 @@ -/* -** Copyright 2017, 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 ioogle/s distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include "guest/hals/ril/cuttlefish_ril.h" - -#include <cutils/properties.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <time.h> - -#include <map> -#include <set> -#include <string> -#include <vector> - -#include "common/libs/device_config/device_config.h" -#include "common/libs/net/netlink_client.h" -#include "common/libs/net/network_interface.h" -#include "common/libs/net/network_interface_manager.h" - -#define CUTTLEFISH_RIL_VERSION_STRING "Android Cuttlefish RIL 1.4" - -/* Modem Technology bits */ -#define MDM_GSM 0x01 -#define MDM_WCDMA 0x02 -#define MDM_CDMA 0x04 -#define MDM_EVDO 0x08 -#define MDM_LTE 0x10 - -typedef enum { - SIM_ABSENT = 0, - SIM_NOT_READY = 1, - SIM_READY = 2, // SIM_READY means the radio state is RADIO_STATE_SIM_READY - SIM_PIN = 3, - SIM_PUK = 4, - SIM_NETWORK_PERSONALIZATION = 5, - RUIM_ABSENT = 6, - RUIM_NOT_READY = 7, - RUIM_READY = 8, - RUIM_PIN = 9, - RUIM_PUK = 10, - RUIM_NETWORK_PERSONALIZATION = 11 -} SIM_Status; - -static std::unique_ptr<cvd::DeviceConfig> global_ril_config = nullptr; - -static const struct RIL_Env* gce_ril_env; - -static const struct timeval TIMEVAL_SIMPOLL = {3, 0}; - -static time_t gce_ril_start_time; - -static void pollSIMState(void* param); - -RIL_RadioState gRadioPowerState = RADIO_STATE_OFF; -RIL_RadioAccessFamily default_access = RAF_LTE; - -struct DataCall { - enum AllowedAuthenticationType { kNone = 0, kPap = 1, kChap = 2, kBoth = 3 }; - - enum ConnectionType { - kConnTypeIPv4, - kConnTypeIPv6, - kConnTypeIPv4v6, - kConnTypePPP - }; - - enum LinkState { - kLinkStateInactive = 0, - kLinkStateDown = 1, - kLinkStateUp = 2, - }; - - RIL_RadioTechnology technology_; - RIL_DataProfile profile_; - std::string access_point_; - std::string username_; - std::string password_; - AllowedAuthenticationType auth_type_; - ConnectionType connection_type_; - LinkState link_state_; - RIL_DataCallFailCause fail_cause_; - std::string other_properties_; -}; - -static std::string gSimPIN = "0000"; -static const std::string gSimPUK = "11223344"; -static int gSimPINAttempts = 0; -static const int gSimPINAttemptsMax = 3; -static SIM_Status gSimStatus = SIM_NOT_READY; -static bool areUiccApplicationsEnabled = true; - -// SetUpNetworkInterface configures IP and Broadcast addresses on a RIL -// controlled network interface. -// This call returns true, if operation was successful. -bool SetUpNetworkInterface(const char* ipaddr, int prefixlen, - const char* bcaddr) { - auto factory = cvd::NetlinkClientFactory::Default(); - std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE)); - std::unique_ptr<cvd::NetworkInterfaceManager> nm( - cvd::NetworkInterfaceManager::New(factory)); - std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0", "eth1")); - - if (ni) { - ni->SetName("rmnet0"); - ni->SetAddress(ipaddr); - ni->SetBroadcastAddress(bcaddr); - ni->SetPrefixLength(prefixlen); - ni->SetOperational(true); - bool res = nm->ApplyChanges(*ni); - if (!res) ALOGE("Could not configure rmnet0"); - return res; - } - return false; -} - -// TearDownNetworkInterface disables network interface. -// This call returns true, if operation was successful. -bool TearDownNetworkInterface() { - auto nm(cvd::NetworkInterfaceManager::New(nullptr)); - auto ni(nm->Open("rmnet0", "eth1")); - - if (ni) { - ni->SetOperational(false); - bool res = nm->ApplyChanges(*ni); - if (!res) ALOGE("Could not disable rmnet0"); - return res; - } - return false; -} - -static int gNextDataCallId = 8; -static std::map<int, DataCall> gDataCalls; -static bool gRilConnected = false; - -static int request_or_send_data_calllist(RIL_Token* t) { - RIL_Data_Call_Response_v11* responses = - new RIL_Data_Call_Response_v11[gDataCalls.size()]; - - int index = 0; - - ALOGV("Query data call list: %zu data calls tracked.", gDataCalls.size()); - - for (std::map<int, DataCall>::iterator iter = gDataCalls.begin(); - iter != gDataCalls.end(); ++iter, ++index) { - responses[index].status = iter->second.fail_cause_; - responses[index].suggestedRetryTime = -1; - responses[index].cid = iter->first; - responses[index].active = iter->second.link_state_; - - switch (iter->second.connection_type_) { - case DataCall::kConnTypeIPv4: - responses[index].type = (char*)"IP"; - break; - case DataCall::kConnTypeIPv6: - responses[index].type = (char*)"IPV6"; - break; - case DataCall::kConnTypeIPv4v6: - responses[index].type = (char*)"IPV4V6"; - break; - case DataCall::kConnTypePPP: - responses[index].type = (char*)"PPP"; - break; - default: - responses[index].type = (char*)"IP"; - break; - } - - responses[index].ifname = (char*)"rmnet0"; - responses[index].addresses = - const_cast<char*>(global_ril_config->ril_address_and_prefix()); - responses[index].dnses = const_cast<char*>(global_ril_config->ril_dns()); - responses[index].gateways = const_cast<char*>(global_ril_config->ril_gateway()); - responses[index].pcscf = (char*)""; - responses[index].mtu = 1440; - } - - bool new_conn_state = (gDataCalls.size() > 0); - - if (gRilConnected != new_conn_state) { - time_t curr_time; - time(&curr_time); - double diff_in_secs = difftime(curr_time, gce_ril_start_time); - - gRilConnected = new_conn_state; - - if (new_conn_state) { - ALOGV("MOBILE_DATA_CONNECTED %.2lf seconds", diff_in_secs); - } else { - ALOGV("MOBILE_DATA_DISCONNECTED %.2lf seconds", diff_in_secs); - } - - if (property_set("ril.net_connected", new_conn_state ? "1" : "0")) { - ALOGE("Couldn't set a system property ril.net_connected."); - } - } - - if (t != NULL) { - gce_ril_env->OnRequestComplete(*t, RIL_E_SUCCESS, responses, - gDataCalls.size() * sizeof(*responses)); - } else { - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, - responses, - gDataCalls.size() * sizeof(*responses)); - } - delete[] responses; - return 0; -} - -static void request_datacall_fail_cause(RIL_Token t) { - RIL_DataCallFailCause fail = PDP_FAIL_DATA_REGISTRATION_FAIL; - - if (gDataCalls.size() > 0) { - fail = gDataCalls.rbegin()->second.fail_cause_; - } - - ALOGV("Requesting last data call setup fail cause (%d)", fail); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &fail, sizeof(fail)); -}; - -static void request_data_calllist(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - request_or_send_data_calllist(&t); -} - -static void request_setup_data_call(void* data, size_t datalen, RIL_Token t) { - char** details = static_cast<char**>(data); - const size_t fields = datalen / sizeof(details[0]); - - // There are two different versions of this interface, one providing 7 strings - // and the other providing 8. The code below will assume the presence of 7 - // strings in all cases, so bail out here if things appear to be wrong. We - // protect the 8 string case below. - if (fields < 7) { - ALOGE("%s returning: called with small datalen %zu", __FUNCTION__, datalen); - return; - } - - DataCall call; - int tech = atoi(details[0]); - switch (tech) { - case 0: - case 2 + RADIO_TECH_1xRTT: - call.technology_ = RADIO_TECH_1xRTT; - break; - - case 1: - case 2 + RADIO_TECH_EDGE: - call.technology_ = RADIO_TECH_EDGE; - break; - - default: - call.technology_ = RIL_RadioTechnology(tech - 2); - break; - } - - int profile = atoi(details[1]); - call.profile_ = RIL_DataProfile(profile); - - if (details[2]) call.access_point_ = details[2]; - if (details[3]) call.username_ = details[3]; - if (details[4]) call.password_ = details[4]; - - int auth_type = atoi(details[5]); - call.auth_type_ = DataCall::AllowedAuthenticationType(auth_type); - - if (!strcmp("IP", details[6])) { - call.connection_type_ = DataCall::kConnTypeIPv4; - } else if (!strcmp("IPV6", details[6])) { - call.connection_type_ = DataCall::kConnTypeIPv6; - } else if (!strcmp("IPV4V6", details[6])) { - call.connection_type_ = DataCall::kConnTypeIPv4v6; - } else if (!strcmp("PPP", details[6])) { - call.connection_type_ = DataCall::kConnTypePPP; - } else { - ALOGW("Unknown / unsupported connection type %s. Falling back to IPv4", - details[6]); - call.connection_type_ = DataCall::kConnTypeIPv4; - } - - if (call.connection_type_ != DataCall::kConnTypeIPv4) { - ALOGE("Non-IPv4 connections are not supported by Cuttlefish RIL."); - gce_ril_env->OnRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0); - return; - } - - call.link_state_ = DataCall::kLinkStateUp; - call.fail_cause_ = PDP_FAIL_NONE; - if (fields > 7) { - if (details[7]) call.other_properties_ = details[7]; - } - - if (gDataCalls.empty()) { - SetUpNetworkInterface(global_ril_config->ril_ipaddr(), - global_ril_config->ril_prefixlen(), - global_ril_config->ril_broadcast()); - } - - gDataCalls[gNextDataCallId] = call; - gNextDataCallId++; - - ALOGV("Requesting data call setup to APN %s, technology %s, prof %s", - details[2], details[0], details[1]); - - request_or_send_data_calllist(&t); - - gRilConnected = (gDataCalls.size() > 0); -} - -static void request_teardown_data_call(void* data, size_t /*datalen*/, - RIL_Token t) { - char** data_strs = (char**)data; - int call_id = atoi(data_strs[0]); - int reason = atoi(data_strs[1]); - - ALOGV("Tearing down data call %d, reason: %d", call_id, reason); - - gDataCalls.erase(call_id); - gRilConnected = (gDataCalls.size() > 0); - - if (!gRilConnected) { - TearDownNetworkInterface(); - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void set_radio_state(RIL_RadioState new_state, RIL_Token t) { - // From header: - // Toggle radio on and off (for "airplane" mode) - // If the radio is is turned off/on the radio modem subsystem - // is expected return to an initialized state. For instance, - // any voice and data calls will be terminated and all associated - // lists emptied. - gDataCalls.clear(); - - gSimStatus = SIM_NOT_READY; - ALOGV("RIL_RadioState change %d to %d", gRadioPowerState, new_state); - gRadioPowerState = new_state; - - if (new_state == RADIO_STATE_OFF) { - TearDownNetworkInterface(); - } - - if (t != NULL) { - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - } - - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, - NULL, 0); - - pollSIMState(NULL); -} - -// returns 1 if on, 0 if off, and -1 on error -static void request_radio_power(void* data, size_t /*datalen*/, RIL_Token t) { - int on = ((int*)data)[0]; - set_radio_state(on ? RADIO_STATE_ON : RADIO_STATE_OFF, t); -} - -// TODO(ender): this should be a class member. Move where it belongs. -struct CallState { - RIL_CallState state; // e.g. RIL_CALL_HOLDING; - bool isInternational; - bool isMobileTerminated; - bool isVoice; - bool isMultiParty; - - std::string number; - std::string name; - std::string dtmf; - - bool canPresentNumber; - bool canPresentName; - - CallState() - : state(RIL_CallState(0)), - isInternational(false), - isMobileTerminated(true), - isVoice(true), - isMultiParty(false), - canPresentNumber(true), - canPresentName(true) {} - - CallState(const std::string& number) - : state(RIL_CALL_INCOMING), - isInternational(false), - isMobileTerminated(true), - isVoice(true), - isMultiParty(false), - number(number), - name(number), - canPresentNumber(true), - canPresentName(true) {} - - bool isBackground() { return state == RIL_CALL_HOLDING; } - - bool isActive() { return state == RIL_CALL_ACTIVE; } - - bool isDialing() { return state == RIL_CALL_DIALING; } - - bool isIncoming() { return state == RIL_CALL_INCOMING; } - - bool isWaiting() { return state == RIL_CALL_WAITING; } - - void addDtmfDigit(char c) { - dtmf.push_back(c); - ALOGV("Call to %s: DTMF %s", number.c_str(), dtmf.c_str()); - } - - bool makeBackground() { - if (state == RIL_CALL_ACTIVE) { - state = RIL_CALL_HOLDING; - return true; - } - - return false; - } - - bool makeActive() { - if (state == RIL_CALL_INCOMING || state == RIL_CALL_WAITING || - state == RIL_CALL_DIALING || state == RIL_CALL_HOLDING) { - state = RIL_CALL_ACTIVE; - return true; - } - - return false; - } -}; - -static int gLastActiveCallIndex = 1; -static int gMicrophoneMute = 0; -static std::map<int, CallState> gActiveCalls; - -static void request_get_current_calls(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - const int countCalls = gActiveCalls.size(); - - RIL_Call** pp_calls = (RIL_Call**)alloca(countCalls * sizeof(RIL_Call*)); - RIL_Call* p_calls = (RIL_Call*)alloca(countCalls * sizeof(RIL_Call)); - - memset(p_calls, 0, countCalls * sizeof(RIL_Call)); - - /* init the pointer array */ - for (int i = 0; i < countCalls; i++) { - pp_calls[i] = &(p_calls[i]); - } - - // TODO(ender): This should be built from calls requested via RequestDial. - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end(); ++iter, ++p_calls) { - p_calls->state = iter->second.state; - p_calls->index = iter->first; - p_calls->toa = iter->second.isInternational ? 145 : 129; - p_calls->isMpty = iter->second.isMultiParty; - p_calls->isMT = iter->second.isMobileTerminated; - p_calls->als = iter->first; - p_calls->isVoice = iter->second.isVoice; - p_calls->isVoicePrivacy = 0; - p_calls->number = strdup(iter->second.number.c_str()); - p_calls->numberPresentation = iter->second.canPresentNumber ? 0 : 1; - p_calls->name = strdup(iter->second.name.c_str()); - p_calls->namePresentation = iter->second.canPresentName ? 0 : 1; - p_calls->uusInfo = NULL; - - ALOGV("Call to %s (%s): voice=%d mt=%d type=%d state=%d index=%d", - p_calls->name, p_calls->number, p_calls->isVoice, p_calls->isMT, - p_calls->toa, p_calls->state, p_calls->index); - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, pp_calls, - countCalls * sizeof(RIL_Call*)); - - ALOGV("Get Current calls: %d calls found.\n", countCalls); -} - -static void simulate_pending_calls_answered(void* /*ignore*/) { - ALOGV("Simulating outgoing call answered."); - // This also resumes held calls. - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end(); ++iter) { - if (iter->second.isDialing()) { - iter->second.makeActive(); - } - } - - // Only unsolicited here. - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, - NULL, 0); -} - -static void request_dial(void* data, size_t /*datalen*/, RIL_Token t) { - RIL_Dial* p_dial = (RIL_Dial*)data; - - ALOGV("Dialing %s, number presentation is %s.", p_dial->address, - (p_dial->clir == 0) ? "defined by operator" - : (p_dial->clir == 1) ? "allowed" : "restricted"); - - CallState state(p_dial->address); - state.isMobileTerminated = false; - state.state = RIL_CALL_DIALING; - - switch (p_dial->clir) { - case 0: // default - case 1: // allow - state.canPresentNumber = true; - break; - - case 2: // restrict - state.canPresentNumber = false; - break; - } - - int call_index = gLastActiveCallIndex++; - gActiveCalls[call_index] = state; - - static const struct timeval kAnswerTime = {5, 0}; - gce_ril_env->RequestTimedCallback(simulate_pending_calls_answered, NULL, - &kAnswerTime); - - // success or failure is ignored by the upper layer here. - // it will call GET_CURRENT_CALLS and determine success that way - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -void request_set_mute(void* data, size_t /*datalen*/, RIL_Token t) { - gMicrophoneMute = ((int*)data)[0] != 0; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -void request_get_mute(RIL_Token t) { - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gMicrophoneMute, - sizeof(gMicrophoneMute)); -} - -// TODO(ender): this should be a class member. Move where it belongs. -struct SmsMessage { - enum SmsStatus { kUnread = 0, kRead = 1, kUnsent = 2, kSent = 3 }; - - std::string message; - SmsStatus status; -}; - -static int gNextMessageId = 1; -static std::map<int, SmsMessage> gMessagesOnSimCard; - -static void request_write_sms_to_sim(void* data, size_t /*datalen*/, - RIL_Token t) { - RIL_SMS_WriteArgs* p_args = (RIL_SMS_WriteArgs*)data; - - SmsMessage message; - message.status = SmsMessage::SmsStatus(p_args->status); - message.message = p_args->pdu; - - ALOGV("Storing SMS message: '%s' with state: %s.", message.message.c_str(), - (message.status < SmsMessage::kUnsent) - ? ((message.status == SmsMessage::kRead) ? "READ" : "UNREAD") - : ((message.status == SmsMessage::kSent) ? "SENT" : "UNSENT")); - - // TODO(ender): simulate SIM FULL? - int index = gNextMessageId++; - gMessagesOnSimCard[index] = message; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &index, sizeof(index)); -} - -static void request_delete_sms_on_sim(void* data, size_t /*datalen*/, - RIL_Token t) { - int index = *(int*)data; - - ALOGV("Delete SMS message %d", index); - - if (gMessagesOnSimCard.erase(index) == 0) { - // No such message - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_hangup(void* data, size_t /*datalen*/, RIL_Token t) { - int* p_line = (int*)data; - - ALOGV("Hanging up call %d.", *p_line); - std::map<int, CallState>::iterator iter = gActiveCalls.find(*p_line); - - if (iter == gActiveCalls.end()) { - ALOGV("No such call: %d.", *p_line); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - } else { - gActiveCalls.erase(iter); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - } -} - -static void request_hangup_waiting(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGV("Hanging up background/held calls."); - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end();) { - if (iter->second.isBackground()) { - // C++98 -- std::map::erase doesn't return iterator. - std::map<int, CallState>::iterator temp = iter++; - gActiveCalls.erase(temp); - } else { - ++iter; - } - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_hangup_current(RIL_Token t) { - ALOGV("Hanging up foreground/active calls."); - // This also resumes held calls. - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end();) { - if (iter->second.isBackground()) { - iter->second.makeActive(); - ++iter; - } else { - // C++98 -- std::map::erase doesn't return iterator. - std::map<int, CallState>::iterator temp = iter++; - gActiveCalls.erase(temp); - } - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_switch_current_and_waiting(RIL_Token t) { - ALOGV("Toggle foreground and background calls."); - // TODO(ender): fix all states. Max 2 calls. - // BEFORE AFTER - // Call 1 Call 2 Call 1 Call 2 - // ACTIVE HOLDING HOLDING ACTIVE - // ACTIVE WAITING HOLDING ACTIVE - // HOLDING WAITING HOLDING ACTIVE - // ACTIVE IDLE HOLDING IDLE - // IDLE IDLE IDLE IDLE - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end(); ++iter) { - // TODO(ender): call could also be waiting or dialing or... - if (iter->second.isBackground()) { - iter->second.makeActive(); - } else { - iter->second.makeBackground(); - } - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_answer_incoming(RIL_Token t) { - ALOGV("Answering incoming call."); - - // There's two types of incoming calls: - // - incoming: we are receiving this call while nothing happens, - // - waiting: we are receiving this call while we're already talking. - // We only accept the incoming ones. - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end(); ++iter) { - if (iter->second.isIncoming()) { - iter->second.makeActive(); - } - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_combine_multiparty_call(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGW("Conference calls are not supported."); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); -} - -static void request_split_multiparty_call(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGW("Conference calls are not supported."); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); -} - -static void request_udub_on_incoming_calls(RIL_Token t) { - // UDUB = user determined user busy. - // We don't exactly do that. We simply drop these calls. - ALOGV("Reporting busy signal to incoming calls."); - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end();) { - // If we have an incoming call, there should be no waiting call. - // If we have a waiting call, then previous incoming call has been answered. - if (iter->second.isIncoming() || iter->second.isWaiting()) { - // C++98 -- std::map::erase doesn't return iterator. - std::map<int, CallState>::iterator temp = iter++; - gActiveCalls.erase(temp); - } else { - ++iter; - } - } - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_send_dtmf(void* data, size_t /*datalen*/, RIL_Token t) { - char c = ((char*)data)[0]; - ALOGV("Sending DTMF digit '%c'", c); - - for (std::map<int, CallState>::iterator iter = gActiveCalls.begin(); - iter != gActiveCalls.end(); ++iter) { - if (iter->second.isActive()) { - iter->second.addDtmfDigit(c); - break; - } - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_send_dtmf_stop(RIL_Token t) { - ALOGV("DTMF tone end."); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -// Check SignalStrength.java file for more details on how these map to signal -// strength bars. -const int kGatewaySignalStrengthMin = 4; -const int kGatewaySignalStrengthMax = 30; -const int kCDMASignalStrengthMin = -110; -const int kCDMASignalStrengthMax = -60; -const int kEVDOSignalStrengthMin = -160; -const int kEVDOSignalStrengthMax = -70; -const int kLTESignalStrengthMin = 4; -const int kLTESignalStrengthMax = 30; - -static int gGatewaySignalStrength = kGatewaySignalStrengthMax; -static int gCDMASignalStrength = kCDMASignalStrengthMax; -static int gEVDOSignalStrength = kEVDOSignalStrengthMax; -static int gLTESignalStrength = kLTESignalStrengthMax; - -static void request_signal_strength(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - // TODO(ender): possible to support newer APIs here. - RIL_SignalStrength_v10 strength; - - gGatewaySignalStrength += (rand() % 3 - 1); - gCDMASignalStrength += (rand() % 3 - 1); - gEVDOSignalStrength += (rand() % 3 - 1); - gLTESignalStrength += (rand() % 3 - 1); - - if (gGatewaySignalStrength < kGatewaySignalStrengthMin) - gGatewaySignalStrength = kGatewaySignalStrengthMin; - if (gGatewaySignalStrength > kGatewaySignalStrengthMax) - gGatewaySignalStrength = kGatewaySignalStrengthMax; - if (gCDMASignalStrength < kCDMASignalStrengthMin) - gCDMASignalStrength = kCDMASignalStrengthMin; - if (gCDMASignalStrength > kCDMASignalStrengthMax) - gCDMASignalStrength = kCDMASignalStrengthMax; - if (gEVDOSignalStrength < kEVDOSignalStrengthMin) - gEVDOSignalStrength = kEVDOSignalStrengthMin; - if (gEVDOSignalStrength > kEVDOSignalStrengthMax) - gEVDOSignalStrength = kEVDOSignalStrengthMax; - if (gLTESignalStrength < kLTESignalStrengthMin) - gLTESignalStrength = kLTESignalStrengthMin; - if (gLTESignalStrength > kLTESignalStrengthMax) - gLTESignalStrength = kLTESignalStrengthMax; - - strength.GW_SignalStrength.signalStrength = gGatewaySignalStrength; - strength.GW_SignalStrength.bitErrorRate = 0; // 0..7% - - strength.CDMA_SignalStrength.dbm = gCDMASignalStrength; - strength.CDMA_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm. - - strength.EVDO_SignalStrength.dbm = gEVDOSignalStrength; - strength.EVDO_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm. - - strength.LTE_SignalStrength.signalStrength = gLTESignalStrength; - strength.LTE_SignalStrength.rsrp = INT_MAX; // Invalid = Use signalStrength. - strength.LTE_SignalStrength.rsrq = INT_MAX; // Invalid = Use signalStrength. - strength.LTE_SignalStrength.rssnr = INT_MAX; // Invalid = Use signalStrength. - strength.LTE_SignalStrength.cqi = INT_MAX; // Invalid = Use signalStrength. - - ALOGV("Reporting signal strength: GW=%d CDMA=%d EVDO=%d LTE=%d", - gGatewaySignalStrength, gCDMASignalStrength, gEVDOSignalStrength, - gLTESignalStrength); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &strength, sizeof(strength)); -} - -static std::map<RIL_PreferredNetworkType, int> gModemSupportedNetworkTypes; - -static void init_modem_supported_network_types() { - gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA] = MDM_GSM | MDM_WCDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_ONLY] = MDM_GSM; - gModemSupportedNetworkTypes[PREF_NET_TYPE_WCDMA] = MDM_WCDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_AUTO] = - MDM_GSM | MDM_WCDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_EVDO_AUTO] = - MDM_CDMA | MDM_EVDO; - gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_ONLY] = MDM_CDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_EVDO_ONLY] = MDM_EVDO; - gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] = - MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO; - gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CDMA_EVDO] = - MDM_LTE | MDM_CDMA | MDM_EVDO; - gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_GSM_WCDMA] = - MDM_LTE | MDM_GSM | MDM_WCDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] = - MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA; - gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_ONLY] = MDM_LTE; -} - -static std::map<RIL_PreferredNetworkType, int> gModemTechnologies; - -RIL_RadioTechnology gDataTechnologiesPreferenceOrder[] = { - RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_HSPAP, RADIO_TECH_HSPA, - RADIO_TECH_HSDPA, RADIO_TECH_HSUPA, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A, - RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_UMTS, RADIO_TECH_EDGE, - RADIO_TECH_GPRS}; - -RIL_RadioTechnology gVoiceTechnologiesPreferenceOrder[] = { - RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A, - RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_IS95B, RADIO_TECH_IS95A, - RADIO_TECH_UMTS, RADIO_TECH_GSM}; - -static void init_modem_technologies() { - gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA] = - (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) | - (1 << RADIO_TECH_UMTS); - gModemTechnologies[PREF_NET_TYPE_GSM_ONLY] = - (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE); - gModemTechnologies[PREF_NET_TYPE_WCDMA] = - (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS); - gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_AUTO] = - (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) | - (1 << RADIO_TECH_UMTS); - gModemTechnologies[PREF_NET_TYPE_CDMA_EVDO_AUTO] = - (1 << RADIO_TECH_IS95A) | (1 << RADIO_TECH_IS95B) | - (1 << RADIO_TECH_1xRTT) | (1 << RADIO_TECH_EVDO_0) | - (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) | - (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) | - (1 << RADIO_TECH_EVDO_B); - gModemTechnologies[PREF_NET_TYPE_CDMA_ONLY] = (1 << RADIO_TECH_IS95A) | - (1 << RADIO_TECH_IS95B) | - (1 << RADIO_TECH_1xRTT); - gModemTechnologies[PREF_NET_TYPE_EVDO_ONLY] = - (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) | - (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) | - (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) | - (1 << RADIO_TECH_EVDO_B); - gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] = - (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) | - (1 << RADIO_TECH_UMTS) | (1 << RADIO_TECH_IS95A) | - (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) | - (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) | - (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) | - (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B); - gModemTechnologies[PREF_NET_TYPE_LTE_CDMA_EVDO] = - (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | - (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) | - (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) | - (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) | - (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) | - (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B); - gModemTechnologies[PREF_NET_TYPE_LTE_GSM_WCDMA] = - (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | - (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | - (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS); - - gModemTechnologies[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] = - (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | - (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) | - (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) | - (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) | - (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) | - (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B) | - (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) | - (1 << RADIO_TECH_UMTS); - gModemTechnologies[PREF_NET_TYPE_LTE_ONLY] = - (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | (1 << RADIO_TECH_EHRPD); -} - -static const RIL_PreferredNetworkType gModemDefaultType = - PREF_NET_TYPE_LTE_GSM_WCDMA; -static RIL_PreferredNetworkType gModemCurrentType = gModemDefaultType; -static RIL_RadioTechnology gModemVoiceTechnology = RADIO_TECH_LTE; - -// Report technology change. -// Select best technology from the list of supported techs. -// Demotes RADIO_TECH_GSM as it's voice-only. -static RIL_RadioTechnology getBestDataTechnology( - RIL_PreferredNetworkType network_type) { - RIL_RadioTechnology technology = RADIO_TECH_GPRS; - - std::map<RIL_PreferredNetworkType, int>::iterator iter = - gModemTechnologies.find(network_type); - - ALOGV("Searching for best data technology for network type %d...", - network_type); - - // Find which technology bits are lit. Pick the top most. - for (size_t tech_index = 0; - tech_index < sizeof(gDataTechnologiesPreferenceOrder) / - sizeof(gDataTechnologiesPreferenceOrder[0]); - ++tech_index) { - if (iter->second & (1 << gDataTechnologiesPreferenceOrder[tech_index])) { - technology = gDataTechnologiesPreferenceOrder[tech_index]; - break; - } - } - - ALOGV("Best data technology: %d.", technology); - return technology; -} - -static RIL_RadioTechnology getBestVoiceTechnology( - RIL_PreferredNetworkType network_type) { - RIL_RadioTechnology technology = RADIO_TECH_GSM; - - std::map<RIL_PreferredNetworkType, int>::iterator iter = - gModemTechnologies.find(network_type); - - ALOGV("Searching for best voice technology for network type %d...", - network_type); - - // Find which technology bits are lit. Pick the top most. - for (size_t tech_index = 0; - tech_index < sizeof(gVoiceTechnologiesPreferenceOrder) / - sizeof(gVoiceTechnologiesPreferenceOrder[0]); - ++tech_index) { - if (iter->second & (1 << gVoiceTechnologiesPreferenceOrder[tech_index])) { - technology = gVoiceTechnologiesPreferenceOrder[tech_index]; - break; - } - } - - ALOGV("Best voice technology: %d.", technology); - return technology; -} - -static void setRadioTechnology(RIL_PreferredNetworkType network_type) { - RIL_RadioTechnology technology = getBestVoiceTechnology(network_type); - - if (technology != gModemVoiceTechnology) { - gModemVoiceTechnology = technology; - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, - &gModemVoiceTechnology, - sizeof(gModemVoiceTechnology)); - } -} - -static void request_get_radio_capability(RIL_Token t) { - ALOGV("Requesting radio capability."); - RIL_RadioCapability rc; - rc.version = RIL_RADIO_CAPABILITY_VERSION; - rc.session = 1; - rc.phase = RC_PHASE_CONFIGURED; - rc.rat = RAF_HSPAP; - strncpy(rc.logicalModemUuid, "com.google.cvdgce1.modem", MAX_UUID_LENGTH); - rc.status = RC_STATUS_SUCCESS; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &rc, sizeof(rc)); -} - -static void request_set_radio_capability(void* data, size_t datalen, - RIL_Token t) { - RIL_RadioCapability* rc = (RIL_RadioCapability*)data; - ALOGV( - "RadioCapability version %d session %d phase %d rat %d " - "logicalModemUuid %s status %d", - rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid, - rc->status); - // TODO(ender): do something about these numbers. - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, rc, datalen); -} - -static void request_set_preferred_network_type(int /*request*/, void* data, - size_t /*datalen*/, - RIL_Token t) { - RIL_PreferredNetworkType desired_type = *(RIL_PreferredNetworkType*)(data); - - // TODO(ender): telephony still believes this phone is GSM only. - ALOGV("Requesting modem technology change -> %d", desired_type); - - if (gModemSupportedNetworkTypes.find(desired_type) == - gModemSupportedNetworkTypes.end()) { - desired_type = gModemSupportedNetworkTypes.begin()->first; - } - - if (gModemCurrentType == desired_type) { - ALOGV("Modem technology already set to %d.", desired_type); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; - } - - int supported_technologies = gModemSupportedNetworkTypes[gModemDefaultType]; - int desired_technologies = gModemSupportedNetworkTypes[desired_type]; - - ALOGV("Requesting modem technology change %d -> %d", gModemCurrentType, - desired_type); - - // Check if we support this technology. - if ((supported_technologies & desired_technologies) != desired_technologies) { - ALOGV("Desired technology is not supported."); - gce_ril_env->OnRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0); - return; - } - - gModemCurrentType = desired_type; - setRadioTechnology(desired_type); - ALOGV("Technology change successful."); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_get_preferred_network_type(int /*request*/, void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - gce_ril_env->OnRequestComplete( - t, RIL_E_SUCCESS, - const_cast<RIL_PreferredNetworkType*>(&gModemDefaultType), - sizeof(gModemDefaultType)); -} - -enum RegistrationState { - kUnregistered = 0, - kRegisteredInHomeNetwork = 1, - kSearchingForOperators = 2, - kRegistrationDenied = 3, - kUnknown = 4, - kRegisteredInRoamingMode = 5, - - kUnregistered_EmergencyCallsOnly = 10, - kSearchingForOperators_EmergencyCallsOnly = 12, - kRegistrationDenied_EmergencyCallsOnly = 13, - kUnknown_EmergencyCallsOnly = 14 -}; - -static const char kCdmaMobileDeviceNumber[] = "5551234567"; -static const char kCdmaSID[] = "123"; -static const char kCdmaNID[] = "65535"; // special: indicates free roaming. - -static void request_registration_state(int request, void* /*data*/, - size_t /*datalen*/, RIL_Token t) { - char** responseStr = NULL; - int numElements = 0; - - // See RIL_REQUEST_VOICE_REGISTRATION_STATE and - // RIL_REQUEST_DATA_REGISTRATION_STATE. - numElements = (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) ? 15 : 6; - responseStr = (char**)malloc(numElements * sizeof(char*)); - - asprintf(&responseStr[0], "%d", kRegisteredInHomeNetwork); - responseStr[1] = NULL; // LAC - needed for GSM / WCDMA only. - responseStr[2] = NULL; // CID - needed for GSM / WCDMA only. - - // This is (and always has been) a huge memory leak. - if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) { - ALOGV("Requesting voice registration state."); - asprintf(&responseStr[3], "%d", getBestVoiceTechnology(gModemCurrentType)); - responseStr[4] = strdup("1"); // BSID - responseStr[5] = strdup("123"); // Latitude - responseStr[6] = strdup("222"); // Longitude - responseStr[7] = strdup("0"); // CSS Indicator - responseStr[8] = strdup(kCdmaSID); // SID - responseStr[9] = strdup(kCdmaNID); // NID - responseStr[10] = strdup("0"); // Roaming indicator - responseStr[11] = strdup("1"); // System is in PRL - responseStr[12] = strdup("0"); // Default Roaming indicator - responseStr[13] = strdup("0"); // Reason for denial - responseStr[14] = strdup("0"); // Primary Scrambling Code of Current - } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) { - ALOGV("Requesting data registration state."); - asprintf(&responseStr[3], "%d", getBestDataTechnology(gModemCurrentType)); - responseStr[4] = strdup(""); // DataServiceDenyReason - responseStr[5] = strdup("1"); // Max simultaneous data calls. - } else { - ALOGV("Unexpected request type: %d", request); - return; - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr, - numElements * sizeof(responseStr)); -} - -static void request_baseband_version(RIL_Token t) { - const char* response_str = "CVD_R1.0.0"; - - ALOGV("Requested phone baseband version."); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, strdup(response_str), - sizeof(response_str)); -} - -// Returns true, if modem is CDMA capable. -static bool isCDMA() { - switch (gModemCurrentType) { - case PREF_NET_TYPE_GSM_WCDMA: - case PREF_NET_TYPE_GSM_ONLY: - case PREF_NET_TYPE_WCDMA: - case PREF_NET_TYPE_GSM_WCDMA_AUTO: - case PREF_NET_TYPE_LTE_GSM_WCDMA: - case PREF_NET_TYPE_LTE_ONLY: - return false; - - case PREF_NET_TYPE_CDMA_EVDO_AUTO: - case PREF_NET_TYPE_CDMA_ONLY: - case PREF_NET_TYPE_EVDO_ONLY: - case PREF_NET_TYPE_LTE_CDMA_EVDO: - case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA: - case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO: - return true; - default: - break; - } - - ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType); - return false; -} - -// Returns true, if modem is GSM capable. -// Note, this is not same as !isCDMA(). -static bool isGSM() { - switch (gModemCurrentType) { - case PREF_NET_TYPE_GSM_WCDMA: - case PREF_NET_TYPE_GSM_ONLY: - case PREF_NET_TYPE_WCDMA: - case PREF_NET_TYPE_GSM_WCDMA_AUTO: - case PREF_NET_TYPE_LTE_GSM_WCDMA: - case PREF_NET_TYPE_LTE_ONLY: - case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO: - return true; - - case PREF_NET_TYPE_CDMA_EVDO_AUTO: - case PREF_NET_TYPE_CDMA_ONLY: - case PREF_NET_TYPE_EVDO_ONLY: - case PREF_NET_TYPE_LTE_CDMA_EVDO: - case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA: - return false; - default: - break; - } - - ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType); - return false; -} - -static const char gIdentityGsmImei[] = "12345678902468"; // Luhn cksum = 0. -static const char gIdentityGsmImeiSv[] = "01"; // Arbitrary version. -static const char gIdentityCdmaEsn[] = "A0123456"; // 8 digits, ^[A-F].* -static const char gIdentityCdmaMeid[] = - "A0123456789012"; // 14 digits, ^[A-F].* - -static void request_get_imei(RIL_Token t) { - ALOGV("Requesting IMEI"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, - const_cast<char*>(gIdentityGsmImei), - strlen(gIdentityGsmImei)); -} - -static void request_get_imei_sv(RIL_Token t) { - ALOGV("Requesting IMEI SV"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, - const_cast<char*>(gIdentityGsmImeiSv), - strlen(gIdentityGsmImeiSv)); -} - -static void request_device_identity(int /*request*/, void* /*data*/, - size_t /*datalen*/, RIL_Token t) { - char* response[4] = {NULL}; - - ALOGV("Requesting device identity..."); - - if (isCDMA()) { - response[2] = strdup(&gIdentityCdmaEsn[0]); - response[3] = strdup(&gIdentityCdmaMeid[0]); - } - - if (isGSM()) { - response[0] = strdup(&gIdentityGsmImei[0]); - response[1] = strdup(&gIdentityGsmImeiSv[0]); - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); - - free(response[0]); - free(response[1]); -} - -// Let's pretend we have SIM for CDMA (by default). -static bool gCdmaHasSim = true; -static RIL_CdmaSubscriptionSource gCdmaSubscriptionType = - CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM; - -static void request_cdma_get_subscription_source(int /*request*/, - void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Requesting CDMA Subscription source."); - - if (!isCDMA()) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaSubscriptionType, - sizeof(gCdmaSubscriptionType)); -} - -static void request_enable_uicc_applications(int /*request*/, void* data, - size_t datalen, - RIL_Token t) { - ALOGV("Enable uicc applications."); - - if (data == NULL || datalen != sizeof(int)) { - gce_ril_env->OnRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0); - return; - } - - bool enable = *(int *)(data) != 0; - - ALOGV("areUiccApplicationsEnabled change from %d to %d", areUiccApplicationsEnabled, enable); - - areUiccApplicationsEnabled = enable; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_are_uicc_applications_enabled(int /*request*/, void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Getting whether uicc applications are enabled."); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &areUiccApplicationsEnabled, sizeof(bool)); -} - -static void request_can_toggle_uicc_applications_enablement(int /*request*/, void* /*data*/, - size_t /*datalen*/, RIL_Token t) { - ALOGV("Getting can toggle uicc applications enablement."); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_cdma_set_subscription_source(int /*request*/, void* data, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Setting CDMA Subscription source."); - - if (!isCDMA()) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - RIL_CdmaSubscriptionSource new_source = *(RIL_CdmaSubscriptionSource*)(data); - - if (new_source == CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM && !gCdmaHasSim) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0); - return; - } - - ALOGV("Changed CDMA subscription type from %d to %d", gCdmaSubscriptionType, - new_source); - gCdmaSubscriptionType = new_source; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, - &gCdmaSubscriptionType, - sizeof(gCdmaSubscriptionType)); -} - -static void request_cdma_subscription(int /*request*/, void* /*data*/, - size_t /*datalen*/, RIL_Token t) { - ALOGV("Requesting CDMA Subscription."); - - if (!isCDMA()) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - char* responseStr[5] = {NULL}; - responseStr[0] = strdup(&kCdmaMobileDeviceNumber[0]); // MDN - responseStr[1] = strdup(&kCdmaSID[0]); // SID - responseStr[2] = strdup(&kCdmaNID[0]); // NID - responseStr[3] = strdup(&kCdmaMobileDeviceNumber[0]); // MIN - responseStr[4] = strdup("1"); // PRL Version - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr, - sizeof(responseStr)); -} - -static const int gMaxConcurrentVoiceCalls = 4; -static const int gMaxConcurrentDataCalls = 4; -static const int gMaxConcurrentStandbyConnections = 4; - -static void request_hardware_config(RIL_Token t) { - RIL_HardwareConfig hw_cfg[2]; - - ALOGV("Requesting hardware configuration."); - - strncpy(hw_cfg[0].uuid, "com.google.cvdgce1.modem", sizeof(hw_cfg[0].uuid)); - strncpy(hw_cfg[1].uuid, "com.google.cvdgce1.sim", sizeof(hw_cfg[1].uuid)); - - int technologies = 0; // = unknown. - std::map<RIL_PreferredNetworkType, int>::iterator iter = - gModemTechnologies.find(gModemDefaultType); - if (iter != gModemTechnologies.end()) { - technologies = iter->second; - } - - hw_cfg[0].type = RIL_HARDWARE_CONFIG_MODEM; - hw_cfg[0].state = RIL_HARDWARE_CONFIG_STATE_ENABLED; - hw_cfg[0].cfg.modem.rilModel = 0; - hw_cfg[0].cfg.modem.rat = technologies; - hw_cfg[0].cfg.modem.maxVoice = gMaxConcurrentVoiceCalls; - hw_cfg[0].cfg.modem.maxData = gMaxConcurrentDataCalls; - hw_cfg[0].cfg.modem.maxStandby = gMaxConcurrentStandbyConnections; - - hw_cfg[1].type = RIL_HARDWARE_CONFIG_SIM; - hw_cfg[1].state = RIL_HARDWARE_CONFIG_STATE_ENABLED; - memcpy(hw_cfg[1].cfg.sim.modemUuid, hw_cfg[0].uuid, - sizeof(hw_cfg[1].cfg.sim.modemUuid)); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &hw_cfg, sizeof(hw_cfg)); -} - -// 0 = Home network only, 1 = preferred networks only, 2 = all networks. -static int gCdmaRoamingPreference = 2; - -static void request_cdma_get_roaming_preference(int /*request*/, void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - if (!isCDMA()) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - ALOGV("Requesting CDMA Roaming preference"); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaRoamingPreference, - sizeof(gCdmaRoamingPreference)); -} - -static void request_cdma_set_roaming_preference(int /*request*/, void* data, - size_t /*datalen*/, - RIL_Token t) { - if (!isCDMA()) { - // No such radio. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - int pref = *(int*)data; - ALOGV("Changing CDMA roaming preference: %d -> %d", gCdmaRoamingPreference, - pref); - - if ((pref < 0) || (pref > 2)) { - ALOGV("Unsupported roaming preference: %d", pref); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - gCdmaRoamingPreference = pref; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_send_ussd(void* /*data*/, size_t /*datalen*/, RIL_Token t) { - ALOGV("Sending USSD code is currently not supported"); - // TODO(ender): support this feature - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); -} - -static void request_cancel_ussd(RIL_Token t) { - ALOGV("Cancelling USSD code is currently not supported"); - // TODO(ender): support this feature - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); -} - -static void request_exit_emergency_mode(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGV("Exiting emergency callback mode."); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_set_carrier_restrictions4(void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Set carrier restrictions is not supported"); - // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); -} - -static void request_get_carrier_restrictions4(RIL_Token t) { - ALOGV("Get carrier restrictions is not supported"); - // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); -} - -static RIL_RadioState gce_ril_current_state() { - ALOGV("Reporting radio state %d", gRadioPowerState); - return gRadioPowerState; -} - -static int gce_ril_on_supports(int requestCode) { - ALOGE("%s: Request code %d not implemented", __FUNCTION__, requestCode); - return 1; -} - -static void gce_ril_on_cancel(RIL_Token /*t*/) { - ALOGE("Cancel operation not implemented"); -} - -static const char* gce_ril_get_version(void) { - ALOGV("Reporting Cuttlefish version " CUTTLEFISH_RIL_VERSION_STRING); - return CUTTLEFISH_RIL_VERSION_STRING; -} - -static int s_cell_info_rate_ms = INT_MAX; -static int s_mcc = 0; -static int s_mnc = 0; -static int s_lac = 0; -static int s_cid = 0; - -std::vector<RIL_NeighboringCell> gGSMNeighboringCells; - -static void request_get_neighboring_cell_ids(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGV("Requesting GSM neighboring cell ids"); - - if (!isGSM() || gGSMNeighboringCells.empty()) { - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - RIL_NeighboringCell** cells = - new RIL_NeighboringCell*[gGSMNeighboringCells.size()]; - - for (size_t index = 0; index < gGSMNeighboringCells.size(); ++index) { - cells[index] = &gGSMNeighboringCells[index]; - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, cells, - sizeof(RIL_NeighboringCell*)); - delete[] cells; -} - -static void request_get_cell_info_list(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - struct timespec now; - uint64_t curTime; - - ALOGV("Requesting Cell Info List"); - - clock_gettime(CLOCK_MONOTONIC, &now); - curTime = now.tv_sec * 1000000000LL + now.tv_nsec; - - RIL_CellInfo_v12 ci; - - if (isGSM()) { - ci.cellInfoType = RIL_CELL_INFO_TYPE_GSM; - ci.registered = 1; - ci.timeStampType = RIL_TIMESTAMP_TYPE_ANTENNA; // Our own timestamp. - ci.timeStamp = curTime - 1000; // Fake time in the past. - ci.CellInfo.gsm.cellIdentityGsm.mcc = s_mcc; - ci.CellInfo.gsm.cellIdentityGsm.mnc = s_mnc; - ci.CellInfo.gsm.cellIdentityGsm.lac = s_lac; - ci.CellInfo.gsm.cellIdentityGsm.cid = s_cid; - ci.CellInfo.gsm.signalStrengthGsm.signalStrength = 10; - ci.CellInfo.gsm.signalStrengthGsm.bitErrorRate = 0; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &ci, sizeof(ci)); - } else if (isCDMA()) { - // TODO(ender): CDMA cell support. And LTE. - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - } else { - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - } -} - -struct NetworkOperator { - std::string long_name; - std::string short_name; - bool is_accessible; - - NetworkOperator() {} - - NetworkOperator(const std::string& long_name, const std::string& short_name, - bool is_accessible) - : long_name(long_name), - short_name(short_name), - is_accessible(is_accessible) {} -}; - -static std::map<std::string, NetworkOperator> gNetworkOperators; -static std::string gCurrentNetworkOperator = ""; - -enum OperatorSelectionMethod { - kOperatorAutomatic = 0, - kOperatorManual = 1, - kOperatorDeregistered = 2, - kOperatorManualThenAutomatic = 4 -}; - -static void init_virtual_network() { - gGSMNeighboringCells.resize(1); - gGSMNeighboringCells[0].cid = (char*)"0000"; - gGSMNeighboringCells[0].rssi = 75; - gNetworkOperators["311740"] = - NetworkOperator("Android Virtual Operator", "Android", true); - gNetworkOperators["310300"] = - NetworkOperator("Alternative Operator", "Alternative", true); - gNetworkOperators["310400"] = - NetworkOperator("Hermetic Network Operator", "Hermetic", false); -} - -static OperatorSelectionMethod gOperatorSelectionMethod = kOperatorDeregistered; - -static void request_query_network_selection_mode(void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Query operator selection mode (%d)", gOperatorSelectionMethod); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gOperatorSelectionMethod, - sizeof(gOperatorSelectionMethod)); -} - -static void request_operator(void* /*data*/, size_t /*datalen*/, RIL_Token t) { - std::map<std::string, NetworkOperator>::iterator iter = - gNetworkOperators.find(gCurrentNetworkOperator); - - ALOGV("Requesting current operator info"); - - if (iter == gNetworkOperators.end()) { - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - const char* response[] = {iter->second.long_name.c_str(), - iter->second.short_name.c_str(), - iter->first.c_str()}; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); -} - -static void request_query_available_networks(void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - const char** available_networks = - new const char*[gNetworkOperators.size() * 4]; - - ALOGV("Querying available networks."); - - // TODO(ender): this should only respond once operator is selected and - // registered. - int index = 0; - for (std::map<std::string, NetworkOperator>::iterator iter = - gNetworkOperators.begin(); - iter != gNetworkOperators.end(); ++iter) { - // TODO(ender): wrap in a neat structure maybe? - available_networks[index++] = iter->second.long_name.c_str(); - available_networks[index++] = iter->second.short_name.c_str(); - available_networks[index++] = iter->first.c_str(); - if (!iter->second.is_accessible) { - available_networks[index++] = "forbidden"; - } else if (iter->first == gCurrentNetworkOperator) { - available_networks[index++] = "current"; - } else { - available_networks[index++] = "available"; - } - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &available_networks, - 4 * gNetworkOperators.size()); - delete[] available_networks; -} - -static void request_set_automatic_network_selection(RIL_Token t) { - ALOGV("Requesting automatic operator selection"); - gCurrentNetworkOperator = gNetworkOperators.begin()->first; - gOperatorSelectionMethod = kOperatorAutomatic; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static void request_set_manual_network_selection(void* data, size_t /*datalen*/, - RIL_Token t) { - char* mccmnc = (char*)data; - - ALOGV("Requesting manual operator selection: %s", mccmnc); - - std::map<std::string, NetworkOperator>::iterator iter = - gNetworkOperators.find(mccmnc); - - if (iter == gNetworkOperators.end() || iter->second.is_accessible) { - gce_ril_env->OnRequestComplete(t, RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0); - return; - } - - gCurrentNetworkOperator = mccmnc; - gOperatorSelectionMethod = kOperatorManual; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -static const char kDefaultSMSC[] = "00"; -static int gNextSmsMessageId = 1; - -static void request_cdma_send_SMS(void* /*data*/, RIL_Token t) { - RIL_SMS_Response response = {0, 0, 0}; - // RIL_CDMA_SMS_Message* rcsm = (RIL_CDMA_SMS_Message*) data; - - ALOGW("CDMA SMS Send is currently not implemented."); - - // Cdma Send SMS implementation will go here: - // But it is not implemented yet. - memset(&response, 0, sizeof(response)); - response.messageRef = -1; // This must be BearerData MessageId. - gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, - sizeof(response)); -} - -static void request_send_SMS(void* data, RIL_Token t) { - RIL_SMS_Response response = {0, 0, 0}; - - ALOGV("Send GSM SMS Message"); - - // SMSC is an address of SMS center or NULL for default. - const char* smsc = ((const char**)data)[0]; - if (smsc == NULL) smsc = &kDefaultSMSC[0]; - - response.messageRef = gNextSmsMessageId++; - response.ackPDU = NULL; - response.errorCode = 0; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); - - // response.messageRef = -1; - // gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, - // sizeof(response)); -} - -static void request_set_cell_info_list_rate(void* data, size_t /*datalen*/, - RIL_Token t) { - // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages - // will be sent. - ALOGV("Setting cell info list rate."); - s_cell_info_rate_ms = ((int*)data)[0]; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} -static void request_ims_send_SMS(void* data, size_t /*datalen*/, RIL_Token t) { - RIL_IMS_SMS_Message* args = (RIL_IMS_SMS_Message*)data; - RIL_SMS_Response response{}; - - ALOGV("Send IMS SMS Message"); - - switch (args->tech) { - case RADIO_TECH_3GPP: - return request_send_SMS(args->message.gsmMessage, t); - - case RADIO_TECH_3GPP2: - return request_cdma_send_SMS(args->message.gsmMessage, t); - - default: - ALOGE("Invalid SMS format value: %d", args->tech); - response.messageRef = -2; - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, - sizeof(response)); - } -} - -static void request_SMS_acknowledge(void* data, size_t /*datalen*/, - RIL_Token t) { - int* ack = (int*)data; - - // TODO(ender): we should retain "incoming" sms for later reception. - ALOGV("SMS receipt %ssuccessful (reason %d).", ack[0] ? "" : "un", ack[1]); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -struct SimFileCommand { - uint8_t command; - uint16_t efid; - uint8_t param1; - uint8_t param2; - uint8_t param3; - - bool operator<(const SimFileCommand& other) const { - uint64_t sum1, sum2; - sum1 = (command * 1ull << 40) | (efid * 1ull << 24) | (param1 << 16) | - (param2 << 8) | (param3); - sum2 = (other.command * 1ull << 40) | (other.efid * 1ull << 24) | - (other.param1 << 16) | (other.param2 << 8) | (other.param3); - return sum1 < sum2; - } - - SimFileCommand(uint8_t cmd, uint16_t efid, uint8_t p1, uint8_t p2, uint8_t p3) - : command(cmd), efid(efid), param1(p1), param2(p2), param3(p3) {} -}; - -struct SimFileResponse { - uint8_t sw1; - uint8_t sw2; - const char* data; - - SimFileResponse() : sw1(0), sw2(0), data(NULL) {} - - SimFileResponse(uint8_t sw1, uint8_t sw2, const char* data) - : sw1(sw1), sw2(sw2), data(data) {} -}; - -// TODO(ender): Double check & rewrite these. -std::map<SimFileCommand, SimFileResponse> gSimFileSystem; - -static void init_sim_file_system() { - gSimFileSystem[SimFileCommand(192, 28436, 0, 0, 15)] = - SimFileResponse(144, 0, "000000146f1404001aa0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28436, 0, 0, 20)] = - SimFileResponse(144, 0, "416e64726f6964ffffffffffffffffffffffffff"); - gSimFileSystem[SimFileCommand(192, 28433, 0, 0, 15)] = - SimFileResponse(144, 0, "000000016f11040011a0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28433, 0, 0, 1)] = - SimFileResponse(144, 0, "55"); - gSimFileSystem[SimFileCommand(192, 12258, 0, 0, 15)] = - SimFileResponse(144, 0, "0000000a2fe204000fa0aa01020000"); - gSimFileSystem[SimFileCommand(176, 12258, 0, 0, 10)] = - SimFileResponse(144, 0, "98101430121181157002"); - gSimFileSystem[SimFileCommand(192, 28435, 0, 0, 15)] = - SimFileResponse(144, 0, "000000016f13040011a0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28435, 0, 0, 1)] = - SimFileResponse(144, 0, "55"); - gSimFileSystem[SimFileCommand(192, 28472, 0, 0, 15)] = - SimFileResponse(144, 0, "0000000f6f3804001aa0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28472, 0, 0, 15)] = - SimFileResponse(144, 0, "ff30ffff3c003c03000c0000f03f00"); - gSimFileSystem[SimFileCommand(192, 28617, 0, 0, 15)] = - SimFileResponse(144, 0, "000000086fc9040011a0aa01020104"); - gSimFileSystem[SimFileCommand(178, 28617, 1, 4, 4)] = - SimFileResponse(144, 0, "01000000"); - gSimFileSystem[SimFileCommand(192, 28618, 0, 0, 15)] = - SimFileResponse(144, 0, "0000000a6fca040011a0aa01020105"); - gSimFileSystem[SimFileCommand(178, 28618, 1, 4, 5)] = - SimFileResponse(144, 0, "0000000000"); - gSimFileSystem[SimFileCommand(192, 28589, 0, 0, 15)] = - SimFileResponse(144, 0, "000000046fad04000aa0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28589, 0, 0, 4)] = - SimFileResponse(144, 0, "00000003"); - gSimFileSystem[SimFileCommand(192, 28438, 0, 0, 15)] = - SimFileResponse(144, 0, "000000026f1604001aa0aa01020000"); - gSimFileSystem[SimFileCommand(176, 28438, 0, 0, 2)] = - SimFileResponse(144, 0, "0233"); - gSimFileSystem[SimFileCommand(192, 28486, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28621, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28613, 0, 0, 15)] = - SimFileResponse(144, 0, "000000f06fc504000aa0aa01020118"); - gSimFileSystem[SimFileCommand(178, 28613, 1, 4, 24)] = SimFileResponse( - 144, 0, "43058441aa890affffffffffffffffffffffffffffffffff"); - gSimFileSystem[SimFileCommand(192, 28480, 0, 0, 15)] = - SimFileResponse(144, 0, "000000806f40040011a0aa01020120"); - // Primary phone number encapsulated - // [51][55][21][43][65][f7] = 1 555 1234 567$ - gSimFileSystem[SimFileCommand(178, 28480, 1, 4, 32)] = SimFileResponse( - 144, 0, - "ffffffffffffffffffffffffffffffffffff07915155214365f7ffffffffffff"); - gSimFileSystem[SimFileCommand(192, 28615, 0, 0, 15)] = - SimFileResponse(144, 0, "000000406fc7040011a0aa01020120"); - // Voice mail number encapsulated - // [56][6f][69][63][65][6d][61][69][6c] = 'Voicemail' - // [51][55][67][45][23][f1] = 1 555 7654 321$ - gSimFileSystem[SimFileCommand(178, 28615, 1, 4, 32)] = SimFileResponse( - 144, 0, - "566f6963656d61696cffffffffffffffffff07915155674523f1ffffffffffff"); - gSimFileSystem[SimFileCommand(192, 12037, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28437, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28478, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28450, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28456, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28474, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28481, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28484, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28493, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(192, 28619, 0, 0, 15)] = - SimFileResponse(148, 4, NULL); - gSimFileSystem[SimFileCommand(176, 28506, 0, 0, 4)] = - SimFileResponse(144, 0, "00000013"); -} - -static void request_SIM_IO(void* data, size_t /*datalen*/, RIL_Token t) { - const RIL_SIM_IO_v6& args = *(RIL_SIM_IO_v6*)data; - RIL_SIM_IO_Response sr = {0, 0, 0}; - - ALOGV( - "Requesting SIM File IO: %d EFID %x, Params: %d, %d, %d, path: %s, " - "data %s PIN: %s AID: %s", - args.command, args.fileid, args.p1, args.p2, args.p3, args.path, - args.data, args.pin2, args.aidPtr); - - SimFileCommand cmd(args.command, args.fileid, args.p1, args.p2, args.p3); - - std::map<SimFileCommand, SimFileResponse>::iterator resp = - gSimFileSystem.find(cmd); - - if (resp != gSimFileSystem.end()) { - sr.sw1 = resp->second.sw1; - sr.sw2 = resp->second.sw2; - if (resp->second.data) sr.simResponse = strdup(resp->second.data); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr)); - return; - } - - ALOGW("Unsupported SIM File IO command."); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); -} - -static void request_enter_sim_pin(void* data, size_t /*datalen*/, RIL_Token t) { - const char** pin_aid = (const char**)data; - - ALOGV("Entering PIN: %s / %s", pin_aid[0], pin_aid[1]); - - ++gSimPINAttempts; - int remaining_attempts = gSimPINAttemptsMax - gSimPINAttempts; - - bool is_valid = false; - - if (gSimStatus == SIM_PIN) { - is_valid = (gSimPIN == pin_aid[0]); - } else if (gSimStatus == SIM_PUK) { - is_valid = (gSimPUK == pin_aid[0]); - } else { - ALOGV("Unexpected SIM status for unlock: %d", gSimStatus); - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - - if (!is_valid) { - if (gSimPINAttempts == gSimPINAttemptsMax) { - if (gSimStatus == SIM_PIN) { - gSimStatus = SIM_PUK; - gSimPINAttempts = 0; - } else { - ALOGV("PIN and PUK verification failed; locking SIM card."); - gSimStatus = SIM_NOT_READY; - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - return; - } - } - - gce_ril_env->OnRequestComplete(t, RIL_E_PASSWORD_INCORRECT, - &remaining_attempts, - sizeof(remaining_attempts)); - } else { - if (gSimStatus == SIM_PUK) { - ALOGV("Resetting SIM PIN to %s", pin_aid[1]); - gSimPIN = pin_aid[1]; - } - - gSimPINAttempts = 0; - gSimStatus = SIM_READY; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &remaining_attempts, - sizeof(remaining_attempts)); - } - - pollSIMState(NULL); -} - -/** - * No longer POLL. - */ -static void pollSIMState(void* /*param*/) { - // TODO(ender): check radio state? - - ALOGV("Polling SIM Status."); - - switch (gSimStatus) { - case SIM_ABSENT: - case SIM_PIN: - case SIM_PUK: - case SIM_NETWORK_PERSONALIZATION: - default: - ALOGV("SIM Absent or Locked"); - break; - - case SIM_NOT_READY: - // Transition directly to READY. Set default network operator. - if (gRadioPowerState == RADIO_STATE_ON) { - gSimStatus = SIM_READY; - gCurrentNetworkOperator = "311740"; - } - - gce_ril_env->RequestTimedCallback(pollSIMState, NULL, &TIMEVAL_SIMPOLL); - break; - - case SIM_READY: - ALOGV("SIM Ready. Notifying network state changed."); - break; - } - - if (gRadioPowerState != RADIO_STATE_OFF) { - gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, - NULL, 0); - gce_ril_env->OnUnsolicitedResponse( - RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0); - } -} - -std::map<SIM_Status, RIL_AppStatus> gRilAppStatus; - -static void init_sim_status() { - gRilAppStatus[SIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN, - RIL_APPSTATE_UNKNOWN, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_UNKNOWN, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[SIM_NOT_READY] = - (RIL_AppStatus){RIL_APPTYPE_SIM, - RIL_APPSTATE_DETECTED, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED, - RIL_PINSTATE_ENABLED_NOT_VERIFIED}; - gRilAppStatus[SIM_READY] = (RIL_AppStatus){ - RIL_APPTYPE_SIM, - RIL_APPSTATE_READY, - RIL_PERSOSUBSTATE_READY, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_VERIFIED, - RIL_PINSTATE_ENABLED_VERIFIED, - }; - gRilAppStatus[SIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_SIM, - RIL_APPSTATE_PIN, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[SIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_SIM, - RIL_APPSTATE_PUK, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_BLOCKED, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[SIM_NETWORK_PERSONALIZATION] = - (RIL_AppStatus){RIL_APPTYPE_SIM, - RIL_APPSTATE_SUBSCRIPTION_PERSO, - RIL_PERSOSUBSTATE_SIM_NETWORK, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN, - RIL_APPSTATE_UNKNOWN, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_UNKNOWN, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_NOT_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM, - RIL_APPSTATE_DETECTED, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_UNKNOWN, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM, - RIL_APPSTATE_READY, - RIL_PERSOSUBSTATE_READY, - NULL, - NULL, - 0, - RIL_PINSTATE_UNKNOWN, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_RUIM, - RIL_APPSTATE_PIN, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_RUIM, - RIL_APPSTATE_PUK, - RIL_PERSOSUBSTATE_UNKNOWN, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_BLOCKED, - RIL_PINSTATE_UNKNOWN}; - gRilAppStatus[RUIM_NETWORK_PERSONALIZATION] = - (RIL_AppStatus){RIL_APPTYPE_RUIM, - RIL_APPSTATE_SUBSCRIPTION_PERSO, - RIL_PERSOSUBSTATE_SIM_NETWORK, - NULL, - NULL, - 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED, - RIL_PINSTATE_UNKNOWN}; -} - -/** - * Get the current card status. - */ -static void getCardStatus(RIL_Token t) { - ALOGV("Querying SIM status."); - RIL_CardStatus_v6 card_status; - - if (gSimStatus == SIM_ABSENT) { - card_status.card_state = RIL_CARDSTATE_ABSENT; - card_status.num_applications = 0; - } else { - card_status.card_state = RIL_CARDSTATE_PRESENT; - card_status.num_applications = 1; - } - - card_status.universal_pin_state = RIL_PINSTATE_UNKNOWN; - card_status.gsm_umts_subscription_app_index = -1; - card_status.cdma_subscription_app_index = -1; - card_status.ims_subscription_app_index = -1; - - // Initialize application status - for (int i = 0; i < RIL_CARD_MAX_APPS; i++) { - card_status.applications[i] = gRilAppStatus[SIM_ABSENT]; - } - - if (card_status.num_applications > 0) { - card_status.gsm_umts_subscription_app_index = 0; - - card_status.applications[0] = gRilAppStatus[gSimStatus]; - card_status.universal_pin_state = card_status.applications[0].pin1; - // To enable basic CDMA (currently neither supported nor functional): - // card_status.num_applications = 2; - // card_status.cdma_subscription_app_index = 1; - // card_status.applications[1] = - // gRilAppStatus[SIM_Status(gSimStatus + RUIM_ABSENT)]; - } - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &card_status, - sizeof(card_status)); -} - -struct SimSession { - std::string aid; -}; - -static int gNextSimSessionId = 1; -static std::map<int, SimSession> gSimSessions; - -static void request_sim_open_channel(void* data, size_t /*datalen*/, - RIL_Token t) { - char* aid = (char*)data; - SimSession session; - - ALOGV("Requesting new SIM session"); - - if (aid != NULL) { - session.aid = aid; - } - - int response = gNextSimSessionId++; - gSimSessions[response] = session; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); -} - -static void request_sim_close_channel(void* data, size_t /*datalen*/, - RIL_Token t) { - int session = *(int*)(data); - - ALOGV("Closing SIM session %d", session); - - if (gSimSessions.erase(session) == 0) { - // No such session. - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - } else { - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - } -} - -static void request_sim_apdu(void* data, size_t /*datalen*/, RIL_Token t) { - RIL_SIM_APDU* apdu = (RIL_SIM_APDU*)data; - - ALOGV("Requesting APDU: Session %d CLA %d INST %d Params: %d %d %d, data %s", - apdu->sessionid, apdu->cla, apdu->instruction, apdu->p1, apdu->p2, - apdu->p3, apdu->data); - - if (gSimSessions.find(apdu->sessionid) != gSimSessions.end()) { - RIL_SIM_IO_Response sr{}; - - // Fallback / default behavior. - sr.sw1 = 144; - sr.sw2 = 0; - sr.simResponse = NULL; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr)); - } else { - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - } -} - -// 0 = Lock is available, but disabled. -// 1 = Lock is available and enabled, -// 2 = lock is neither available nor enabled -static const int kFacilityLockAllDisabled = 0; - -static void request_facility_lock(void* data, size_t /*datalen*/, RIL_Token t) { - char** data_vec = (char**)data; - - // TODO(ender): implement this; essentially: AT+CLCK - // See http://www.activexperts.com/sms-component/at/commands/?at=%2BCLCK - // and - // opt/telephony/src/java/com/android/internal/telephony/CommandsInterface.java - // opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java - - ALOGV("Query Facility Lock Code: %s PIN2: %s Service(s): %s AID: %s", - data_vec[0], data_vec[1], data_vec[2], data_vec[3]); - - // TODO(ender): there should be a bit vector of responses for each of the - // services requested. - // Depending on lock code, facilities may be unlocked or locked. We report - // these are all unlocked, regardless of the query. - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, - const_cast<int*>(&kFacilityLockAllDisabled), - sizeof(kFacilityLockAllDisabled)); -} - -static void request_international_subscriber_id_number(RIL_Token t) { - // TODO(ender): Reuse MCC and MNC. - std::string subscriber_id = gCurrentNetworkOperator.c_str(); - subscriber_id += "123456789"; - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, - strdup(subscriber_id.c_str()), sizeof(char*)); -} - -static bool gScreenIsOn = true; - -static void request_set_screen_state(void* data, size_t /*datalen*/, - RIL_Token t) { - gScreenIsOn = *(int*)data ? true : false; - ALOGV("Screen is %s", gScreenIsOn ? "on" : "off"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); -} - -// Unsure which section this belongs in. - -static int gModemTtyMode = 1; // 0 = off, 1 = full, 2 = HCO, 3 = VCO. -static void request_set_tty_mode(void* data, size_t /*datalen*/, RIL_Token t) { - int new_tty_mode = *(int*)(data); - ALOGV("Switching modem TTY mode %d -> %d", gModemTtyMode, new_tty_mode); - - if (new_tty_mode >= 0 && new_tty_mode <= 3) { - gModemTtyMode = new_tty_mode; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - } else { - gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); - } -} - -static void request_get_tty_mode(RIL_Token t) { - ALOGV("Querying TTY mode"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gModemTtyMode, - sizeof(gModemTtyMode)); -} - -static bool gImsRegistered = false; -static int gImsFormat = RADIO_TECH_3GPP; - -static void request_ims_registration_state(RIL_Token t) { - ALOGV("Querying IMS mode"); - int reply[2]; - reply[0] = gImsRegistered; - reply[1] = gImsFormat; - - ALOGV("Requesting IMS Registration state: %d, format=%d ", reply[0], - reply[1]); - - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply)); -} - -// New functions after P. -static void request_start_network_scan(RIL_Token t) { - ALOGV("Scanning network - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_start_network_scan4(RIL_Token t) { - ALOGV("Scanning network 1.4"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_set_preferred_network_type_bitmap(int /*request*/, void* data, - size_t /*datalen*/, - RIL_Token t) { - RIL_RadioAccessFamily desired_access = *(RIL_RadioAccessFamily*)(data); - - ALOGV("Requesting modem technology change %d -> %d", default_access, desired_access); - - /** TODO future implementation: set modem type based on radio access family. - * 1) find supported_technologies and desired_technologies - * 2) return RIL_E_MODE_NOT_SUPPORTED error if not supported - */ - default_access = desired_access; - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_get_preferred_network_type_bitmap(int /*request*/, void* /*data*/, - size_t /*datalen*/, - RIL_Token t) { - ALOGV("Requesting modem radio access family: %d", default_access); - gce_ril_env->OnRequestComplete( - t, RIL_E_SUCCESS, (RIL_RadioAccessFamily*)(&default_access), sizeof(default_access)); -} - -static void request_emergency_dial(int /*request*/, void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGV("Emergency dial"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_set_sim_card_power(int /*request*/, void* /*data*/, size_t /*datalen*/, - RIL_Token t) { - ALOGV("Set sim card power - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_get_modem_stack_status(int /*request*/, RIL_Token t) { - ALOGV("Getting modem stack status - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_enable_modem(int /*request*/, RIL_Token t) { - ALOGV("Enabling modem - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_set_system_selection_channels(int /*request*/, RIL_Token t) { - ALOGV("request_set_system_selection_channels - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -// New functions after Q -static void request_set_signal_strength_reporting_criteria_1_5(int /*request*/, void* /*data*/, - size_t /*datalen*/, RIL_Token t) { - ALOGV("request_set_signal_strength_reporting_criteria_1_5 - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_set_system_selection_channels_1_5(int /*request*/, RIL_Token t) { - ALOGV("request_set_system_selection_channels_1_5 - void"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void request_start_network_scan_1_5(RIL_Token t) { - ALOGV("request_start_network_scan_1_5"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - return; -} - -static void gce_ril_on_request(int request, void* data, size_t datalen, - RIL_Token t) { - // Ignore all requests except RIL_REQUEST_GET_SIM_STATUS - // when RADIO_STATE_UNAVAILABLE. - if (gRadioPowerState == RADIO_STATE_UNAVAILABLE && - request != RIL_REQUEST_GET_SIM_STATUS) { - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - - // Ignore all non-power requests when RADIO_STATE_OFF. - if (gRadioPowerState == RADIO_STATE_OFF) { - switch (request) { - case RIL_REQUEST_GET_SIM_STATUS: - case RIL_REQUEST_OPERATOR: - case RIL_REQUEST_RADIO_POWER: - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: - // Process all the above, even though the radio is off - break; - default: - gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); - return; - } - } - - ALOGV("Received request %d", request); - - switch (request) { - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: - request_query_available_networks(data, datalen, t); - break; - case RIL_REQUEST_GET_IMEI: - request_get_imei(t); - break; - case RIL_REQUEST_GET_IMEISV: - request_get_imei_sv(t); - break; - case RIL_REQUEST_DEACTIVATE_DATA_CALL: - request_teardown_data_call(data, datalen, t); - break; - case RIL_REQUEST_SCREEN_STATE: - request_set_screen_state(data, datalen, t); - break; - case RIL_REQUEST_GET_SIM_STATUS: - getCardStatus(t); - break; - case RIL_REQUEST_GET_CURRENT_CALLS: - request_get_current_calls(data, datalen, t); - break; - case RIL_REQUEST_DIAL: - request_dial(data, datalen, t); - break; - case RIL_REQUEST_HANGUP: - request_hangup(data, datalen, t); - break; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: - request_hangup_waiting(data, datalen, t); - break; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: - request_hangup_current(t); - break; - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: - request_switch_current_and_waiting(t); - break; - case RIL_REQUEST_ANSWER: - request_answer_incoming(t); - break; - case RIL_REQUEST_SET_MUTE: - request_set_mute(data, datalen, t); - break; - case RIL_REQUEST_GET_MUTE: - request_get_mute(t); - break; - case RIL_REQUEST_CONFERENCE: - request_combine_multiparty_call(data, datalen, t); - break; - case RIL_REQUEST_SEPARATE_CONNECTION: - request_split_multiparty_call(data, datalen, t); - break; - case RIL_REQUEST_UDUB: - request_udub_on_incoming_calls(t); - break; - case RIL_REQUEST_SIGNAL_STRENGTH: - request_signal_strength(data, datalen, t); - break; - case RIL_REQUEST_VOICE_REGISTRATION_STATE: - case RIL_REQUEST_DATA_REGISTRATION_STATE: - request_registration_state(request, data, datalen, t); - break; - case RIL_REQUEST_OPERATOR: - request_operator(data, datalen, t); - break; - case RIL_REQUEST_RADIO_POWER: - request_radio_power(data, datalen, t); - break; - case RIL_REQUEST_DTMF: - case RIL_REQUEST_DTMF_START: - request_send_dtmf(data, datalen, t); - break; - case RIL_REQUEST_DTMF_STOP: - request_send_dtmf_stop(t); - break; - case RIL_REQUEST_SEND_SMS: - request_send_SMS(data, t); - break; - case RIL_REQUEST_CDMA_SEND_SMS: - request_cdma_send_SMS(data, t); - break; - case RIL_REQUEST_SETUP_DATA_CALL: - request_setup_data_call(data, datalen, t); - break; - case RIL_REQUEST_SMS_ACKNOWLEDGE: - request_SMS_acknowledge(data, datalen, t); - break; - case RIL_REQUEST_GET_IMSI: - request_international_subscriber_id_number(t); - break; - case RIL_REQUEST_QUERY_FACILITY_LOCK: - request_facility_lock(data, datalen, t); - break; - case RIL_REQUEST_SIM_IO: - request_SIM_IO(data, datalen, t); - break; - case RIL_REQUEST_SEND_USSD: - request_send_ussd(data, datalen, t); - break; - case RIL_REQUEST_CANCEL_USSD: - request_cancel_ussd(t); - break; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: - request_set_automatic_network_selection(t); - break; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: - request_set_manual_network_selection(data, datalen, t); - break; - case RIL_REQUEST_DATA_CALL_LIST: - request_data_calllist(data, datalen, t); - break; - case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: - request_datacall_fail_cause(t); - break; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: - request_query_network_selection_mode(data, datalen, t); - break; - case RIL_REQUEST_OEM_HOOK_RAW: - case RIL_REQUEST_OEM_HOOK_STRINGS: - ALOGV("OEM Hooks not supported!"); - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); - break; - case RIL_REQUEST_WRITE_SMS_TO_SIM: - request_write_sms_to_sim(data, datalen, t); - break; - case RIL_REQUEST_DELETE_SMS_ON_SIM: - request_delete_sms_on_sim(data, datalen, t); - break; - case RIL_REQUEST_ENTER_SIM_PIN: - case RIL_REQUEST_ENTER_SIM_PUK: - case RIL_REQUEST_ENTER_SIM_PIN2: - case RIL_REQUEST_ENTER_SIM_PUK2: - case RIL_REQUEST_CHANGE_SIM_PIN: - case RIL_REQUEST_CHANGE_SIM_PIN2: - request_enter_sim_pin(data, datalen, t); - break; - case RIL_REQUEST_VOICE_RADIO_TECH: { - RIL_RadioTechnology tech = getBestVoiceTechnology(gModemCurrentType); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech)); - break; - } - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: - request_set_preferred_network_type(request, data, datalen, t); - break; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: - request_get_preferred_network_type(request, data, datalen, t); - break; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: - request_get_neighboring_cell_ids(data, datalen, t); - break; - case RIL_REQUEST_GET_CELL_INFO_LIST: - request_get_cell_info_list(data, datalen, t); - break; - case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: - request_set_cell_info_list_rate(data, datalen, t); - break; - case RIL_REQUEST_BASEBAND_VERSION: - request_baseband_version(t); - break; - case RIL_REQUEST_SET_TTY_MODE: - request_set_tty_mode(data, datalen, t); - break; - case RIL_REQUEST_QUERY_TTY_MODE: - request_get_tty_mode(t); - break; - case RIL_REQUEST_GET_RADIO_CAPABILITY: - request_get_radio_capability(t); - break; - case RIL_REQUEST_SET_RADIO_CAPABILITY: - request_set_radio_capability(data, datalen, t); - break; - case RIL_REQUEST_SET_DATA_PROFILE: - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - break; - case RIL_REQUEST_GET_HARDWARE_CONFIG: - request_hardware_config(t); - break; - case RIL_REQUEST_IMS_REGISTRATION_STATE: - request_ims_registration_state(t); - break; - case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: - request_sim_apdu(data, datalen, t); - break; - case RIL_REQUEST_SIM_OPEN_CHANNEL: - request_sim_open_channel(data, datalen, t); - break; - case RIL_REQUEST_SIM_CLOSE_CHANNEL: - request_sim_close_channel(data, datalen, t); - break; - case RIL_REQUEST_IMS_SEND_SMS: - request_ims_send_SMS(data, datalen, t); - break; - case RIL_REQUEST_SET_INITIAL_ATTACH_APN: - ALOGW("INITIAL ATTACH APN"); - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - break; - -// New requests after P. - case RIL_REQUEST_START_NETWORK_SCAN: - request_start_network_scan(t); - break; - case RIL_REQUEST_START_NETWORK_SCAN4: - request_start_network_scan4(t); - break; - case RIL_REQUEST_GET_MODEM_STACK_STATUS: - request_get_modem_stack_status(request, t); - break; - case RIL_REQUEST_ENABLE_MODEM: - request_enable_modem(request, t); - break; - case RIL_REQUEST_EMERGENCY_DIAL: - request_emergency_dial(request, data, datalen, t); - break; - case RIL_REQUEST_SET_SIM_CARD_POWER: - request_set_sim_card_power(request, data, datalen, t); - break; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP: - request_get_preferred_network_type_bitmap(request, data, datalen, t); - break; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP: - request_set_preferred_network_type_bitmap(request, data, datalen, t); - break; - case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS: - request_set_system_selection_channels(request, t); - break; - case RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4: - request_set_carrier_restrictions4(data, datalen, t); - break; - case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4: - request_get_carrier_restrictions4(t); - break; - case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: - gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0); - break; - case RIL_REQUEST_DEVICE_IDENTITY: - request_device_identity(request, data, datalen, t); - break; - case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: - request_cdma_get_subscription_source(request, data, datalen, t); - break; - case RIL_REQUEST_CDMA_SUBSCRIPTION: - request_cdma_subscription(request, data, datalen, t); - break; - case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: - request_cdma_set_subscription_source(request, data, datalen, t); - break; - case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: - request_cdma_get_roaming_preference(request, data, datalen, t); - break; - case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: - request_cdma_set_roaming_preference(request, data, datalen, t); - break; - case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: - request_exit_emergency_mode(data, datalen, t); - break; - -// New requests after Q. - case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5: - request_set_signal_strength_reporting_criteria_1_5(request, data, datalen, t); - break; - case RIL_REQUEST_ENABLE_UICC_APPLICATIONS: - request_enable_uicc_applications(request, data, datalen, t); - break; - case RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED: - request_are_uicc_applications_enabled(request, data, datalen, t); - break; - case RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT: - request_can_toggle_uicc_applications_enablement(request, data, datalen, t); - break; - case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5: - request_set_system_selection_channels_1_5(request, t); - break; - case RIL_REQUEST_START_NETWORK_SCAN_1_5: - request_start_network_scan_1_5(t); - break; - default: - ALOGE("Request %d not supported.", request); - gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); - break; - } -} - -#define CUTTLEFISH_RIL_VERSION 6 - -static const RIL_RadioFunctions ril_callbacks = { - CUTTLEFISH_RIL_VERSION, gce_ril_on_request, gce_ril_current_state, - gce_ril_on_supports, gce_ril_on_cancel, gce_ril_get_version}; - -extern "C" { - -const RIL_RadioFunctions* RIL_Init(const struct RIL_Env* env, int /*argc*/, - char** /*argv*/) { - time(&gce_ril_start_time); - gce_ril_env = env; - - global_ril_config = cvd::DeviceConfig::Get(); - if (!global_ril_config) { - ALOGE("Failed to open device configuration!!!"); - return nullptr; - } - - TearDownNetworkInterface(); - - init_modem_supported_network_types(); - init_modem_technologies(); - init_virtual_network(); - init_sim_file_system(); - init_sim_status(); - - return &ril_callbacks; -} - -} // extern "C" diff --git a/guest/hals/ril/cuttlefish_ril.h b/guest/hals/ril/cuttlefish_ril.h deleted file mode 100644 index 97d4ae15..00000000 --- a/guest/hals/ril/cuttlefish_ril.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#define RIL_SHLIB - -#define LOG_TAG "CuttlefishRil" - -#include <log/log.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/time.h> - -#include <guest/hals/ril/libril/ril.h> - -#include <telephony/ril_cdma_sms.h>
\ No newline at end of file diff --git a/guest/hals/ril/libril/Android.mk b/guest/hals/ril/libril/Android.mk deleted file mode 100644 index f0fe2c78..00000000 --- a/guest/hals/ril/libril/Android.mk +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2019 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. - -# We're forced to use Android.mk here because: -# This depends on headers in hardware/ril/libril -# hardware/ril/libril is still on Android.mk - -ifeq (libril-cuttlefish-fork,$(CUTTLEFISH_LIBRIL_NAME)) -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_VENDOR_MODULE := true -LOCAL_MODULE := libril-cuttlefish-fork -LOCAL_SRC_FILES:= \ - ril.cpp \ - ril_service.cpp \ - ril_event.cpp \ - RilSapSocket.cpp \ - sap_service.cpp \ - - -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libutils \ - libcutils \ - libhardware_legacy \ - libhidlbase \ - librilutils \ - android.hardware.radio@1.0 \ - android.hardware.radio@1.1 \ - android.hardware.radio.deprecated@1.0 \ - android.hardware.radio@1.2 \ - android.hardware.radio@1.3 \ - android.hardware.radio@1.4 \ - android.hardware.radio@1.5 \ - -LOCAL_STATIC_LIBRARIES := \ - libprotobuf-c-nano-enable_malloc \ - -LOCAL_C_INCLUDES += \ - device/google/cuttlefish_common \ - hardware/include \ - external/nanopb-c \ - hardware/ril/include \ - hardware/ril/libril - -LOCAL_CFLAGS += \ - -Wextra \ - -Wno-unused-parameter - -LOCAL_EXPORT_C_INCLUDE_DIRS := hardware/ril/include - -include $(BUILD_SHARED_LIBRARY) -endif diff --git a/guest/hals/ril/libril/RilSapSocket.cpp b/guest/hals/ril/libril/RilSapSocket.cpp deleted file mode 100644 index 34658079..00000000 --- a/guest/hals/ril/libril/RilSapSocket.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/* -* Copyright (C) 2014 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. -*/ - -#define __STDC_LIMIT_MACROS -#include <stdint.h> -#define RIL_SHLIB -#include "RilSapSocket.h" -#include "pb_decode.h" -#include "pb_encode.h" -#undef LOG_TAG -#define LOG_TAG "RIL_UIM_SOCKET" -#include <utils/Log.h> -#include <arpa/inet.h> -#include <errno.h> -#include <sap_service.h> -#include <guest/hals/ril/libril/ril.h> - -static RilSapSocket::RilSapSocketList *head = NULL; - -extern "C" void -RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, - const struct timeval *relativeTime); - -struct RIL_Env RilSapSocket::uimRilEnv = { - .OnRequestComplete = RilSapSocket::sOnRequestComplete, - .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse, - .RequestTimedCallback = RIL_requestTimedCallback -}; - -void RilSapSocket::sOnRequestComplete (RIL_Token t, - RIL_Errno e, - void *response, - size_t responselen) { - RilSapSocket *sap_socket; - SapSocketRequest *request = (SapSocketRequest*) t; - - RLOGD("Socket id:%d", request->socketId); - - sap_socket = getSocketById(request->socketId); - - if (sap_socket) { - sap_socket->onRequestComplete(t,e,response,responselen); - } else { - RLOGE("Invalid socket id"); - if (request->curr) { - free(request->curr); - } - free(request); - } -} - -#if defined(ANDROID_MULTI_SIM) -void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, - const void *data, - size_t datalen, - RIL_SOCKET_ID socketId) { - RilSapSocket *sap_socket = getSocketById(socketId); - if (sap_socket) { - sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); - } -} -#else -void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, - const void *data, - size_t datalen) { - RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1); - if(sap_socket){ - sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); - } -} -#endif - -void RilSapSocket::printList() { - RilSapSocketList *current = head; - RLOGD("Printing socket list"); - while(NULL != current) { - RLOGD("SocketName:%s",current->socket->name); - RLOGD("Socket id:%d",current->socket->id); - current = current->next; - } -} - -RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) { - RilSapSocket *sap_socket; - RilSapSocketList *current = head; - - RLOGD("Entered getSocketById"); - printList(); - - while(NULL != current) { - if(socketId == current->socket->id) { - sap_socket = current->socket; - return sap_socket; - } - current = current->next; - } - return NULL; -} - -void RilSapSocket::initSapSocket(const char *socketName, - const RIL_RadioFunctions *uimFuncs) { - - if (strcmp(socketName, RIL1_SERVICE_NAME) == 0) { - if(!SocketExists(socketName)) { - addSocketToList(socketName, RIL_SOCKET_1, uimFuncs); - } - } - -#if (SIM_COUNT >= 2) - if (strcmp(socketName, RIL2_SERVICE_NAME) == 0) { - if(!SocketExists(socketName)) { - addSocketToList(socketName, RIL_SOCKET_2, uimFuncs); - } - } -#endif - -#if (SIM_COUNT >= 3) - if (strcmp(socketName, RIL3_SERVICE_NAME) == 0) { - if(!SocketExists(socketName)) { - addSocketToList(socketName, RIL_SOCKET_3, uimFuncs); - } - } -#endif - -#if (SIM_COUNT >= 4) - if (strcmp(socketName, RIL4_SERVICE_NAME) == 0) { - if(!SocketExists(socketName)) { - addSocketToList(socketName, RIL_SOCKET_4, uimFuncs); - } - } -#endif -} - -void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid, - const RIL_RadioFunctions *uimFuncs) { - RilSapSocket* socket = NULL; - RilSapSocketList *current; - - if(!SocketExists(socketName)) { - socket = new RilSapSocket(socketName, socketid, uimFuncs); - RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList)); - if (!listItem) { - RLOGE("addSocketToList: OOM"); - delete socket; - return; - } - listItem->socket = socket; - listItem->next = NULL; - - RLOGD("Adding socket with id: %d", socket->id); - - if(NULL == head) { - head = listItem; - head->next = NULL; - } - else { - current = head; - while(NULL != current->next) { - current = current->next; - } - current->next = listItem; - } - } -} - -bool RilSapSocket::SocketExists(const char *socketName) { - RilSapSocketList* current = head; - - while(NULL != current) { - if(strcmp(current->socket->name, socketName) == 0) { - return true; - } - current = current->next; - } - return false; -} - -RilSapSocket::RilSapSocket(const char *socketName, - RIL_SOCKET_ID socketId, - const RIL_RadioFunctions *inputUimFuncs): - RilSocket(socketName, socketId) { - if (inputUimFuncs) { - uimFuncs = inputUimFuncs; - } -} - -void RilSapSocket::dispatchRequest(MsgHeader *req) { - // SapSocketRequest will be deallocated in onRequestComplete() - SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); - if (!currRequest) { - RLOGE("dispatchRequest: OOM"); - // Free MsgHeader allocated in pushRecord() - free(req); - return; - } - currRequest->token = req->token; - currRequest->curr = req; - currRequest->p_next = NULL; - currRequest->socketId = id; - - pendingResponseQueue.enqueue(currRequest); - - if (uimFuncs) { - RLOGI("RilSapSocket::dispatchRequest [%d] > SAP REQUEST type: %d. id: %d. error: %d, \ - token 0x%p", - req->token, - req->type, - req->id, - req->error, - currRequest ); - -#if defined(ANDROID_MULTI_SIM) - uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); -#else - uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest); -#endif - } -} - -void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response, - size_t response_len) { - SapSocketRequest* request= (SapSocketRequest*)t; - - if (!request || !request->curr) { - RLOGE("RilSapSocket::onRequestComplete: request/request->curr is NULL"); - return; - } - - MsgHeader *hdr = request->curr; - - MsgHeader rsp; - rsp.token = request->curr->token; - rsp.type = MsgType_RESPONSE; - rsp.id = request->curr->id; - rsp.error = (Error)e; - rsp.payload = (pb_bytes_array_t *)calloc(1, sizeof(pb_bytes_array_t) + response_len); - if (!rsp.payload) { - RLOGE("onRequestComplete: OOM"); - } else { - if (response && response_len > 0) { - memcpy(rsp.payload->bytes, response, response_len); - rsp.payload->size = response_len; - } else { - rsp.payload->size = 0; - } - - RLOGE("RilSapSocket::onRequestComplete: Token:%d, MessageId:%d ril token 0x%p", - hdr->token, hdr->id, t); - - sap::processResponse(&rsp, this); - free(rsp.payload); - } - - // Deallocate SapSocketRequest - if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) { - RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id); - RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id"); - } - - // Deallocate MsgHeader - free(hdr); -} - -void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) { - if (data && datalen > 0) { - pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1, - sizeof(pb_bytes_array_t) + datalen); - if (!payload) { - RLOGE("onUnsolicitedResponse: OOM"); - return; - } - memcpy(payload->bytes, data, datalen); - payload->size = datalen; - MsgHeader rsp; - rsp.payload = payload; - rsp.type = MsgType_UNSOL_RESPONSE; - rsp.id = (MsgId)unsolResponse; - rsp.error = Error_RIL_E_SUCCESS; - sap::processUnsolResponse(&rsp, this); - free(payload); - } -} diff --git a/guest/hals/ril/libril/ril.cpp b/guest/hals/ril/libril/ril.cpp deleted file mode 100644 index 8d3497e7..00000000 --- a/guest/hals/ril/libril/ril.cpp +++ /dev/null @@ -1,1253 +0,0 @@ -/* //guest/hals/ril/ril.cpp -** -** Copyright 2006, 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. -*/ - -#define LOG_TAG "RILC" - -#include <hardware_legacy/power.h> -#include <guest/hals/ril/libril/ril.h> -#include <telephony/ril_cdma_sms.h> -#include <cutils/sockets.h> -#include <telephony/record_stream.h> -#include <utils/Log.h> -#include <utils/SystemClock.h> -#include <pthread.h> -#include <sys/types.h> -#include <sys/limits.h> -#include <sys/system_properties.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> -#include <sys/un.h> -#include <assert.h> -#include <netinet/in.h> -#include <cutils/properties.h> -#include <RilSapSocket.h> -#include <guest/hals/ril/libril/ril_service.h> -#include <sap_service.h> - -extern "C" void -RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen); - -extern "C" void -RIL_onRequestAck(RIL_Token t); -namespace android { - -#define PHONE_PROCESS "radio" -#define BLUETOOTH_PROCESS "bluetooth" - -#define ANDROID_WAKE_LOCK_NAME "radio-interface" - -#define ANDROID_WAKE_LOCK_SECS 0 -#define ANDROID_WAKE_LOCK_USECS 200000 - -#define PROPERTY_RIL_IMPL "gsm.version.ril-impl" - -// match with constant in RIL.java -#define MAX_COMMAND_BYTES (8 * 1024) - -// Basically: memset buffers that the client library -// shouldn't be using anymore in an attempt to find -// memory usage issues sooner. -#define MEMSET_FREED 1 - -#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0]) - -/* Negative values for private RIL errno's */ -#define RIL_ERRNO_INVALID_RESPONSE (-1) -#define RIL_ERRNO_NO_MEMORY (-12) - -// request, response, and unsolicited msg print macro -#define PRINTBUF_SIZE 8096 - -enum WakeType {DONT_WAKE, WAKE_PARTIAL}; - -typedef struct { - int requestNumber; - int (*responseFunction) (int slotId, int responseType, int token, - RIL_Errno e, void *response, size_t responselen); - WakeType wakeType; -} UnsolResponseInfo; - -typedef struct UserCallbackInfo { - RIL_TimedCallback p_callback; - void *userParam; - struct ril_event event; - struct UserCallbackInfo *p_next; -} UserCallbackInfo; - -extern "C" const char * failCauseToString(RIL_Errno); -extern "C" const char * callStateToString(RIL_CallState); -extern "C" const char * radioStateToString(RIL_RadioState); -extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id); - -extern "C" -char ril_service_name_base[MAX_SERVICE_NAME_LENGTH] = RIL_SERVICE_NAME_BASE; -extern "C" -char ril_service_name[MAX_SERVICE_NAME_LENGTH] = RIL1_SERVICE_NAME; -/*******************************************************************/ - -RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL}; -static int s_registerCalled = 0; - -static pthread_t s_tid_dispatch; -static int s_started = 0; - -static int s_fdWakeupRead; -static int s_fdWakeupWrite; - -int s_wakelock_count = 0; - -static struct ril_event s_wakeupfd_event; - -static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER; -static RequestInfo *s_pendingRequests = NULL; - -#if (SIM_COUNT >= 2) -static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; -static RequestInfo *s_pendingRequests_socket2 = NULL; -#endif - -#if (SIM_COUNT >= 3) -static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; -static RequestInfo *s_pendingRequests_socket3 = NULL; -#endif - -#if (SIM_COUNT >= 4) -static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; -static RequestInfo *s_pendingRequests_socket4 = NULL; -#endif - -static const struct timeval TIMEVAL_WAKE_TIMEOUT = {ANDROID_WAKE_LOCK_SECS,ANDROID_WAKE_LOCK_USECS}; - - -static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER; - -static UserCallbackInfo *s_last_wake_timeout_info = NULL; - -static void *s_lastNITZTimeData = NULL; -static size_t s_lastNITZTimeDataSize; - -#if RILC_LOG - static char printBuf[PRINTBUF_SIZE]; -#endif - -/*******************************************************************/ -static void grabPartialWakeLock(); -void releaseWakeLock(); -static void wakeTimeoutCallback(void *); - -#ifdef RIL_SHLIB -#if defined(ANDROID_MULTI_SIM) -extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen, RIL_SOCKET_ID socket_id); -#else -extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen); -#endif -#endif - -#if defined(ANDROID_MULTI_SIM) -#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d)) -#else -#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c)) -#endif - -static UserCallbackInfo * internalRequestTimedCallback - (RIL_TimedCallback callback, void *param, - const struct timeval *relativeTime); - -/** Index == requestNumber */ -static CommandInfo s_commands[] = { -#include "ril_commands.h" -}; - -static UnsolResponseInfo s_unsolResponses[] = { -#include "ril_unsol_commands.h" -}; - -char * RIL_getServiceName() { - return ril_service_name; -} - -RequestInfo * -addRequestToList(int serial, int slotId, int request) { - RequestInfo *pRI; - int ret; - RIL_SOCKET_ID socket_id = (RIL_SOCKET_ID) slotId; - /* Hook for current context */ - /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ - pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; - /* pendingRequestsHook refer to &s_pendingRequests */ - RequestInfo** pendingRequestsHook = &s_pendingRequests; - -#if (SIM_COUNT >= 2) - if (socket_id == RIL_SOCKET_2) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; - pendingRequestsHook = &s_pendingRequests_socket2; - } -#if (SIM_COUNT >= 3) - else if (socket_id == RIL_SOCKET_3) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3; - pendingRequestsHook = &s_pendingRequests_socket3; - } -#endif -#if (SIM_COUNT >= 4) - else if (socket_id == RIL_SOCKET_4) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4; - pendingRequestsHook = &s_pendingRequests_socket4; - } -#endif -#endif - - pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); - if (pRI == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(request)); - return NULL; - } - - pRI->token = serial; - pRI->pCI = &(s_commands[request]); - pRI->socket_id = socket_id; - - ret = pthread_mutex_lock(pendingRequestsMutexHook); - assert (ret == 0); - - pRI->p_next = *pendingRequestsHook; - *pendingRequestsHook = pRI; - - ret = pthread_mutex_unlock(pendingRequestsMutexHook); - assert (ret == 0); - - return pRI; -} - -static void triggerEvLoop() { - int ret; - if (!pthread_equal(pthread_self(), s_tid_dispatch)) { - /* trigger event loop to wakeup. No reason to do this, - * if we're in the event loop thread */ - do { - ret = write (s_fdWakeupWrite, " ", 1); - } while (ret < 0 && errno == EINTR); - } -} - -static void rilEventAddWakeup(struct ril_event *ev) { - ril_event_add(ev); - triggerEvLoop(); -} - -/** - * A write on the wakeup fd is done just to pop us out of select() - * We empty the buffer here and then ril_event will reset the timers on the - * way back down - */ -static void processWakeupCallback(int fd, short flags, void *param) { - char buff[16]; - int ret; - - RLOGV("processWakeupCallback"); - - /* empty our wakeup socket out */ - do { - ret = read(s_fdWakeupRead, &buff, sizeof(buff)); - } while (ret > 0 || (ret < 0 && errno == EINTR)); -} - -static void resendLastNITZTimeData(RIL_SOCKET_ID socket_id) { - if (s_lastNITZTimeData != NULL) { - int responseType = (s_callbacks.version >= 13) - ? RESPONSE_UNSOLICITED_ACK_EXP - : RESPONSE_UNSOLICITED; - // acquire read lock for the service before calling nitzTimeReceivedInd() since it reads - // nitzTimeReceived in ril_service - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock( - (int) socket_id); - int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - - int ret = radio_1_5::nitzTimeReceivedInd( - (int)socket_id, responseType, 0, - RIL_E_SUCCESS, s_lastNITZTimeData, s_lastNITZTimeDataSize); - if (ret == 0) { - free(s_lastNITZTimeData); - s_lastNITZTimeData = NULL; - } - - rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - } -} - -void onNewCommandConnect(RIL_SOCKET_ID socket_id) { - // Inform we are connected and the ril version - int rilVer = s_callbacks.version; - RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, - &rilVer, sizeof(rilVer), socket_id); - - // implicit radio state changed - RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, - NULL, 0, socket_id); - - // Send last NITZ time data, in case it was missed - if (s_lastNITZTimeData != NULL) { - resendLastNITZTimeData(socket_id); - } - - // Get version string - if (s_callbacks.getVersion != NULL) { - const char *version; - version = s_callbacks.getVersion(); - RLOGI("RIL Daemon version: %s\n", version); - - property_set(PROPERTY_RIL_IMPL, version); - } else { - RLOGI("RIL Daemon version: unavailable\n"); - property_set(PROPERTY_RIL_IMPL, "unavailable"); - } - -} - -static void userTimerCallback (int fd, short flags, void *param) { - UserCallbackInfo *p_info; - - p_info = (UserCallbackInfo *)param; - - p_info->p_callback(p_info->userParam); - - - // FIXME generalize this...there should be a cancel mechanism - if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) { - s_last_wake_timeout_info = NULL; - } - - free(p_info); -} - - -static void * -eventLoop(void *param) { - int ret; - int filedes[2]; - - ril_event_init(); - - pthread_mutex_lock(&s_startupMutex); - - s_started = 1; - pthread_cond_broadcast(&s_startupCond); - - pthread_mutex_unlock(&s_startupMutex); - - ret = pipe(filedes); - - if (ret < 0) { - RLOGE("Error in pipe() errno:%d", errno); - return NULL; - } - - s_fdWakeupRead = filedes[0]; - s_fdWakeupWrite = filedes[1]; - - fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK); - - ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, - processWakeupCallback, NULL); - - rilEventAddWakeup (&s_wakeupfd_event); - - // Only returns on error - ril_event_loop(); - RLOGE ("error in event_loop_base errno:%d", errno); - // kill self to restart on error - kill(0, SIGKILL); - - return NULL; -} - -extern "C" void -RIL_startEventLoop(void) { - /* spin up eventLoop thread and wait for it to get started */ - s_started = 0; - pthread_mutex_lock(&s_startupMutex); - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL); - if (result != 0) { - RLOGE("Failed to create dispatch thread: %s", strerror(result)); - goto done; - } - - while (s_started == 0) { - pthread_cond_wait(&s_startupCond, &s_startupMutex); - } - -done: - pthread_mutex_unlock(&s_startupMutex); -} - -// Used for testing purpose only. -extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) { - memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); -} - -extern "C" void -RIL_register (const RIL_RadioFunctions *callbacks) { - RLOGI("SIM_COUNT: %d", SIM_COUNT); - - if (callbacks == NULL) { - RLOGE("RIL_register: RIL_RadioFunctions * null"); - return; - } - if (callbacks->version < RIL_VERSION_MIN) { - RLOGE("RIL_register: version %d is to old, min version is %d", - callbacks->version, RIL_VERSION_MIN); - return; - } - - RLOGD("RIL_register: Vsoc RIL version %d", callbacks->version); - - if (s_registerCalled > 0) { - RLOGE("RIL_register has been called more than once. " - "Subsequent call ignored"); - return; - } - - memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); - - s_registerCalled = 1; - - RLOGI("s_registerCalled flag set, %d", s_started); - // Little self-check - - for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) { - assert(i == s_commands[i].requestNumber); - } - - for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) { - assert(i + RIL_UNSOL_RESPONSE_BASE - == s_unsolResponses[i].requestNumber); - } - - radio_1_5::registerService(&s_callbacks, s_commands); - RLOGI("RILHIDL called registerService"); - -} - -extern "C" void -RIL_register_socket (const RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **), - RIL_SOCKET_TYPE socketType, int argc, char **argv) { - - const RIL_RadioFunctions* UimFuncs = NULL; - - if(Init) { - UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv); - - switch(socketType) { - case RIL_SAP_SOCKET: - RilSapSocket::initSapSocket(RIL1_SERVICE_NAME, UimFuncs); - -#if (SIM_COUNT >= 2) - RilSapSocket::initSapSocket(RIL2_SERVICE_NAME, UimFuncs); -#endif - -#if (SIM_COUNT >= 3) - RilSapSocket::initSapSocket(RIL3_SERVICE_NAME, UimFuncs); -#endif - -#if (SIM_COUNT >= 4) - RilSapSocket::initSapSocket(RIL4_SERVICE_NAME, UimFuncs); -#endif - break; - default:; - } - - RLOGI("RIL_register_socket: calling registerService"); - sap::registerService(UimFuncs); - } -} - -// Check and remove RequestInfo if its a response and not just ack sent back -static int -checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) { - int ret = 0; - /* Hook for current context - pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ - pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; - /* pendingRequestsHook refer to &s_pendingRequests */ - RequestInfo ** pendingRequestsHook = &s_pendingRequests; - - if (pRI == NULL) { - return 0; - } - -#if (SIM_COUNT >= 2) - if (pRI->socket_id == RIL_SOCKET_2) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; - pendingRequestsHook = &s_pendingRequests_socket2; - } -#if (SIM_COUNT >= 3) - if (pRI->socket_id == RIL_SOCKET_3) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3; - pendingRequestsHook = &s_pendingRequests_socket3; - } -#endif -#if (SIM_COUNT >= 4) - if (pRI->socket_id == RIL_SOCKET_4) { - pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4; - pendingRequestsHook = &s_pendingRequests_socket4; - } -#endif -#endif - pthread_mutex_lock(pendingRequestsMutexHook); - - for(RequestInfo **ppCur = pendingRequestsHook - ; *ppCur != NULL - ; ppCur = &((*ppCur)->p_next) - ) { - if (pRI == *ppCur) { - ret = 1; - if (isAck) { // Async ack - if (pRI->wasAckSent == 1) { - RLOGD("Ack was already sent for %s", requestToString(pRI->pCI->requestNumber)); - } else { - pRI->wasAckSent = 1; - } - } else { - *ppCur = (*ppCur)->p_next; - } - break; - } - } - - pthread_mutex_unlock(pendingRequestsMutexHook); - - return ret; -} - -extern "C" void -RIL_onRequestAck(RIL_Token t) { - RequestInfo *pRI; - - RIL_SOCKET_ID socket_id = RIL_SOCKET_1; - - pRI = (RequestInfo *)t; - - if (!checkAndDequeueRequestInfoIfAck(pRI, true)) { - RLOGE ("RIL_onRequestAck: invalid RIL_Token"); - return; - } - - socket_id = pRI->socket_id; - -#if VDBG - RLOGD("Request Ack, %s", rilSocketIdToString(socket_id)); -#endif - - appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber)); - - if (pRI->cancelled == 0) { - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock( - (int) socket_id); - int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - - radio_1_5::acknowledgeRequest((int) socket_id, pRI->token); - - rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - } -} -extern "C" void -RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) { - RequestInfo *pRI; - int ret; - RIL_SOCKET_ID socket_id = RIL_SOCKET_1; - - pRI = (RequestInfo *)t; - - if (!checkAndDequeueRequestInfoIfAck(pRI, false)) { - RLOGE ("RIL_onRequestComplete: invalid RIL_Token"); - return; - } - - socket_id = pRI->socket_id; - -#if VDBG - RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id)); -#endif - - if (pRI->local > 0) { - // Locally issued command...void only! - // response does not go back up the command socket - RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber)); - - free(pRI); - return; - } - - appendPrintBuf("[%04d]< %s", - pRI->token, requestToString(pRI->pCI->requestNumber)); - - if (pRI->cancelled == 0) { - int responseType; - if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) { - // If ack was already sent, then this call is an asynchronous response. So we need to - // send id indicating that we expect an ack from RIL.java as we acquire wakelock here. - responseType = RESPONSE_SOLICITED_ACK_EXP; - grabPartialWakeLock(); - } else { - responseType = RESPONSE_SOLICITED; - } - - // there is a response payload, no matter success or not. -#if VDBG - RLOGE ("Calling responseFunction() for token %d", pRI->token); -#endif - - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock((int) socket_id); - int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - - ret = pRI->pCI->responseFunction((int) socket_id, - responseType, pRI->token, e, response, responselen); - - rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - } - free(pRI); -} - -static void -grabPartialWakeLock() { - if (s_callbacks.version >= 13) { - int ret; - ret = pthread_mutex_lock(&s_wakeLockCountMutex); - assert(ret == 0); - acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME); - - UserCallbackInfo *p_info = - internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT); - if (p_info == NULL) { - release_wake_lock(ANDROID_WAKE_LOCK_NAME); - } else { - s_wakelock_count++; - if (s_last_wake_timeout_info != NULL) { - s_last_wake_timeout_info->userParam = (void *)1; - } - s_last_wake_timeout_info = p_info; - } - ret = pthread_mutex_unlock(&s_wakeLockCountMutex); - assert(ret == 0); - } else { - acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME); - } -} - -void -releaseWakeLock() { - if (s_callbacks.version >= 13) { - int ret; - ret = pthread_mutex_lock(&s_wakeLockCountMutex); - assert(ret == 0); - - if (s_wakelock_count > 1) { - s_wakelock_count--; - } else { - s_wakelock_count = 0; - release_wake_lock(ANDROID_WAKE_LOCK_NAME); - if (s_last_wake_timeout_info != NULL) { - s_last_wake_timeout_info->userParam = (void *)1; - } - } - - ret = pthread_mutex_unlock(&s_wakeLockCountMutex); - assert(ret == 0); - } else { - release_wake_lock(ANDROID_WAKE_LOCK_NAME); - } -} - -/** - * Timer callback to put us back to sleep before the default timeout - */ -static void -wakeTimeoutCallback (void *param) { - // We're using "param != NULL" as a cancellation mechanism - if (s_callbacks.version >= 13) { - if (param == NULL) { - int ret; - ret = pthread_mutex_lock(&s_wakeLockCountMutex); - assert(ret == 0); - s_wakelock_count = 0; - release_wake_lock(ANDROID_WAKE_LOCK_NAME); - ret = pthread_mutex_unlock(&s_wakeLockCountMutex); - assert(ret == 0); - } - } else { - if (param == NULL) { - releaseWakeLock(); - } - } -} - -#if defined(ANDROID_MULTI_SIM) -extern "C" -void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen, RIL_SOCKET_ID socket_id) -#else -extern "C" -void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen) -#endif -{ - int unsolResponseIndex; - int ret; - bool shouldScheduleTimeout = false; - RIL_SOCKET_ID soc_id = RIL_SOCKET_1; - -#if defined(ANDROID_MULTI_SIM) - soc_id = socket_id; -#endif - - - if (s_registerCalled == 0) { - // Ignore RIL_onUnsolicitedResponse before RIL_register - RLOGW("RIL_onUnsolicitedResponse called before RIL_register"); - return; - } - - unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE; - - if ((unsolResponseIndex < 0) - || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) { - RLOGE("unsupported unsolicited response code %d", unsolResponse); - return; - } - - // Grab a wake lock if needed for this reponse, - // as we exit we'll either release it immediately - // or set a timer to release it later. - switch (s_unsolResponses[unsolResponseIndex].wakeType) { - case WAKE_PARTIAL: - grabPartialWakeLock(); - shouldScheduleTimeout = true; - break; - - case DONT_WAKE: - default: - // No wake lock is grabed so don't set timeout - shouldScheduleTimeout = false; - break; - } - - appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse)); - - int responseType; - if (s_callbacks.version >= 13 - && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) { - responseType = RESPONSE_UNSOLICITED_ACK_EXP; - } else { - responseType = RESPONSE_UNSOLICITED; - } - - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock((int) soc_id); - int rwlockRet; - - if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { - // get a write lock in caes of NITZ since setNitzTimeReceived() is called - rwlockRet = pthread_rwlock_wrlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - radio_1_5::setNitzTimeReceived((int) soc_id, android::elapsedRealtime()); - } else { - rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - } - - if (s_unsolResponses[unsolResponseIndex].responseFunction) { - RLOGD("calling UNSOLICITED responseFunction for index %d", unsolResponseIndex); - ret = s_unsolResponses[unsolResponseIndex].responseFunction( - (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast<void*>(data), - datalen); - } else { - RLOGW("No call responseFunction defined for UNSOLICITED"); - } - - rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(rwlockRet == 0); - - if (s_callbacks.version < 13) { - if (shouldScheduleTimeout) { - UserCallbackInfo *p_info = internalRequestTimedCallback(wakeTimeoutCallback, NULL, - &TIMEVAL_WAKE_TIMEOUT); - - if (p_info == NULL) { - goto error_exit; - } else { - // Cancel the previous request - if (s_last_wake_timeout_info != NULL) { - s_last_wake_timeout_info->userParam = (void *)1; - } - s_last_wake_timeout_info = p_info; - } - } - } - -#if VDBG - RLOGI("%s UNSOLICITED: %s length:%zu", rilSocketIdToString(soc_id), - requestToString(unsolResponse), datalen); -#endif - - if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { - // Unfortunately, NITZ time is not poll/update like everything - // else in the system. So, if the upstream client isn't connected, - // keep a copy of the last NITZ response (with receive time noted - // above) around so we can deliver it when it is connected - - if (s_lastNITZTimeData != NULL) { - free(s_lastNITZTimeData); - s_lastNITZTimeData = NULL; - } - - s_lastNITZTimeData = calloc(datalen, 1); - if (s_lastNITZTimeData == NULL) { - RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse"); - goto error_exit; - } - s_lastNITZTimeDataSize = datalen; - memcpy(s_lastNITZTimeData, data, datalen); - } - - // Normal exit - return; - -error_exit: - if (shouldScheduleTimeout) { - releaseWakeLock(); - } -} - -/** FIXME generalize this if you track UserCAllbackInfo, clear it - when the callback occurs -*/ -static UserCallbackInfo * -internalRequestTimedCallback (RIL_TimedCallback callback, void *param, - const struct timeval *relativeTime) -{ - struct timeval myRelativeTime; - UserCallbackInfo *p_info; - - p_info = (UserCallbackInfo *) calloc(1, sizeof(UserCallbackInfo)); - if (p_info == NULL) { - RLOGE("Memory allocation failed in internalRequestTimedCallback"); - return p_info; - - } - - p_info->p_callback = callback; - p_info->userParam = param; - - if (relativeTime == NULL) { - /* treat null parameter as a 0 relative time */ - memset (&myRelativeTime, 0, sizeof(myRelativeTime)); - } else { - /* FIXME I think event_add's tv param is really const anyway */ - memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime)); - } - - ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info); - - ril_timer_add(&(p_info->event), &myRelativeTime); - - triggerEvLoop(); - return p_info; -} - - -extern "C" void -RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, - const struct timeval *relativeTime) { - internalRequestTimedCallback (callback, param, relativeTime); -} - -const char * -failCauseToString(RIL_Errno e) { - switch(e) { - case RIL_E_SUCCESS: return "E_SUCCESS"; - case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE"; - case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE"; - case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT"; - case RIL_E_SIM_PIN2: return "E_SIM_PIN2"; - case RIL_E_SIM_PUK2: return "E_SIM_PUK2"; - case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED"; - case RIL_E_CANCELLED: return "E_CANCELLED"; - case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL"; - case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW"; - case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY"; - case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT"; - case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME"; -#ifdef FEATURE_MULTIMODE_ANDROID - case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE"; - case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED"; -#endif - case RIL_E_FDN_CHECK_FAILURE: return "E_FDN_CHECK_FAILURE"; - case RIL_E_MISSING_RESOURCE: return "E_MISSING_RESOURCE"; - case RIL_E_NO_SUCH_ELEMENT: return "E_NO_SUCH_ELEMENT"; - case RIL_E_DIAL_MODIFIED_TO_USSD: return "E_DIAL_MODIFIED_TO_USSD"; - case RIL_E_DIAL_MODIFIED_TO_SS: return "E_DIAL_MODIFIED_TO_SS"; - case RIL_E_DIAL_MODIFIED_TO_DIAL: return "E_DIAL_MODIFIED_TO_DIAL"; - case RIL_E_USSD_MODIFIED_TO_DIAL: return "E_USSD_MODIFIED_TO_DIAL"; - case RIL_E_USSD_MODIFIED_TO_SS: return "E_USSD_MODIFIED_TO_SS"; - case RIL_E_USSD_MODIFIED_TO_USSD: return "E_USSD_MODIFIED_TO_USSD"; - case RIL_E_SS_MODIFIED_TO_DIAL: return "E_SS_MODIFIED_TO_DIAL"; - case RIL_E_SS_MODIFIED_TO_USSD: return "E_SS_MODIFIED_TO_USSD"; - case RIL_E_SUBSCRIPTION_NOT_SUPPORTED: return "E_SUBSCRIPTION_NOT_SUPPORTED"; - case RIL_E_SS_MODIFIED_TO_SS: return "E_SS_MODIFIED_TO_SS"; - case RIL_E_LCE_NOT_SUPPORTED: return "E_LCE_NOT_SUPPORTED"; - case RIL_E_NO_MEMORY: return "E_NO_MEMORY"; - case RIL_E_INTERNAL_ERR: return "E_INTERNAL_ERR"; - case RIL_E_SYSTEM_ERR: return "E_SYSTEM_ERR"; - case RIL_E_MODEM_ERR: return "E_MODEM_ERR"; - case RIL_E_INVALID_STATE: return "E_INVALID_STATE"; - case RIL_E_NO_RESOURCES: return "E_NO_RESOURCES"; - case RIL_E_SIM_ERR: return "E_SIM_ERR"; - case RIL_E_INVALID_ARGUMENTS: return "E_INVALID_ARGUMENTS"; - case RIL_E_INVALID_SIM_STATE: return "E_INVALID_SIM_STATE"; - case RIL_E_INVALID_MODEM_STATE: return "E_INVALID_MODEM_STATE"; - case RIL_E_INVALID_CALL_ID: return "E_INVALID_CALL_ID"; - case RIL_E_NO_SMS_TO_ACK: return "E_NO_SMS_TO_ACK"; - case RIL_E_NETWORK_ERR: return "E_NETWORK_ERR"; - case RIL_E_REQUEST_RATE_LIMITED: return "E_REQUEST_RATE_LIMITED"; - case RIL_E_SIM_BUSY: return "E_SIM_BUSY"; - case RIL_E_SIM_FULL: return "E_SIM_FULL"; - case RIL_E_NETWORK_REJECT: return "E_NETWORK_REJECT"; - case RIL_E_OPERATION_NOT_ALLOWED: return "E_OPERATION_NOT_ALLOWED"; - case RIL_E_EMPTY_RECORD: return "E_EMPTY_RECORD"; - case RIL_E_INVALID_SMS_FORMAT: return "E_INVALID_SMS_FORMAT"; - case RIL_E_ENCODING_ERR: return "E_ENCODING_ERR"; - case RIL_E_INVALID_SMSC_ADDRESS: return "E_INVALID_SMSC_ADDRESS"; - case RIL_E_NO_SUCH_ENTRY: return "E_NO_SUCH_ENTRY"; - case RIL_E_NETWORK_NOT_READY: return "E_NETWORK_NOT_READY"; - case RIL_E_NOT_PROVISIONED: return "E_NOT_PROVISIONED"; - case RIL_E_NO_SUBSCRIPTION: return "E_NO_SUBSCRIPTION"; - case RIL_E_NO_NETWORK_FOUND: return "E_NO_NETWORK_FOUND"; - case RIL_E_DEVICE_IN_USE: return "E_DEVICE_IN_USE"; - case RIL_E_ABORTED: return "E_ABORTED"; - case RIL_E_INVALID_RESPONSE: return "INVALID_RESPONSE"; - case RIL_E_OEM_ERROR_1: return "E_OEM_ERROR_1"; - case RIL_E_OEM_ERROR_2: return "E_OEM_ERROR_2"; - case RIL_E_OEM_ERROR_3: return "E_OEM_ERROR_3"; - case RIL_E_OEM_ERROR_4: return "E_OEM_ERROR_4"; - case RIL_E_OEM_ERROR_5: return "E_OEM_ERROR_5"; - case RIL_E_OEM_ERROR_6: return "E_OEM_ERROR_6"; - case RIL_E_OEM_ERROR_7: return "E_OEM_ERROR_7"; - case RIL_E_OEM_ERROR_8: return "E_OEM_ERROR_8"; - case RIL_E_OEM_ERROR_9: return "E_OEM_ERROR_9"; - case RIL_E_OEM_ERROR_10: return "E_OEM_ERROR_10"; - case RIL_E_OEM_ERROR_11: return "E_OEM_ERROR_11"; - case RIL_E_OEM_ERROR_12: return "E_OEM_ERROR_12"; - case RIL_E_OEM_ERROR_13: return "E_OEM_ERROR_13"; - case RIL_E_OEM_ERROR_14: return "E_OEM_ERROR_14"; - case RIL_E_OEM_ERROR_15: return "E_OEM_ERROR_15"; - case RIL_E_OEM_ERROR_16: return "E_OEM_ERROR_16"; - case RIL_E_OEM_ERROR_17: return "E_OEM_ERROR_17"; - case RIL_E_OEM_ERROR_18: return "E_OEM_ERROR_18"; - case RIL_E_OEM_ERROR_19: return "E_OEM_ERROR_19"; - case RIL_E_OEM_ERROR_20: return "E_OEM_ERROR_20"; - case RIL_E_OEM_ERROR_21: return "E_OEM_ERROR_21"; - case RIL_E_OEM_ERROR_22: return "E_OEM_ERROR_22"; - case RIL_E_OEM_ERROR_23: return "E_OEM_ERROR_23"; - case RIL_E_OEM_ERROR_24: return "E_OEM_ERROR_24"; - case RIL_E_OEM_ERROR_25: return "E_OEM_ERROR_25"; - default: return "<unknown error>"; - } -} - -const char * -radioStateToString(RIL_RadioState s) { - switch(s) { - case RADIO_STATE_OFF: return "RADIO_OFF"; - case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE"; - case RADIO_STATE_ON:return"RADIO_ON"; - default: return "<unknown state>"; - } -} - -const char * -callStateToString(RIL_CallState s) { - switch(s) { - case RIL_CALL_ACTIVE : return "ACTIVE"; - case RIL_CALL_HOLDING: return "HOLDING"; - case RIL_CALL_DIALING: return "DIALING"; - case RIL_CALL_ALERTING: return "ALERTING"; - case RIL_CALL_INCOMING: return "INCOMING"; - case RIL_CALL_WAITING: return "WAITING"; - default: return "<unknown state>"; - } -} - -const char * -requestToString(int request) { -/* - cat guest/hals/ril/libril/ril_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' - - - cat guest/hals/ril/libril/ril_unsol_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/' - -*/ - switch(request) { - case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS"; - case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN"; - case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK"; - case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2"; - case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2"; - case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN"; - case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2"; - case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION"; - case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS"; - case RIL_REQUEST_DIAL: return "DIAL"; - case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; - case RIL_REQUEST_HANGUP: return "HANGUP"; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND"; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND"; - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"; - case RIL_REQUEST_CONFERENCE: return "CONFERENCE"; - case RIL_REQUEST_UDUB: return "UDUB"; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE"; - case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH"; - case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE"; - case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE"; - case RIL_REQUEST_OPERATOR: return "OPERATOR"; - case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER"; - case RIL_REQUEST_DTMF: return "DTMF"; - case RIL_REQUEST_SEND_SMS: return "SEND_SMS"; - case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE"; - case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL"; - case RIL_REQUEST_SIM_IO: return "SIM_IO"; - case RIL_REQUEST_SEND_USSD: return "SEND_USSD"; - case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD"; - case RIL_REQUEST_GET_CLIR: return "GET_CLIR"; - case RIL_REQUEST_SET_CLIR: return "SET_CLIR"; - case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS"; - case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD"; - case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING"; - case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING"; - case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE"; - case RIL_REQUEST_GET_IMEI: return "GET_IMEI"; - case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV"; - case RIL_REQUEST_ANSWER: return "ANSWER"; - case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL"; - case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK"; - case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK"; - case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD"; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; - case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS: return "RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS"; - case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5: return "RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS5"; - case RIL_REQUEST_START_NETWORK_SCAN: return "RIL_REQUEST_START_NETWORK_SCAN"; - case RIL_REQUEST_START_NETWORK_SCAN4: return "RIL_REQUEST_START_NETWORK_SCAN4"; - case RIL_REQUEST_START_NETWORK_SCAN_1_5: return "RIL_REQUEST_START_NETWORK_SCAN5"; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: return "QUERY_AVAILABLE_NETWORKS"; - case RIL_REQUEST_DTMF_START: return "DTMF_START"; - case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; - case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; - case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; - case RIL_REQUEST_SET_MUTE: return "SET_MUTE"; - case RIL_REQUEST_GET_MUTE: return "GET_MUTE"; - case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP"; - case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE"; - case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST"; - case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO"; - case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW"; - case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS"; - case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; - case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; - case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; - case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; - case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; - case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; - case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE"; - case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE"; - case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND"; - case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE"; - case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; - case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER"; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS"; - case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES"; - case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "CDMA_SET_SUBSCRIPTION_SOURCE"; - case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "CDMA_SET_ROAMING_PREFERENCE"; - case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "CDMA_QUERY_ROAMING_PREFERENCE"; - case RIL_REQUEST_SET_TTY_MODE: return "SET_TTY_MODE"; - case RIL_REQUEST_QUERY_TTY_MODE: return "QUERY_TTY_MODE"; - case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; - case RIL_REQUEST_CDMA_FLASH: return "CDMA_FLASH"; - case RIL_REQUEST_CDMA_BURST_DTMF: return "CDMA_BURST_DTMF"; - case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "CDMA_VALIDATE_AND_WRITE_AKEY"; - case RIL_REQUEST_CDMA_SEND_SMS: return "CDMA_SEND_SMS"; - case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "CDMA_SMS_ACKNOWLEDGE"; - case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG: return "GSM_GET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG: return "GSM_SET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION: return "GSM_SMS_BROADCAST_ACTIVATION"; - case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG: return "CDMA_GET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG: return "CDMA_SET_BROADCAST_SMS_CONFIG"; - case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION: return "CDMA_SMS_BROADCAST_ACTIVATION"; - case RIL_REQUEST_CDMA_SUBSCRIPTION: return "CDMA_SUBSCRIPTION"; - case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM"; - case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM"; - case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY"; - case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE"; - case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS"; - case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS"; - case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS"; - case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING"; - case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE"; - case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION"; - case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; - case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "STK_SEND_ENVELOPE_WITH_STATUS"; - case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH"; - case RIL_REQUEST_GET_CELL_INFO_LIST: return "GET_CELL_INFO_LIST"; - case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return "SET_UNSOL_CELL_INFO_LIST_RATE"; - case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "SET_INITIAL_ATTACH_APN"; - case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE"; - case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS"; - case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC"; - case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL"; - case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL"; - case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL"; - case RIL_REQUEST_NV_READ_ITEM: return "NV_READ_ITEM"; - case RIL_REQUEST_NV_WRITE_ITEM: return "NV_WRITE_ITEM"; - case RIL_REQUEST_NV_WRITE_CDMA_PRL: return "NV_WRITE_CDMA_PRL"; - case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG"; - case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION"; - case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA"; - case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG"; - case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION"; - case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO"; - case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE"; - case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE"; - case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN"; - case RIL_REQUEST_GET_RADIO_CAPABILITY: return "GET_RADIO_CAPABILITY"; - case RIL_REQUEST_SET_RADIO_CAPABILITY: return "SET_RADIO_CAPABILITY"; - case RIL_REQUEST_START_LCE: return "START_LCE"; - case RIL_REQUEST_STOP_LCE: return "STOP_LCE"; - case RIL_REQUEST_PULL_LCEDATA: return "PULL_LCEDATA"; - case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO"; - case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS"; - case RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4: return "SET_CARRIER_RESTRICTIONS_1_4"; - case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS"; - case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4: return "GET_CARRIER_RESTRICTIONS_1_4"; - case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION: return "SET_CARRIER_INFO_IMSI_ENCRYPTION"; - case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5: return "SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5"; - case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT"; - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS"; - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; - case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; - case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; - case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; - case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; - case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; - case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; - case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; - case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; - case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; - case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; - case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; - case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; - case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; - case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; - case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; - case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED"; - case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; - case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING"; - case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; - case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; - case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; - case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE"; - case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; - case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED"; - case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED"; - case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE"; - case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; - case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; - case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; - case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED"; - case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED"; - case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY"; - case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "UNSOL_HARDWARE_CONFIG_CHANGED"; - case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED"; - case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY"; - case RIL_UNSOL_MODEM_RESTART: return "UNSOL_MODEM_RESTART"; - case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION: return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION"; - case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS"; - case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY"; - case RIL_UNSOL_LCEDATA_RECV: return "UNSOL_LCEDATA_RECV"; - case RIL_UNSOL_PCO_DATA: return "UNSOL_PCO_DATA"; - default: return "<unknown request>"; - } -} - -const char * -rilSocketIdToString(RIL_SOCKET_ID socket_id) -{ - switch(socket_id) { - case RIL_SOCKET_1: - return "RIL_SOCKET_1"; -#if (SIM_COUNT >= 2) - case RIL_SOCKET_2: - return "RIL_SOCKET_2"; -#endif -#if (SIM_COUNT >= 3) - case RIL_SOCKET_3: - return "RIL_SOCKET_3"; -#endif -#if (SIM_COUNT >= 4) - case RIL_SOCKET_4: - return "RIL_SOCKET_4"; -#endif - default: - return "not a valid RIL"; - } -} - -} /* namespace android */ diff --git a/guest/hals/ril/libril/ril.h b/guest/hals/ril/libril/ril.h deleted file mode 100644 index 80394ead..00000000 --- a/guest/hals/ril/libril/ril.h +++ /dev/null @@ -1,7762 +0,0 @@ -/* - * Copyright (C) 2006 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. - */ - -#ifndef ANDROID_RIL_H -#define ANDROID_RIL_H 1 - -#include <stdlib.h> -#include <stdint.h> -#include <telephony/ril_cdma_sms.h> -#include <telephony/ril_nv_items.h> -#include <telephony/ril_msim.h> - -#ifndef FEATURE_UNIT_TEST -#include <sys/time.h> -#endif /* !FEATURE_UNIT_TEST */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef SIM_COUNT -#if defined(ANDROID_SIM_COUNT_2) -#define SIM_COUNT 2 -#elif defined(ANDROID_SIM_COUNT_3) -#define SIM_COUNT 3 -#elif defined(ANDROID_SIM_COUNT_4) -#define SIM_COUNT 4 -#else -#define SIM_COUNT 1 -#endif - -#ifndef ANDROID_MULTI_SIM -#define SIM_COUNT 1 -#endif -#endif - -/* - * RIL version. - * Value of RIL_VERSION should not be changed in future. Here onwards, - * when a new change is supposed to be introduced which could involve new - * schemes added like Wakelocks, data structures added/updated, etc, we would - * just document RIL version associated with that change below. When OEM updates its - * RIL with those changes, they would return that new RIL version during RIL_REGISTER. - * We should make use of the returned version by vendor to identify appropriate scheme - * or data structure version to use. - * - * Documentation of RIL version and associated changes - * RIL_VERSION = 12 : This version corresponds to updated data structures namely - * RIL_Data_Call_Response_v11, RIL_SIM_IO_v6, RIL_CardStatus_v6, - * RIL_SimRefreshResponse_v7, RIL_CDMA_CallWaiting_v6, - * RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_CellIdentityGsm_v12 - * RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,RIL_CellInfoGsm_v12, - * RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12. - * - * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first - * strongly versioned version it enforces structure use. - * - * RIL_VERSION = 14 : New data structures are added, namely RIL_CarrierMatchType, - * RIL_Carrier, RIL_CarrierRestrictions and RIL_PCO_Data. - * New commands added: RIL_REQUEST_SET_CARRIER_RESTRICTIONS, - * RIL_REQUEST_SET_CARRIER_RESTRICTIONS and RIL_UNSOL_PCO_DATA. - * - * RIL_VERSION = 15 : New commands added: - * RIL_UNSOL_MODEM_RESTART, - * RIL_REQUEST_SEND_DEVICE_STATE, - * RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, - * RIL_REQUEST_SET_SIM_CARD_POWER, - * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, - * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION - * The new parameters for RIL_REQUEST_SETUP_DATA_CALL, - * Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15 - * New data structure RIL_DataRegistrationStateResponse, - * RIL_VoiceRegistrationStateResponse same is - * used in RIL_REQUEST_DATA_REGISTRATION_STATE and - * RIL_REQUEST_VOICE_REGISTRATION_STATE respectively. - * New data structure RIL_OpenChannelParams. - * RIL_REQUEST_START_NETWORK_SCAN - * RIL_REQUEST_STOP_NETWORK_SCAN - * RIL_UNSOL_NETWORK_SCAN_RESULT - * RIL_REQUEST_GET_MODEM_STACK_STATUS - * RIL_REQUEST_ENABLE_MODEM - * RIL_REQUEST_EMERGENCY_DIAL - * RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS - * RIL_REQUEST_ENABLE_UICC_APPLICATIONS - * RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED - * RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT - */ -#define RIL_VERSION 12 -#define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name -#define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ - -#define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 -#define CDMA_NUMBER_INFO_BUFFER_LENGTH 81 - -#define MAX_RILDS 3 -#define MAX_SERVICE_NAME_LENGTH 6 -#define MAX_CLIENT_ID_LENGTH 2 -#define MAX_DEBUG_SOCKET_NAME_LENGTH 12 -#define MAX_QEMU_PIPE_NAME_LENGTH 11 -#define MAX_UUID_LENGTH 64 -#define MAX_BANDS 8 -#define MAX_CHANNELS 32 -#define MAX_RADIO_ACCESS_NETWORKS 8 - - -typedef void * RIL_Token; - -typedef enum { - RIL_SOCKET_1, -#if (SIM_COUNT >= 2) - RIL_SOCKET_2, -#if (SIM_COUNT >= 3) - RIL_SOCKET_3, -#endif -#if (SIM_COUNT >= 4) - RIL_SOCKET_4, -#endif -#endif - RIL_SOCKET_NUM -} RIL_SOCKET_ID; - - -typedef enum { - RIL_E_SUCCESS = 0, - RIL_E_RADIO_NOT_AVAILABLE = 1, /* If radio did not start or is resetting */ - RIL_E_GENERIC_FAILURE = 2, - RIL_E_PASSWORD_INCORRECT = 3, /* for PIN/PIN2 methods only! */ - RIL_E_SIM_PIN2 = 4, /* Operation requires SIM PIN2 to be entered */ - RIL_E_SIM_PUK2 = 5, /* Operation requires SIM PIN2 to be entered */ - RIL_E_REQUEST_NOT_SUPPORTED = 6, - RIL_E_CANCELLED = 7, - RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, /* data ops are not allowed during voice - call on a Class C GPRS device */ - RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, /* data ops are not allowed before device - registers in network */ - RIL_E_SMS_SEND_FAIL_RETRY = 10, /* fail to send sms and need retry */ - RIL_E_SIM_ABSENT = 11, /* fail to set the location where CDMA subscription - shall be retrieved because of SIM or RUIM - card absent */ - RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12, /* fail to find CDMA subscription from specified - location */ - RIL_E_MODE_NOT_SUPPORTED = 13, /* HW does not support preferred network type */ - RIL_E_FDN_CHECK_FAILURE = 14, /* command failed because recipient is not on FDN list */ - RIL_E_ILLEGAL_SIM_OR_ME = 15, /* network selection failed due to - illegal SIM or ME */ - RIL_E_MISSING_RESOURCE = 16, /* no logical channel available */ - RIL_E_NO_SUCH_ELEMENT = 17, /* application not found on SIM */ - RIL_E_DIAL_MODIFIED_TO_USSD = 18, /* DIAL request modified to USSD */ - RIL_E_DIAL_MODIFIED_TO_SS = 19, /* DIAL request modified to SS */ - RIL_E_DIAL_MODIFIED_TO_DIAL = 20, /* DIAL request modified to DIAL with different - data */ - RIL_E_USSD_MODIFIED_TO_DIAL = 21, /* USSD request modified to DIAL */ - RIL_E_USSD_MODIFIED_TO_SS = 22, /* USSD request modified to SS */ - RIL_E_USSD_MODIFIED_TO_USSD = 23, /* USSD request modified to different USSD - request */ - RIL_E_SS_MODIFIED_TO_DIAL = 24, /* SS request modified to DIAL */ - RIL_E_SS_MODIFIED_TO_USSD = 25, /* SS request modified to USSD */ - RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26, /* Subscription not supported by RIL */ - RIL_E_SS_MODIFIED_TO_SS = 27, /* SS request modified to different SS request */ - RIL_E_LCE_NOT_SUPPORTED = 36, /* LCE service not supported(36 in RILConstants.java) */ - RIL_E_NO_MEMORY = 37, /* Not sufficient memory to process the request */ - RIL_E_INTERNAL_ERR = 38, /* Modem hit unexpected error scenario while handling - this request */ - RIL_E_SYSTEM_ERR = 39, /* Hit platform or system error */ - RIL_E_MODEM_ERR = 40, /* Vendor RIL got unexpected or incorrect response - from modem for this request */ - RIL_E_INVALID_STATE = 41, /* Unexpected request for the current state */ - RIL_E_NO_RESOURCES = 42, /* Not sufficient resource to process the request */ - RIL_E_SIM_ERR = 43, /* Received error from SIM card */ - RIL_E_INVALID_ARGUMENTS = 44, /* Received invalid arguments in request */ - RIL_E_INVALID_SIM_STATE = 45, /* Can not process the request in current SIM state */ - RIL_E_INVALID_MODEM_STATE = 46, /* Can not process the request in current Modem state */ - RIL_E_INVALID_CALL_ID = 47, /* Received invalid call id in request */ - RIL_E_NO_SMS_TO_ACK = 48, /* ACK received when there is no SMS to ack */ - RIL_E_NETWORK_ERR = 49, /* Received error from network */ - RIL_E_REQUEST_RATE_LIMITED = 50, /* Operation denied due to overly-frequent requests */ - RIL_E_SIM_BUSY = 51, /* SIM is busy */ - RIL_E_SIM_FULL = 52, /* The target EF is full */ - RIL_E_NETWORK_REJECT = 53, /* Request is rejected by network */ - RIL_E_OPERATION_NOT_ALLOWED = 54, /* Not allowed the request now */ - RIL_E_EMPTY_RECORD = 55, /* The request record is empty */ - RIL_E_INVALID_SMS_FORMAT = 56, /* Invalid sms format */ - RIL_E_ENCODING_ERR = 57, /* Message not encoded properly */ - RIL_E_INVALID_SMSC_ADDRESS = 58, /* SMSC address specified is invalid */ - RIL_E_NO_SUCH_ENTRY = 59, /* No such entry present to perform the request */ - RIL_E_NETWORK_NOT_READY = 60, /* Network is not ready to perform the request */ - RIL_E_NOT_PROVISIONED = 61, /* Device doesnot have this value provisioned */ - RIL_E_NO_SUBSCRIPTION = 62, /* Device doesnot have subscription */ - RIL_E_NO_NETWORK_FOUND = 63, /* Network cannot be found */ - RIL_E_DEVICE_IN_USE = 64, /* Operation cannot be performed because the device - is currently in use */ - RIL_E_ABORTED = 65, /* Operation aborted */ - RIL_E_INVALID_RESPONSE = 66, /* Invalid response sent by vendor code */ - // OEM specific error codes. To be used by OEM when they don't want to reveal - // specific error codes which would be replaced by Generic failure. - RIL_E_OEM_ERROR_1 = 501, - RIL_E_OEM_ERROR_2 = 502, - RIL_E_OEM_ERROR_3 = 503, - RIL_E_OEM_ERROR_4 = 504, - RIL_E_OEM_ERROR_5 = 505, - RIL_E_OEM_ERROR_6 = 506, - RIL_E_OEM_ERROR_7 = 507, - RIL_E_OEM_ERROR_8 = 508, - RIL_E_OEM_ERROR_9 = 509, - RIL_E_OEM_ERROR_10 = 510, - RIL_E_OEM_ERROR_11 = 511, - RIL_E_OEM_ERROR_12 = 512, - RIL_E_OEM_ERROR_13 = 513, - RIL_E_OEM_ERROR_14 = 514, - RIL_E_OEM_ERROR_15 = 515, - RIL_E_OEM_ERROR_16 = 516, - RIL_E_OEM_ERROR_17 = 517, - RIL_E_OEM_ERROR_18 = 518, - RIL_E_OEM_ERROR_19 = 519, - RIL_E_OEM_ERROR_20 = 520, - RIL_E_OEM_ERROR_21 = 521, - RIL_E_OEM_ERROR_22 = 522, - RIL_E_OEM_ERROR_23 = 523, - RIL_E_OEM_ERROR_24 = 524, - RIL_E_OEM_ERROR_25 = 525 -} RIL_Errno; - -typedef enum { - RIL_CALL_ACTIVE = 0, - RIL_CALL_HOLDING = 1, - RIL_CALL_DIALING = 2, /* MO call only */ - RIL_CALL_ALERTING = 3, /* MO call only */ - RIL_CALL_INCOMING = 4, /* MT call only */ - RIL_CALL_WAITING = 5 /* MT call only */ -} RIL_CallState; - -typedef enum { - RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */ - RADIO_STATE_UNAVAILABLE = 1, /* Radio unavailable (eg, resetting or not booted) */ - RADIO_STATE_ON = 10 /* Radio is on */ -} RIL_RadioState; - -typedef enum { - RADIO_TECH_UNKNOWN = 0, - RADIO_TECH_GPRS = 1, - RADIO_TECH_EDGE = 2, - RADIO_TECH_UMTS = 3, - RADIO_TECH_IS95A = 4, - RADIO_TECH_IS95B = 5, - RADIO_TECH_1xRTT = 6, - RADIO_TECH_EVDO_0 = 7, - RADIO_TECH_EVDO_A = 8, - RADIO_TECH_HSDPA = 9, - RADIO_TECH_HSUPA = 10, - RADIO_TECH_HSPA = 11, - RADIO_TECH_EVDO_B = 12, - RADIO_TECH_EHRPD = 13, - RADIO_TECH_LTE = 14, - RADIO_TECH_HSPAP = 15, // HSPA+ - RADIO_TECH_GSM = 16, // Only supports voice - RADIO_TECH_TD_SCDMA = 17, - RADIO_TECH_IWLAN = 18, - RADIO_TECH_LTE_CA = 19 -} RIL_RadioTechnology; - -typedef enum { - RAF_UNKNOWN = (1 << RADIO_TECH_UNKNOWN), - RAF_GPRS = (1 << RADIO_TECH_GPRS), - RAF_EDGE = (1 << RADIO_TECH_EDGE), - RAF_UMTS = (1 << RADIO_TECH_UMTS), - RAF_IS95A = (1 << RADIO_TECH_IS95A), - RAF_IS95B = (1 << RADIO_TECH_IS95B), - RAF_1xRTT = (1 << RADIO_TECH_1xRTT), - RAF_EVDO_0 = (1 << RADIO_TECH_EVDO_0), - RAF_EVDO_A = (1 << RADIO_TECH_EVDO_A), - RAF_HSDPA = (1 << RADIO_TECH_HSDPA), - RAF_HSUPA = (1 << RADIO_TECH_HSUPA), - RAF_HSPA = (1 << RADIO_TECH_HSPA), - RAF_EVDO_B = (1 << RADIO_TECH_EVDO_B), - RAF_EHRPD = (1 << RADIO_TECH_EHRPD), - RAF_LTE = (1 << RADIO_TECH_LTE), - RAF_HSPAP = (1 << RADIO_TECH_HSPAP), - RAF_GSM = (1 << RADIO_TECH_GSM), - RAF_TD_SCDMA = (1 << RADIO_TECH_TD_SCDMA), - RAF_LTE_CA = (1 << RADIO_TECH_LTE_CA) -} RIL_RadioAccessFamily; - -typedef enum { - BAND_MODE_UNSPECIFIED = 0, //"unspecified" (selected by baseband automatically) - BAND_MODE_EURO = 1, //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) - BAND_MODE_USA = 2, //"US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) - BAND_MODE_JPN = 3, //"JPN band" (WCDMA-800 / WCDMA-IMT-2000) - BAND_MODE_AUS = 4, //"AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) - BAND_MODE_AUS_2 = 5, //"AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) - BAND_MODE_CELL_800 = 6, //"Cellular" (800-MHz Band) - BAND_MODE_PCS = 7, //"PCS" (1900-MHz Band) - BAND_MODE_JTACS = 8, //"Band Class 3" (JTACS Band) - BAND_MODE_KOREA_PCS = 9, //"Band Class 4" (Korean PCS Band) - BAND_MODE_5_450M = 10, //"Band Class 5" (450-MHz Band) - BAND_MODE_IMT2000 = 11, //"Band Class 6" (2-GMHz IMT2000 Band) - BAND_MODE_7_700M_2 = 12, //"Band Class 7" (Upper 700-MHz Band) - BAND_MODE_8_1800M = 13, //"Band Class 8" (1800-MHz Band) - BAND_MODE_9_900M = 14, //"Band Class 9" (900-MHz Band) - BAND_MODE_10_800M_2 = 15, //"Band Class 10" (Secondary 800-MHz Band) - BAND_MODE_EURO_PAMR_400M = 16, //"Band Class 11" (400-MHz European PAMR Band) - BAND_MODE_AWS = 17, //"Band Class 15" (AWS Band) - BAND_MODE_USA_2500M = 18 //"Band Class 16" (US 2.5-GHz Band) -} RIL_RadioBandMode; - -typedef enum { - RC_PHASE_CONFIGURED = 0, // LM is configured is initial value and value after FINISH completes - RC_PHASE_START = 1, // START is sent before Apply and indicates that an APPLY will be - // forthcoming with these same parameters - RC_PHASE_APPLY = 2, // APPLY is sent after all LM's receive START and returned - // RIL_RadioCapability.status = 0, if any START's fail no - // APPLY will be sent - RC_PHASE_UNSOL_RSP = 3, // UNSOL_RSP is sent with RIL_UNSOL_RADIO_CAPABILITY - RC_PHASE_FINISH = 4 // FINISH is sent after all commands have completed. If an error - // occurs in any previous command the RIL_RadioAccessesFamily and - // logicalModemUuid fields will be the prior configuration thus - // restoring the configuration to the previous value. An error - // returned by this command will generally be ignored or may - // cause that logical modem to be removed from service. -} RadioCapabilityPhase; - -typedef enum { - RC_STATUS_NONE = 0, // This parameter has no meaning with RC_PHASE_START, - // RC_PHASE_APPLY - RC_STATUS_SUCCESS = 1, // Tell modem the action transaction of set radio - // capability was success with RC_PHASE_FINISH - RC_STATUS_FAIL = 2, // Tell modem the action transaction of set radio - // capability is fail with RC_PHASE_FINISH. -} RadioCapabilityStatus; - -#define RIL_RADIO_CAPABILITY_VERSION 1 -typedef struct { - int version; // Version of structure, RIL_RADIO_CAPABILITY_VERSION - int session; // Unique session value defined by framework returned in all "responses/unsol" - int phase; // CONFIGURED, START, APPLY, FINISH - int rat; // RIL_RadioAccessFamily for the radio - char logicalModemUuid[MAX_UUID_LENGTH]; // A UUID typically "com.xxxx.lmX where X is the logical modem. - int status; // Return status and an input parameter for RC_PHASE_FINISH -} RIL_RadioCapability; - -// Do we want to split Data from Voice and the use -// RIL_RadioTechnology for get/setPreferredVoice/Data ? -typedef enum { - PREF_NET_TYPE_GSM_WCDMA = 0, /* GSM/WCDMA (WCDMA preferred) */ - PREF_NET_TYPE_GSM_ONLY = 1, /* GSM only */ - PREF_NET_TYPE_WCDMA = 2, /* WCDMA */ - PREF_NET_TYPE_GSM_WCDMA_AUTO = 3, /* GSM/WCDMA (auto mode, according to PRL) */ - PREF_NET_TYPE_CDMA_EVDO_AUTO = 4, /* CDMA and EvDo (auto mode, according to PRL) */ - PREF_NET_TYPE_CDMA_ONLY = 5, /* CDMA only */ - PREF_NET_TYPE_EVDO_ONLY = 6, /* EvDo only */ - PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7, /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) */ - PREF_NET_TYPE_LTE_CDMA_EVDO = 8, /* LTE, CDMA and EvDo */ - PREF_NET_TYPE_LTE_GSM_WCDMA = 9, /* LTE, GSM/WCDMA */ - PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */ - PREF_NET_TYPE_LTE_ONLY = 11, /* LTE only */ - PREF_NET_TYPE_LTE_WCDMA = 12, /* LTE/WCDMA */ - PREF_NET_TYPE_TD_SCDMA_ONLY = 13, /* TD-SCDMA only */ - PREF_NET_TYPE_TD_SCDMA_WCDMA = 14, /* TD-SCDMA and WCDMA */ - PREF_NET_TYPE_TD_SCDMA_LTE = 15, /* TD-SCDMA and LTE */ - PREF_NET_TYPE_TD_SCDMA_GSM = 16, /* TD-SCDMA and GSM */ - PREF_NET_TYPE_TD_SCDMA_GSM_LTE = 17, /* TD-SCDMA,GSM and LTE */ - PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA = 18, /* TD-SCDMA, GSM/WCDMA */ - PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE = 19, /* TD-SCDMA, WCDMA and LTE */ - PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE = 20, /* TD-SCDMA, GSM/WCDMA and LTE */ - PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO = 21, /* TD-SCDMA, GSM/WCDMA, CDMA and EvDo */ - PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22 /* TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA */ -} RIL_PreferredNetworkType; - -/* Source for cdma subscription */ -typedef enum { - CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM = 0, - CDMA_SUBSCRIPTION_SOURCE_NV = 1 -} RIL_CdmaSubscriptionSource; - -/* User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 */ -typedef enum { - RIL_UUS_TYPE1_IMPLICIT = 0, - RIL_UUS_TYPE1_REQUIRED = 1, - RIL_UUS_TYPE1_NOT_REQUIRED = 2, - RIL_UUS_TYPE2_REQUIRED = 3, - RIL_UUS_TYPE2_NOT_REQUIRED = 4, - RIL_UUS_TYPE3_REQUIRED = 5, - RIL_UUS_TYPE3_NOT_REQUIRED = 6 -} RIL_UUS_Type; - -/* User-to-User Signaling Information data coding schemes. Possible values for - * Octet 3 (Protocol Discriminator field) in the UUIE. The values have been - * specified in section 10.5.4.25 of 3GPP TS 24.008 */ -typedef enum { - RIL_UUS_DCS_USP = 0, /* User specified protocol */ - RIL_UUS_DCS_OSIHLP = 1, /* OSI higher layer protocol */ - RIL_UUS_DCS_X244 = 2, /* X.244 */ - RIL_UUS_DCS_RMCF = 3, /* Reserved for system mangement - convergence function */ - RIL_UUS_DCS_IA5c = 4 /* IA5 characters */ -} RIL_UUS_DCS; - -/* User-to-User Signaling Information defined in 3GPP 23.087 v8.0 - * This data is passed in RIL_ExtensionRecord and rec contains this - * structure when type is RIL_UUS_INFO_EXT_REC */ -typedef struct { - RIL_UUS_Type uusType; /* UUS Type */ - RIL_UUS_DCS uusDcs; /* UUS Data Coding Scheme */ - int uusLength; /* Length of UUS Data */ - char * uusData; /* UUS Data */ -} RIL_UUS_Info; - -/* CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 */ -typedef struct { - char isPresent; /* non-zero if signal information record is present */ - char signalType; /* as defined 3.7.5.5-1 */ - char alertPitch; /* as defined 3.7.5.5-2 */ - char signal; /* as defined 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 */ -} RIL_CDMA_SignalInfoRecord; - -typedef struct { - RIL_CallState state; - int index; /* Connection Index for use with, eg, AT+CHLD */ - int toa; /* type of address, eg 145 = intl */ - char isMpty; /* nonzero if is mpty call */ - char isMT; /* nonzero if call is mobile terminated */ - char als; /* ALS line indicator if available - (0 = line 1) */ - char isVoice; /* nonzero if this is is a voice call */ - char isVoicePrivacy; /* nonzero if CDMA voice privacy mode is active */ - char * number; /* Remote party number */ - int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ - char * name; /* Remote party name */ - int namePresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ - RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ -} RIL_Call; - -/* Deprecated, use RIL_Data_Call_Response_v6 */ -typedef struct { - int cid; /* Context ID, uniquely identifies this call */ - int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ - char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. - For example, "IP", "IPV6", "IPV4V6", or "PPP". */ - char * apn; /* ignored */ - char * address; /* An address, e.g., "192.0.1.3" or "2001:db8::1". */ -} RIL_Data_Call_Response_v4; - -/* - * Returned by RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_DATA_CALL_LIST - * and RIL_UNSOL_DATA_CALL_LIST_CHANGED, on error status != 0. - */ -typedef struct { - int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ - int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry - back-off timer value RIL wants to override the one - pre-configured in FW. - The unit is miliseconds. - The value < 0 means no value is suggested. - The value 0 means retry should be done ASAP. - The value of INT_MAX(0x7fffffff) means no retry. */ - int cid; /* Context ID, uniquely identifies this call */ - int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ - char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. - For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is - PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported - such as "IP" or "IPV6" */ - char * ifname; /* The network interface name */ - char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, - e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". - May not be empty, typically 1 IPv4 or 1 IPv6 or - one of each. If the prefix length is absent the addresses - are assumed to be point to point with IPv4 having a prefix - length of 32 and IPv6 128. */ - char * dnses; /* A space-delimited list of DNS server addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty. */ - char * gateways; /* A space-delimited list of default gateway addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty in which case the addresses represent point - to point connections. */ -} RIL_Data_Call_Response_v6; - -typedef struct { - int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ - int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry - back-off timer value RIL wants to override the one - pre-configured in FW. - The unit is miliseconds. - The value < 0 means no value is suggested. - The value 0 means retry should be done ASAP. - The value of INT_MAX(0x7fffffff) means no retry. */ - int cid; /* Context ID, uniquely identifies this call */ - int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ - char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. - For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is - PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported - such as "IP" or "IPV6" */ - char * ifname; /* The network interface name */ - char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, - e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". - May not be empty, typically 1 IPv4 or 1 IPv6 or - one of each. If the prefix length is absent the addresses - are assumed to be point to point with IPv4 having a prefix - length of 32 and IPv6 128. */ - char * dnses; /* A space-delimited list of DNS server addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty. */ - char * gateways; /* A space-delimited list of default gateway addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty in which case the addresses represent point - to point connections. */ - char * pcscf; /* the Proxy Call State Control Function address - via PCO(Protocol Configuration Option) for IMS client. */ -} RIL_Data_Call_Response_v9; - -typedef struct { - int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ - int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry - back-off timer value RIL wants to override the one - pre-configured in FW. - The unit is miliseconds. - The value < 0 means no value is suggested. - The value 0 means retry should be done ASAP. - The value of INT_MAX(0x7fffffff) means no retry. */ - int cid; /* Context ID, uniquely identifies this call */ - int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ - char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. - For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is - PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported - such as "IP" or "IPV6" */ - char * ifname; /* The network interface name */ - char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, - e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". - May not be empty, typically 1 IPv4 or 1 IPv6 or - one of each. If the prefix length is absent the addresses - are assumed to be point to point with IPv4 having a prefix - length of 32 and IPv6 128. */ - char * dnses; /* A space-delimited list of DNS server addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty. */ - char * gateways; /* A space-delimited list of default gateway addresses, - e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". - May be empty in which case the addresses represent point - to point connections. */ - char * pcscf; /* the Proxy Call State Control Function address - via PCO(Protocol Configuration Option) for IMS client. */ - int mtu; /* MTU received from network - Value <= 0 means network has either not sent a value or - sent an invalid value */ -} RIL_Data_Call_Response_v11; - -typedef enum { - RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */ - RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */ -} RIL_RadioTechnologyFamily; - -typedef struct { - RIL_RadioTechnologyFamily tech; - unsigned char retry; /* 0 == not retry, nonzero == retry */ - int messageRef; /* Valid field if retry is set to nonzero. - Contains messageRef from RIL_SMS_Response - corresponding to failed MO SMS. - */ - - union { - /* Valid field if tech is RADIO_TECH_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */ - RIL_CDMA_SMS_Message* cdmaMessage; - - /* Valid field if tech is RADIO_TECH_3GPP. See RIL_REQUEST_SEND_SMS */ - char** gsmMessage; /* This is an array of pointers where pointers - are contiguous but elements pointed by those pointers - are not contiguous - */ - } message; -} RIL_IMS_SMS_Message; - -typedef struct { - int messageRef; /* TP-Message-Reference for GSM, - and BearerData MessageId for CDMA - (See 3GPP2 C.S0015-B, v2.0, table 4.5-1). */ - char *ackPDU; /* or NULL if n/a */ - int errorCode; /* See 3GPP 27.005, 3.2.5 for GSM/UMTS, - 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, - -1 if unknown or not applicable*/ -} RIL_SMS_Response; - -/** Used by RIL_REQUEST_WRITE_SMS_TO_SIM */ -typedef struct { - int status; /* Status of message. See TS 27.005 3.1, "<stat>": */ - /* 0 = "REC UNREAD" */ - /* 1 = "REC READ" */ - /* 2 = "STO UNSENT" */ - /* 3 = "STO SENT" */ - char * pdu; /* PDU of message to write, as an ASCII hex string less the SMSC address, - the TP-layer length is "strlen(pdu)/2". */ - char * smsc; /* SMSC address in GSM BCD format prefixed by a length byte - (as expected by TS 27.005) or NULL for default SMSC */ -} RIL_SMS_WriteArgs; - -/** Used by RIL_REQUEST_DIAL */ -typedef struct { - char * address; - int clir; - /* (same as 'n' paremeter in TS 27.007 7.7 "+CLIR" - * clir == 0 on "use subscription default value" - * clir == 1 on "CLIR invocation" (restrict CLI presentation) - * clir == 2 on "CLIR suppression" (allow CLI presentation) - */ - RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ -} RIL_Dial; - -typedef struct { - int command; /* one of the commands listed for TS 27.007 +CRSM*/ - int fileid; /* EF id */ - char *path; /* "pathid" from TS 27.007 +CRSM command. - Path is in hex asciii format eg "7f205f70" - Path must always be provided. - */ - int p1; - int p2; - int p3; - char *data; /* May be NULL*/ - char *pin2; /* May be NULL*/ -} RIL_SIM_IO_v5; - -typedef struct { - int command; /* one of the commands listed for TS 27.007 +CRSM*/ - int fileid; /* EF id */ - char *path; /* "pathid" from TS 27.007 +CRSM command. - Path is in hex asciii format eg "7f205f70" - Path must always be provided. - */ - int p1; - int p2; - int p3; - char *data; /* May be NULL*/ - char *pin2; /* May be NULL*/ - char *aidPtr; /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */ -} RIL_SIM_IO_v6; - -/* Used by RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL and - * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC. */ -typedef struct { - int sessionid; /* "sessionid" from TS 27.007 +CGLA command. Should be - ignored for +CSIM command. */ - - /* Following fields are used to derive the APDU ("command" and "length" - values in TS 27.007 +CSIM and +CGLA commands). */ - int cla; - int instruction; - int p1; - int p2; - int p3; /* A negative P3 implies a 4 byte APDU. */ - char *data; /* May be NULL. In hex string format. */ -} RIL_SIM_APDU; - -typedef struct { - int sw1; - int sw2; - char *simResponse; /* In hex string format ([a-fA-F0-9]*), except for SIM_AUTHENTICATION - response for which it is in Base64 format, see 3GPP TS 31.102 7.1.2 */ -} RIL_SIM_IO_Response; - -/* See also com.android.internal.telephony.gsm.CallForwardInfo */ - -typedef struct { - int status; /* - * For RIL_REQUEST_QUERY_CALL_FORWARD_STATUS - * status 1 = active, 0 = not active - * - * For RIL_REQUEST_SET_CALL_FORWARD: - * status is: - * 0 = disable - * 1 = enable - * 2 = interrogate - * 3 = registeration - * 4 = erasure - */ - - int reason; /* from TS 27.007 7.11 "reason" */ - int serviceClass;/* From 27.007 +CCFC/+CLCK "class" - See table for Android mapping from - MMI service code - 0 means user doesn't input class */ - int toa; /* "type" from TS 27.007 7.11 */ - char * number; /* "number" from TS 27.007 7.11. May be NULL */ - int timeSeconds; /* for CF no reply only */ -}RIL_CallForwardInfo; - -typedef struct { - char * cid; /* Combination of LAC and Cell Id in 32 bits in GSM. - * Upper 16 bits is LAC and lower 16 bits - * is CID (as described in TS 27.005) - * Primary Scrambling Code (as described in TS 25.331) - * in 9 bits in UMTS - * Valid values are hexadecimal 0x0000 - 0xffffffff. - */ - int rssi; /* Received RSSI in GSM, - * Level index of CPICH Received Signal Code Power in UMTS - */ -} RIL_NeighboringCell; - -typedef struct { - char lce_status; /* LCE service status: - * -1 = not supported; - * 0 = stopped; - * 1 = active. - */ - unsigned int actual_interval_ms; /* actual LCE reporting interval, - * meaningful only if LCEStatus = 1. - */ -} RIL_LceStatusInfo; - -typedef struct { - unsigned int last_hop_capacity_kbps; /* last-hop cellular capacity: kilobits/second. */ - unsigned char confidence_level; /* capacity estimate confidence: 0-100 */ - unsigned char lce_suspended; /* LCE report going to be suspended? (e.g., radio - * moves to inactive state or network type change) - * 1 = suspended; - * 0 = not suspended. - */ -} RIL_LceDataInfo; - -typedef enum { - RIL_MATCH_ALL = 0, /* Apply to all carriers with the same mcc/mnc */ - RIL_MATCH_SPN = 1, /* Use SPN and mcc/mnc to identify the carrier */ - RIL_MATCH_IMSI_PREFIX = 2, /* Use IMSI prefix and mcc/mnc to identify the carrier */ - RIL_MATCH_GID1 = 3, /* Use GID1 and mcc/mnc to identify the carrier */ - RIL_MATCH_GID2 = 4, /* Use GID2 and mcc/mnc to identify the carrier */ -} RIL_CarrierMatchType; - -typedef struct { - const char * mcc; - const char * mnc; - RIL_CarrierMatchType match_type; /* Specify match type for the carrier. - * If it’s RIL_MATCH_ALL, match_data is null; - * otherwise, match_data is the value for the match type. - */ - const char * match_data; -} RIL_Carrier; - -typedef struct { - int32_t len_allowed_carriers; /* length of array allowed_carriers */ - int32_t len_excluded_carriers; /* length of array excluded_carriers */ - RIL_Carrier * allowed_carriers; /* whitelist for allowed carriers */ - RIL_Carrier * excluded_carriers; /* blacklist for explicitly excluded carriers - * which match allowed_carriers. Eg. allowed_carriers match - * mcc/mnc, excluded_carriers has same mcc/mnc and gid1 - * is ABCD. It means except the carrier whose gid1 is ABCD, - * all carriers with the same mcc/mnc are allowed. - */ -} RIL_CarrierRestrictions; - -typedef enum { - NO_MULTISIM_POLICY = 0, /* configuration applies to each slot independently. */ - ONE_VALID_SIM_MUST_BE_PRESENT = 1, /* Any SIM card can be used as far as one valid card is - * present in the device. - */ -} RIL_SimLockMultiSimPolicy; - -typedef struct { - int32_t len_allowed_carriers; /* length of array allowed_carriers */ - int32_t len_excluded_carriers; /* length of array excluded_carriers */ - RIL_Carrier * allowed_carriers; /* whitelist for allowed carriers */ - RIL_Carrier * excluded_carriers; /* blacklist for explicitly excluded carriers - * which match allowed_carriers. Eg. allowed_carriers match - * mcc/mnc, excluded_carriers has same mcc/mnc and gid1 - * is ABCD. It means except the carrier whose gid1 is ABCD, - * all carriers with the same mcc/mnc are allowed. - */ - int allowedCarriersPrioritized; /* allowed list prioritized */ - RIL_SimLockMultiSimPolicy multiSimPolicy; /* multisim policy */ -} RIL_CarrierRestrictionsWithPriority; - -typedef struct { - char * mcc; /* MCC of the Carrier. */ - char * mnc ; /* MNC of the Carrier. */ - uint8_t * carrierKey; /* Public Key from the Carrier used to encrypt the - * IMSI/IMPI. - */ - int32_t carrierKeyLength; /* Length of the Public Key. */ - char * keyIdentifier; /* The keyIdentifier Attribute value pair that helps - * a server locate the private key to decrypt the - * permanent identity. - */ - int64_t expirationTime; /* Date-Time (in UTC) when the key will expire. */ - -} RIL_CarrierInfoForImsiEncryption; - -/* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */ -typedef enum { - CALL_FAIL_UNOBTAINABLE_NUMBER = 1, - CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3, - CALL_FAIL_CHANNEL_UNACCEPTABLE = 6, - CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8, - CALL_FAIL_NORMAL = 16, - CALL_FAIL_BUSY = 17, - CALL_FAIL_NO_USER_RESPONDING = 18, - CALL_FAIL_NO_ANSWER_FROM_USER = 19, - CALL_FAIL_CALL_REJECTED = 21, - CALL_FAIL_NUMBER_CHANGED = 22, - CALL_FAIL_PREEMPTION = 25, - CALL_FAIL_DESTINATION_OUT_OF_ORDER = 27, - CALL_FAIL_INVALID_NUMBER_FORMAT = 28, - CALL_FAIL_FACILITY_REJECTED = 29, - CALL_FAIL_RESP_TO_STATUS_ENQUIRY = 30, - CALL_FAIL_NORMAL_UNSPECIFIED = 31, - CALL_FAIL_CONGESTION = 34, - CALL_FAIL_NETWORK_OUT_OF_ORDER = 38, - CALL_FAIL_TEMPORARY_FAILURE = 41, - CALL_FAIL_SWITCHING_EQUIPMENT_CONGESTION = 42, - CALL_FAIL_ACCESS_INFORMATION_DISCARDED = 43, - CALL_FAIL_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44, - CALL_FAIL_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47, - CALL_FAIL_QOS_UNAVAILABLE = 49, - CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50, - CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55, - CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57, - CALL_FAIL_BEARER_CAPABILITY_UNAVAILABLE = 58, - CALL_FAIL_SERVICE_OPTION_NOT_AVAILABLE = 63, - CALL_FAIL_BEARER_SERVICE_NOT_IMPLEMENTED = 65, - CALL_FAIL_ACM_LIMIT_EXCEEDED = 68, - CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69, - CALL_FAIL_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70, - CALL_FAIL_SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79, - CALL_FAIL_INVALID_TRANSACTION_IDENTIFIER = 81, - CALL_FAIL_USER_NOT_MEMBER_OF_CUG = 87, - CALL_FAIL_INCOMPATIBLE_DESTINATION = 88, - CALL_FAIL_INVALID_TRANSIT_NW_SELECTION = 91, - CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95, - CALL_FAIL_INVALID_MANDATORY_INFORMATION = 96, - CALL_FAIL_MESSAGE_TYPE_NON_IMPLEMENTED = 97, - CALL_FAIL_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, - CALL_FAIL_INFORMATION_ELEMENT_NON_EXISTENT = 99, - CALL_FAIL_CONDITIONAL_IE_ERROR = 100, - CALL_FAIL_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, - CALL_FAIL_RECOVERY_ON_TIMER_EXPIRED = 102, - CALL_FAIL_PROTOCOL_ERROR_UNSPECIFIED = 111, - CALL_FAIL_INTERWORKING_UNSPECIFIED = 127, - CALL_FAIL_CALL_BARRED = 240, - CALL_FAIL_FDN_BLOCKED = 241, - CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242, - CALL_FAIL_IMEI_NOT_ACCEPTED = 243, - CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244, /* STK Call Control */ - CALL_FAIL_DIAL_MODIFIED_TO_SS = 245, - CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246, - CALL_FAIL_RADIO_OFF = 247, /* Radio is OFF */ - CALL_FAIL_OUT_OF_SERVICE = 248, /* No cellular coverage */ - CALL_FAIL_NO_VALID_SIM = 249, /* No valid SIM is present */ - CALL_FAIL_RADIO_INTERNAL_ERROR = 250, /* Internal error at Modem */ - CALL_FAIL_NETWORK_RESP_TIMEOUT = 251, /* No response from network */ - CALL_FAIL_NETWORK_REJECT = 252, /* Explicit network reject */ - CALL_FAIL_RADIO_ACCESS_FAILURE = 253, /* RRC connection failure. Eg.RACH */ - CALL_FAIL_RADIO_LINK_FAILURE = 254, /* Radio Link Failure */ - CALL_FAIL_RADIO_LINK_LOST = 255, /* Radio link lost due to poor coverage */ - CALL_FAIL_RADIO_UPLINK_FAILURE = 256, /* Radio uplink failure */ - CALL_FAIL_RADIO_SETUP_FAILURE = 257, /* RRC connection setup failure */ - CALL_FAIL_RADIO_RELEASE_NORMAL = 258, /* RRC connection release, normal */ - CALL_FAIL_RADIO_RELEASE_ABNORMAL = 259, /* RRC connection release, abnormal */ - CALL_FAIL_ACCESS_CLASS_BLOCKED = 260, /* Access class barring */ - CALL_FAIL_NETWORK_DETACH = 261, /* Explicit network detach */ - CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, - CALL_FAIL_CDMA_DROP = 1001, - CALL_FAIL_CDMA_INTERCEPT = 1002, - CALL_FAIL_CDMA_REORDER = 1003, - CALL_FAIL_CDMA_SO_REJECT = 1004, - CALL_FAIL_CDMA_RETRY_ORDER = 1005, - CALL_FAIL_CDMA_ACCESS_FAILURE = 1006, - CALL_FAIL_CDMA_PREEMPTED = 1007, - CALL_FAIL_CDMA_NOT_EMERGENCY = 1008, /* For non-emergency number dialed - during emergency callback mode */ - CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009, /* CDMA network access probes blocked */ - - /* OEM specific error codes. Used to distinguish error from - * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging */ - CALL_FAIL_OEM_CAUSE_1 = 0xf001, - CALL_FAIL_OEM_CAUSE_2 = 0xf002, - CALL_FAIL_OEM_CAUSE_3 = 0xf003, - CALL_FAIL_OEM_CAUSE_4 = 0xf004, - CALL_FAIL_OEM_CAUSE_5 = 0xf005, - CALL_FAIL_OEM_CAUSE_6 = 0xf006, - CALL_FAIL_OEM_CAUSE_7 = 0xf007, - CALL_FAIL_OEM_CAUSE_8 = 0xf008, - CALL_FAIL_OEM_CAUSE_9 = 0xf009, - CALL_FAIL_OEM_CAUSE_10 = 0xf00a, - CALL_FAIL_OEM_CAUSE_11 = 0xf00b, - CALL_FAIL_OEM_CAUSE_12 = 0xf00c, - CALL_FAIL_OEM_CAUSE_13 = 0xf00d, - CALL_FAIL_OEM_CAUSE_14 = 0xf00e, - CALL_FAIL_OEM_CAUSE_15 = 0xf00f, - - CALL_FAIL_ERROR_UNSPECIFIED = 0xffff /* This error will be deprecated soon, - vendor code should make sure to map error - code to specific error */ -} RIL_LastCallFailCause; - -typedef struct { - RIL_LastCallFailCause cause_code; - char * vendor_cause; -} RIL_LastCallFailCauseInfo; - -/* See RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */ -typedef enum { - PDP_FAIL_NONE = 0, /* No error, connection ok */ - - /* an integer cause code defined in TS 24.008 - section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B. - If the implementation does not have access to the exact cause codes, - then it should return one of the following values, - as the UI layer needs to distinguish these - cases for error notification and potential retries. */ - PDP_FAIL_OPERATOR_BARRED = 0x08, /* no retry */ - PDP_FAIL_NAS_SIGNALLING = 0x0E, - PDP_FAIL_LLC_SNDCP = 0x19, - PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A, - PDP_FAIL_MISSING_UKNOWN_APN = 0x1B, /* no retry */ - PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C, /* no retry */ - PDP_FAIL_USER_AUTHENTICATION = 0x1D, /* no retry */ - PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E, /* no retry */ - PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F, - PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20, /* no retry */ - PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */ - PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22, - PDP_FAIL_NSAPI_IN_USE = 0x23, /* no retry */ - PDP_FAIL_REGULAR_DEACTIVATION = 0x24, /* possibly restart radio, - based on framework config */ - PDP_FAIL_QOS_NOT_ACCEPTED = 0x25, - PDP_FAIL_NETWORK_FAILURE = 0x26, - PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27, - PDP_FAIL_FEATURE_NOT_SUPP = 0x28, - PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29, - PDP_FAIL_TFT_SYTAX_ERROR = 0x2A, - PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B, - PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C, - PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D, - PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E, - PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32, /* no retry */ - PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33, /* no retry */ - PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34, - PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35, - PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36, - PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37, - PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41, - PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42, - PDP_FAIL_INVALID_TRANSACTION_ID = 0x51, - PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F, - PDP_FAIL_INVALID_MANDATORY_INFO = 0x60, - PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61, - PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62, - PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63, - PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64, - PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65, - PDP_FAIL_PROTOCOL_ERRORS = 0x6F, /* no retry */ - PDP_FAIL_APN_TYPE_CONFLICT = 0x70, - PDP_FAIL_INVALID_PCSCF_ADDR = 0x71, - PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72, - PDP_FAIL_EMM_ACCESS_BARRED = 0x73, - PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74, - PDP_FAIL_IFACE_MISMATCH = 0x75, - PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76, - PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77, - PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78, - PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79, - PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A, - - // OEM specific error codes. To be used by OEMs when they don't want to - // reveal error code which would be replaced by PDP_FAIL_ERROR_UNSPECIFIED - PDP_FAIL_OEM_DCFAILCAUSE_1 = 0x1001, - PDP_FAIL_OEM_DCFAILCAUSE_2 = 0x1002, - PDP_FAIL_OEM_DCFAILCAUSE_3 = 0x1003, - PDP_FAIL_OEM_DCFAILCAUSE_4 = 0x1004, - PDP_FAIL_OEM_DCFAILCAUSE_5 = 0x1005, - PDP_FAIL_OEM_DCFAILCAUSE_6 = 0x1006, - PDP_FAIL_OEM_DCFAILCAUSE_7 = 0x1007, - PDP_FAIL_OEM_DCFAILCAUSE_8 = 0x1008, - PDP_FAIL_OEM_DCFAILCAUSE_9 = 0x1009, - PDP_FAIL_OEM_DCFAILCAUSE_10 = 0x100A, - PDP_FAIL_OEM_DCFAILCAUSE_11 = 0x100B, - PDP_FAIL_OEM_DCFAILCAUSE_12 = 0x100C, - PDP_FAIL_OEM_DCFAILCAUSE_13 = 0x100D, - PDP_FAIL_OEM_DCFAILCAUSE_14 = 0x100E, - PDP_FAIL_OEM_DCFAILCAUSE_15 = 0x100F, - - /* Not mentioned in the specification */ - PDP_FAIL_VOICE_REGISTRATION_FAIL = -1, - PDP_FAIL_DATA_REGISTRATION_FAIL = -2, - - /* reasons for data call drop - network/modem disconnect */ - PDP_FAIL_SIGNAL_LOST = -3, - PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry - with parameters appropriate for new technology */ - PDP_FAIL_RADIO_POWER_OFF = -5, /* data call was disconnected because radio was resetting, - powered off - no retry */ - PDP_FAIL_TETHERED_CALL_ACTIVE = -6, /* data call was disconnected by modem because tethered - mode was up on same APN/data profile - no retry until - tethered call is off */ - - PDP_FAIL_ERROR_UNSPECIFIED = 0xffff, /* retry silently. Will be deprecated soon as - new error codes are added making this unnecessary */ -} RIL_DataCallFailCause; - -/* See RIL_REQUEST_SETUP_DATA_CALL */ -typedef enum { - RIL_DATA_PROFILE_DEFAULT = 0, - RIL_DATA_PROFILE_TETHERED = 1, - RIL_DATA_PROFILE_IMS = 2, - RIL_DATA_PROFILE_FOTA = 3, - RIL_DATA_PROFILE_CBS = 4, - RIL_DATA_PROFILE_OEM_BASE = 1000, /* Start of OEM-specific profiles */ - RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF -} RIL_DataProfile; - -/* Used by RIL_UNSOL_SUPP_SVC_NOTIFICATION */ -typedef struct { - int notificationType; /* - * 0 = MO intermediate result code - * 1 = MT unsolicited result code - */ - int code; /* See 27.007 7.17 - "code1" for MO - "code2" for MT. */ - int index; /* CUG index. See 27.007 7.17. */ - int type; /* "type" from 27.007 7.17 (MT only). */ - char * number; /* "number" from 27.007 7.17 - (MT only, may be NULL). */ -} RIL_SuppSvcNotification; - -#define RIL_CARD_MAX_APPS 8 - -typedef enum { - RIL_CARDSTATE_ABSENT = 0, - RIL_CARDSTATE_PRESENT = 1, - RIL_CARDSTATE_ERROR = 2, - RIL_CARDSTATE_RESTRICTED = 3 /* card is present but not usable due to carrier restrictions.*/ -} RIL_CardState; - -typedef enum { - RIL_PERSOSUBSTATE_UNKNOWN = 0, /* initial state */ - RIL_PERSOSUBSTATE_IN_PROGRESS = 1, /* in between each lock transition */ - RIL_PERSOSUBSTATE_READY = 2, /* when either SIM or RUIM Perso is finished - since each app can only have 1 active perso - involved */ - RIL_PERSOSUBSTATE_SIM_NETWORK = 3, - RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4, - RIL_PERSOSUBSTATE_SIM_CORPORATE = 5, - RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6, - RIL_PERSOSUBSTATE_SIM_SIM = 7, - RIL_PERSOSUBSTATE_SIM_NETWORK_PUK = 8, /* The corresponding perso lock is blocked */ - RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9, - RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10, - RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11, - RIL_PERSOSUBSTATE_SIM_SIM_PUK = 12, - RIL_PERSOSUBSTATE_RUIM_NETWORK1 = 13, - RIL_PERSOSUBSTATE_RUIM_NETWORK2 = 14, - RIL_PERSOSUBSTATE_RUIM_HRPD = 15, - RIL_PERSOSUBSTATE_RUIM_CORPORATE = 16, - RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17, - RIL_PERSOSUBSTATE_RUIM_RUIM = 18, - RIL_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19, /* The corresponding perso lock is blocked */ - RIL_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20, - RIL_PERSOSUBSTATE_RUIM_HRPD_PUK = 21, - RIL_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22, - RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23, - RIL_PERSOSUBSTATE_RUIM_RUIM_PUK = 24 -} RIL_PersoSubstate; - -typedef enum { - RIL_APPSTATE_UNKNOWN = 0, - RIL_APPSTATE_DETECTED = 1, - RIL_APPSTATE_PIN = 2, /* If PIN1 or UPin is required */ - RIL_APPSTATE_PUK = 3, /* If PUK1 or Puk for UPin is required */ - RIL_APPSTATE_SUBSCRIPTION_PERSO = 4, /* perso_substate should be look at - when app_state is assigned to this value */ - RIL_APPSTATE_READY = 5 -} RIL_AppState; - -typedef enum { - RIL_PINSTATE_UNKNOWN = 0, - RIL_PINSTATE_ENABLED_NOT_VERIFIED = 1, - RIL_PINSTATE_ENABLED_VERIFIED = 2, - RIL_PINSTATE_DISABLED = 3, - RIL_PINSTATE_ENABLED_BLOCKED = 4, - RIL_PINSTATE_ENABLED_PERM_BLOCKED = 5 -} RIL_PinState; - -typedef enum { - RIL_APPTYPE_UNKNOWN = 0, - RIL_APPTYPE_SIM = 1, - RIL_APPTYPE_USIM = 2, - RIL_APPTYPE_RUIM = 3, - RIL_APPTYPE_CSIM = 4, - RIL_APPTYPE_ISIM = 5 -} RIL_AppType; - -/* - * Please note that registration state UNKNOWN is - * treated as "out of service" in the Android telephony. - * Registration state REG_DENIED must be returned if Location Update - * Reject (with cause 17 - Network Failure) is received - * repeatedly from the network, to facilitate - * "managed roaming" - */ -typedef enum { - RIL_NOT_REG_AND_NOT_SEARCHING = 0, // Not registered, MT is not currently searching - // a new operator to register - RIL_REG_HOME = 1, // Registered, home network - RIL_NOT_REG_AND_SEARCHING = 2, // Not registered, but MT is currently searching - // a new operator to register - RIL_REG_DENIED = 3, // Registration denied - RIL_UNKNOWN = 4, // Unknown - RIL_REG_ROAMING = 5, // Registered, roaming - RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_NOT_SEARCHING = 10, // Same as - // RIL_NOT_REG_AND_NOT_SEARCHING but indicates that - // emergency calls are enabled. - RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_SEARCHING = 12, // Same as RIL_NOT_REG_AND_SEARCHING - // but indicates that - // emergency calls are enabled. - RIL_REG_DENIED_AND_EMERGENCY_AVAILABLE = 13, // Same as REG_DENIED but indicates that - // emergency calls are enabled. - RIL_UNKNOWN_AND_EMERGENCY_AVAILABLE = 14, // Same as UNKNOWN but indicates that - // emergency calls are enabled. -} RIL_RegState; - -typedef struct -{ - RIL_AppType app_type; - RIL_AppState app_state; - RIL_PersoSubstate perso_substate; /* applicable only if app_state == - RIL_APPSTATE_SUBSCRIPTION_PERSO */ - char *aid_ptr; /* null terminated string, e.g., from 0xA0, 0x00 -> 0x41, - 0x30, 0x30, 0x30 */ - char *app_label_ptr; /* null terminated string */ - int pin1_replaced; /* applicable to USIM, CSIM & ISIM */ - RIL_PinState pin1; - RIL_PinState pin2; -} RIL_AppStatus; - -/* Deprecated, use RIL_CardStatus_v6 */ -typedef struct -{ - RIL_CardState card_state; - RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ - int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ - int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ - int num_applications; /* value <= RIL_CARD_MAX_APPS */ - RIL_AppStatus applications[RIL_CARD_MAX_APPS]; -} RIL_CardStatus_v5; - -typedef struct -{ - RIL_CardState card_state; - RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ - int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ - int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ - int ims_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ - int num_applications; /* value <= RIL_CARD_MAX_APPS */ - RIL_AppStatus applications[RIL_CARD_MAX_APPS]; -} RIL_CardStatus_v6; - -/** The result of a SIM refresh, returned in data[0] of RIL_UNSOL_SIM_REFRESH - * or as part of RIL_SimRefreshResponse_v7 - */ -typedef enum { - /* A file on SIM has been updated. data[1] contains the EFID. */ - SIM_FILE_UPDATE = 0, - /* SIM initialized. All files should be re-read. */ - SIM_INIT = 1, - /* SIM reset. SIM power required, SIM may be locked and all files should be re-read. */ - SIM_RESET = 2 -} RIL_SimRefreshResult; - -typedef struct { - RIL_SimRefreshResult result; - int ef_id; /* is the EFID of the updated file if the result is */ - /* SIM_FILE_UPDATE or 0 for any other result. */ - char * aid; /* is AID(application ID) of the card application */ - /* See ETSI 102.221 8.1 and 101.220 4 */ - /* For SIM_FILE_UPDATE result it can be set to AID of */ - /* application in which updated EF resides or it can be */ - /* NULL if EF is outside of an application. */ - /* For SIM_INIT result this field is set to AID of */ - /* application that caused REFRESH */ - /* For SIM_RESET result it is NULL. */ -} RIL_SimRefreshResponse_v7; - -/* Deprecated, use RIL_CDMA_CallWaiting_v6 */ -typedef struct { - char * number; /* Remote party number */ - int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ - char * name; /* Remote party name */ - RIL_CDMA_SignalInfoRecord signalInfoRecord; -} RIL_CDMA_CallWaiting_v5; - -typedef struct { - char * number; /* Remote party number */ - int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ - char * name; /* Remote party name */ - RIL_CDMA_SignalInfoRecord signalInfoRecord; - /* Number type/Number plan required to support International Call Waiting */ - int number_type; /* 0=Unknown, 1=International, 2=National, - 3=Network specific, 4=subscriber */ - int number_plan; /* 0=Unknown, 1=ISDN, 3=Data, 4=Telex, 8=Nat'l, 9=Private */ -} RIL_CDMA_CallWaiting_v6; - -/** - * Which types of Cell Broadcast Message (CBM) are to be received by the ME - * - * uFromServiceID - uToServiceID defines a range of CBM message identifiers - * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS - * and 9.4.4.2.2 for UMTS. All other values can be treated as empty - * CBM message ID. - * - * uFromCodeScheme - uToCodeScheme defines a range of CBM data coding schemes - * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS - * and 9.4.4.2.3 for UMTS. - * All other values can be treated as empty CBM data coding scheme. - * - * selected 0 means message types specified in <fromServiceId, toServiceId> - * and <fromCodeScheme, toCodeScheme>are not accepted, while 1 means accepted. - * - * Used by RIL_REQUEST_GSM_GET_BROADCAST_CONFIG and - * RIL_REQUEST_GSM_SET_BROADCAST_CONFIG. - */ -typedef struct { - int fromServiceId; - int toServiceId; - int fromCodeScheme; - int toCodeScheme; - unsigned char selected; -} RIL_GSM_BroadcastSmsConfigInfo; - -/* No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. */ -#define RIL_RESTRICTED_STATE_NONE 0x00 -/* Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. */ -#define RIL_RESTRICTED_STATE_CS_EMERGENCY 0x01 -/* Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. */ -#define RIL_RESTRICTED_STATE_CS_NORMAL 0x02 -/* Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction.*/ -#define RIL_RESTRICTED_STATE_CS_ALL 0x04 -/* Block packet data access due to restriction. */ -#define RIL_RESTRICTED_STATE_PS_ALL 0x10 - -/* The status for an OTASP/OTAPA session */ -typedef enum { - CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED, - CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED, - CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED, - CDMA_OTA_PROVISION_STATUS_SSD_UPDATED, - CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED, - CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED, - CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED, - CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED, - CDMA_OTA_PROVISION_STATUS_COMMITTED, - CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED, - CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED, - CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED -} RIL_CDMA_OTA_ProvisionStatus; - -typedef struct { - int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ -} RIL_GW_SignalStrength; - -typedef struct { - int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ - int timingAdvance; /* Timing Advance in bit periods. 1 bit period = 48/13 us. - * INT_MAX denotes invalid value */ -} RIL_GSM_SignalStrength_v12; - -typedef struct { - int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ -} RIL_SignalStrengthWcdma; - -typedef struct { - int dbm; /* Valid values are positive integers. This value is the actual RSSI value - * multiplied by -1. Example: If the actual RSSI is -75, then this response - * value will be 75. - */ - int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied - * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value - * will be 125. - */ -} RIL_CDMA_SignalStrength; - - -typedef struct { - int dbm; /* Valid values are positive integers. This value is the actual RSSI value - * multiplied by -1. Example: If the actual RSSI is -75, then this response - * value will be 75. - */ - int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied - * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value - * will be 125. - */ - int signalNoiseRatio; /* Valid values are 0-8. 8 is the highest signal to noise ratio. */ -} RIL_EVDO_SignalStrength; - -typedef struct { - int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. - * Range: 44 to 140 dBm - * INT_MAX: 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.133 9.1.4 */ - int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. - * Range: 20 to 3 dB. - * INT_MAX: 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.133 9.1.7 */ - int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. - * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). - * INT_MAX : 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.101 8.1.1 */ - int cqi; /* The current Channel Quality Indicator. - * Range: 0 to 15. - * INT_MAX : 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ -} RIL_LTE_SignalStrength; - -typedef struct { - int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ - int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. - * Range: 44 to 140 dBm - * INT_MAX: 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.133 9.1.4 */ - int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. - * Range: 20 to 3 dB. - * INT_MAX: 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.133 9.1.7 */ - int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. - * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). - * INT_MAX : 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.101 8.1.1 */ - int cqi; /* The current Channel Quality Indicator. - * Range: 0 to 15. - * INT_MAX : 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ - int timingAdvance; /* timing advance in micro seconds for a one way trip from cell to device. - * Approximate distance can be calculated using 300m/us * timingAdvance. - * Range: 0 to 0x7FFFFFFE - * INT_MAX : 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP 36.321 section 6.1.3.5 - * also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html */ -} RIL_LTE_SignalStrength_v8; - -typedef struct { - int rscp; /* The Received Signal Code Power in dBm multipled by -1. - * Range : 25 to 120 - * INT_MAX: 0x7FFFFFFF denotes invalid value. - * Reference: 3GPP TS 25.123, section 9.1.1.1 */ -} RIL_TD_SCDMA_SignalStrength; - -/* Deprecated, use RIL_SignalStrength_v6 */ -typedef struct { - RIL_GW_SignalStrength GW_SignalStrength; - RIL_CDMA_SignalStrength CDMA_SignalStrength; - RIL_EVDO_SignalStrength EVDO_SignalStrength; -} RIL_SignalStrength_v5; - -typedef struct { - RIL_GW_SignalStrength GW_SignalStrength; - RIL_CDMA_SignalStrength CDMA_SignalStrength; - RIL_EVDO_SignalStrength EVDO_SignalStrength; - RIL_LTE_SignalStrength LTE_SignalStrength; -} RIL_SignalStrength_v6; - -typedef struct { - RIL_GW_SignalStrength GW_SignalStrength; - RIL_CDMA_SignalStrength CDMA_SignalStrength; - RIL_EVDO_SignalStrength EVDO_SignalStrength; - RIL_LTE_SignalStrength_v8 LTE_SignalStrength; -} RIL_SignalStrength_v8; - -typedef struct { - RIL_GW_SignalStrength GW_SignalStrength; - RIL_CDMA_SignalStrength CDMA_SignalStrength; - RIL_EVDO_SignalStrength EVDO_SignalStrength; - RIL_LTE_SignalStrength_v8 LTE_SignalStrength; - RIL_TD_SCDMA_SignalStrength TD_SCDMA_SignalStrength; -} RIL_SignalStrength_v10; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ - int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ -} RIL_CellIdentityGsm; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ - int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ - int arfcn; /* 16-bit GSM Absolute RF channel number; this value must be reported */ - uint8_t bsic; /* 6-bit Base Station Identity Code; 0xFF if unknown */ -} RIL_CellIdentityGsm_v12; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ - int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ - int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */ -} RIL_CellIdentityWcdma; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ - int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ - int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511; this value must be reported */ - int uarfcn; /* 16-bit UMTS Absolute RF Channel Number; this value must be reported */ -} RIL_CellIdentityWcdma_v12; - -typedef struct { - int networkId; /* Network Id 0..65535, INT_MAX if unknown */ - int systemId; /* CDMA System Id 0..32767, INT_MAX if unknown */ - int basestationId; /* Base Station Id 0..65535, INT_MAX if unknown */ - int longitude; /* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. - * It is represented in units of 0.25 seconds and ranges from -2592000 - * to 2592000, both values inclusive (corresponding to a range of -180 - * to +180 degrees). INT_MAX if unknown */ - - int latitude; /* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. - * It is represented in units of 0.25 seconds and ranges from -1296000 - * to 1296000, both values inclusive (corresponding to a range of -90 - * to +90 degrees). INT_MAX if unknown */ -} RIL_CellIdentityCdma; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ - int pci; /* physical cell id 0..503, INT_MAX if unknown */ - int tac; /* 16-bit tracking area code, INT_MAX if unknown */ -} RIL_CellIdentityLte; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ - int pci; /* physical cell id 0..503; this value must be reported */ - int tac; /* 16-bit tracking area code, INT_MAX if unknown */ - int earfcn; /* 18-bit LTE Absolute RF Channel Number; this value must be reported */ -} RIL_CellIdentityLte_v12; - -typedef struct { - int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ - int mnc; /* 2 or 3-digit Mobile Network Code, 0..999; - the most significant nibble encodes the number of digits - {2, 3, 0 (unset)}; - INT_MAX if unknown */ - int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ - int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ - int cpid; /* 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown */ -} RIL_CellIdentityTdscdma; - -typedef struct { - RIL_CellIdentityGsm cellIdentityGsm; - RIL_GW_SignalStrength signalStrengthGsm; -} RIL_CellInfoGsm; - -typedef struct { - RIL_CellIdentityGsm_v12 cellIdentityGsm; - RIL_GSM_SignalStrength_v12 signalStrengthGsm; -} RIL_CellInfoGsm_v12; - -typedef struct { - RIL_CellIdentityWcdma cellIdentityWcdma; - RIL_SignalStrengthWcdma signalStrengthWcdma; -} RIL_CellInfoWcdma; - -typedef struct { - RIL_CellIdentityWcdma_v12 cellIdentityWcdma; - RIL_SignalStrengthWcdma signalStrengthWcdma; -} RIL_CellInfoWcdma_v12; - -typedef struct { - RIL_CellIdentityCdma cellIdentityCdma; - RIL_CDMA_SignalStrength signalStrengthCdma; - RIL_EVDO_SignalStrength signalStrengthEvdo; -} RIL_CellInfoCdma; - -typedef struct { - RIL_CellIdentityLte cellIdentityLte; - RIL_LTE_SignalStrength_v8 signalStrengthLte; -} RIL_CellInfoLte; - -typedef struct { - RIL_CellIdentityLte_v12 cellIdentityLte; - RIL_LTE_SignalStrength_v8 signalStrengthLte; -} RIL_CellInfoLte_v12; - -typedef struct { - RIL_CellIdentityTdscdma cellIdentityTdscdma; - RIL_TD_SCDMA_SignalStrength signalStrengthTdscdma; -} RIL_CellInfoTdscdma; - -// Must be the same as CellInfo.TYPE_XXX -typedef enum { - RIL_CELL_INFO_TYPE_NONE = 0, /* indicates no cell information */ - RIL_CELL_INFO_TYPE_GSM = 1, - RIL_CELL_INFO_TYPE_CDMA = 2, - RIL_CELL_INFO_TYPE_LTE = 3, - RIL_CELL_INFO_TYPE_WCDMA = 4, - RIL_CELL_INFO_TYPE_TD_SCDMA = 5 -} RIL_CellInfoType; - -// Must be the same as CellInfo.TIMESTAMP_TYPE_XXX -typedef enum { - RIL_TIMESTAMP_TYPE_UNKNOWN = 0, - RIL_TIMESTAMP_TYPE_ANTENNA = 1, - RIL_TIMESTAMP_TYPE_MODEM = 2, - RIL_TIMESTAMP_TYPE_OEM_RIL = 3, - RIL_TIMESTAMP_TYPE_JAVA_RIL = 4, -} RIL_TimeStampType; - -typedef struct { - RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ - int registered; /* !0 if this cell is registered 0 if not registered */ - RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ - uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ - union { - RIL_CellInfoGsm gsm; - RIL_CellInfoCdma cdma; - RIL_CellInfoLte lte; - RIL_CellInfoWcdma wcdma; - RIL_CellInfoTdscdma tdscdma; - } CellInfo; -} RIL_CellInfo; - -typedef struct { - RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ - int registered; /* !0 if this cell is registered 0 if not registered */ - RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ - uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ - union { - RIL_CellInfoGsm_v12 gsm; - RIL_CellInfoCdma cdma; - RIL_CellInfoLte_v12 lte; - RIL_CellInfoWcdma_v12 wcdma; - RIL_CellInfoTdscdma tdscdma; - } CellInfo; -} RIL_CellInfo_v12; - -typedef struct { - RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ - union { - RIL_CellIdentityGsm_v12 cellIdentityGsm; - RIL_CellIdentityWcdma_v12 cellIdentityWcdma; - RIL_CellIdentityLte_v12 cellIdentityLte; - RIL_CellIdentityTdscdma cellIdentityTdscdma; - RIL_CellIdentityCdma cellIdentityCdma; - }; -}RIL_CellIdentity_v16; - -typedef struct { - RIL_RegState regState; // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING, - // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED, - // UNKNOWN, REG_ROAMING defined in RegState - RIL_RadioTechnology rat; // indicates the available voice radio technology, - // valid values as defined by RadioTechnology. - int32_t cssSupported; // concurrent services support indicator. if - // registered on a CDMA system. - // 0 - Concurrent services not supported, - // 1 - Concurrent services supported - int32_t roamingIndicator; // TSB-58 Roaming Indicator if registered - // on a CDMA or EVDO system or -1 if not. - // Valid values are 0-255. - int32_t systemIsInPrl; // indicates whether the current system is in the - // PRL if registered on a CDMA or EVDO system or -1 if - // not. 0=not in the PRL, 1=in the PRL - int32_t defaultRoamingIndicator; // default Roaming Indicator from the PRL, - // if registered on a CDMA or EVDO system or -1 if not. - // Valid values are 0-255. - int32_t reasonForDenial; // reasonForDenial if registration state is 3 - // (Registration denied) this is an enumerated reason why - // registration was denied. See 3GPP TS 24.008, - // 10.5.3.6 and Annex G. - // 0 - General - // 1 - Authentication Failure - // 2 - IMSI unknown in HLR - // 3 - Illegal MS - // 4 - Illegal ME - // 5 - PLMN not allowed - // 6 - Location area not allowed - // 7 - Roaming not allowed - // 8 - No Suitable Cells in this Location Area - // 9 - Network failure - // 10 - Persistent location update reject - // 11 - PLMN not allowed - // 12 - Location area not allowed - // 13 - Roaming not allowed in this Location Area - // 15 - No Suitable Cells in this Location Area - // 17 - Network Failure - // 20 - MAC Failure - // 21 - Sync Failure - // 22 - Congestion - // 23 - GSM Authentication unacceptable - // 25 - Not Authorized for this CSG - // 32 - Service option not supported - // 33 - Requested service option not subscribed - // 34 - Service option temporarily out of order - // 38 - Call cannot be identified - // 48-63 - Retry upon entry into a new cell - // 95 - Semantically incorrect message - // 96 - Invalid mandatory information - // 97 - Message type non-existent or not implemented - // 98 - Message type not compatible with protocol state - // 99 - Information element non-existent or - // not implemented - // 100 - Conditional IE error - // 101 - Message not compatible with protocol state; - RIL_CellIdentity_v16 cellIdentity; // current cell information -}RIL_VoiceRegistrationStateResponse; - - -typedef struct { - RIL_RegState regState; // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING, - // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED, - // UNKNOWN, REG_ROAMING defined in RegState - RIL_RadioTechnology rat; // indicates the available data radio technology, - // valid values as defined by RadioTechnology. - int32_t reasonDataDenied; // if registration state is 3 (Registration - // denied) this is an enumerated reason why - // registration was denied. See 3GPP TS 24.008, - // Annex G.6 "Additional cause codes for GMM". - // 7 == GPRS services not allowed - // 8 == GPRS services and non-GPRS services not allowed - // 9 == MS identity cannot be derived by the network - // 10 == Implicitly detached - // 14 == GPRS services not allowed in this PLMN - // 16 == MSC temporarily not reachable - // 40 == No PDP context activated - int32_t maxDataCalls; // The maximum number of simultaneous Data Calls that - // must be established using setupDataCall(). - RIL_CellIdentity_v16 cellIdentity; // Current cell information -}RIL_DataRegistrationStateResponse; - -/* Names of the CDMA info records (C.S0005 section 3.7.5) */ -typedef enum { - RIL_CDMA_DISPLAY_INFO_REC, - RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC, - RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC, - RIL_CDMA_CONNECTED_NUMBER_INFO_REC, - RIL_CDMA_SIGNAL_INFO_REC, - RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, - RIL_CDMA_LINE_CONTROL_INFO_REC, - RIL_CDMA_EXTENDED_DISPLAY_INFO_REC, - RIL_CDMA_T53_CLIR_INFO_REC, - RIL_CDMA_T53_RELEASE_INFO_REC, - RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC -} RIL_CDMA_InfoRecName; - -/* Display Info Rec as defined in C.S0005 section 3.7.5.1 - Extended Display Info Rec as defined in C.S0005 section 3.7.5.16 - Note: the Extended Display info rec contains multiple records of the - form: display_tag, display_len, and display_len occurrences of the - chari field if the display_tag is not 10000000 or 10000001. - To save space, the records are stored consecutively in a byte buffer. - The display_tag, display_len and chari fields are all 1 byte. -*/ - -typedef struct { - char alpha_len; - char alpha_buf[CDMA_ALPHA_INFO_BUFFER_LENGTH]; -} RIL_CDMA_DisplayInfoRecord; - -/* Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 - Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3 - Connected Number Info Rec as defined in C.S0005 section 3.7.5.4 -*/ - -typedef struct { - char len; - char buf[CDMA_NUMBER_INFO_BUFFER_LENGTH]; - char number_type; - char number_plan; - char pi; - char si; -} RIL_CDMA_NumberInfoRecord; - -/* Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 */ -typedef enum { - RIL_REDIRECTING_REASON_UNKNOWN = 0, - RIL_REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1, - RIL_REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2, - RIL_REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9, - RIL_REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10, - RIL_REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15, - RIL_REDIRECTING_REASON_RESERVED -} RIL_CDMA_RedirectingReason; - -typedef struct { - RIL_CDMA_NumberInfoRecord redirectingNumber; - /* redirectingReason is set to RIL_REDIRECTING_REASON_UNKNOWN if not included */ - RIL_CDMA_RedirectingReason redirectingReason; -} RIL_CDMA_RedirectingNumberInfoRecord; - -/* Line Control Information Record as defined in C.S0005 section 3.7.5.15 */ -typedef struct { - char lineCtrlPolarityIncluded; - char lineCtrlToggle; - char lineCtrlReverse; - char lineCtrlPowerDenial; -} RIL_CDMA_LineControlInfoRecord; - -/* T53 CLIR Information Record */ -typedef struct { - char cause; -} RIL_CDMA_T53_CLIRInfoRecord; - -/* T53 Audio Control Information Record */ -typedef struct { - char upLink; - char downLink; -} RIL_CDMA_T53_AudioControlInfoRecord; - -typedef struct { - - RIL_CDMA_InfoRecName name; - - union { - /* Display and Extended Display Info Rec */ - RIL_CDMA_DisplayInfoRecord display; - - /* Called Party Number, Calling Party Number, Connected Number Info Rec */ - RIL_CDMA_NumberInfoRecord number; - - /* Signal Info Rec */ - RIL_CDMA_SignalInfoRecord signal; - - /* Redirecting Number Info Rec */ - RIL_CDMA_RedirectingNumberInfoRecord redir; - - /* Line Control Info Rec */ - RIL_CDMA_LineControlInfoRecord lineCtrl; - - /* T53 CLIR Info Rec */ - RIL_CDMA_T53_CLIRInfoRecord clir; - - /* T53 Audio Control Info Rec */ - RIL_CDMA_T53_AudioControlInfoRecord audioCtrl; - } rec; -} RIL_CDMA_InformationRecord; - -#define RIL_CDMA_MAX_NUMBER_OF_INFO_RECS 10 - -typedef struct { - char numberOfInfoRecs; - RIL_CDMA_InformationRecord infoRec[RIL_CDMA_MAX_NUMBER_OF_INFO_RECS]; -} RIL_CDMA_InformationRecords; - -/* See RIL_REQUEST_NV_READ_ITEM */ -typedef struct { - RIL_NV_Item itemID; -} RIL_NV_ReadItem; - -/* See RIL_REQUEST_NV_WRITE_ITEM */ -typedef struct { - RIL_NV_Item itemID; - char * value; -} RIL_NV_WriteItem; - -typedef enum { - HANDOVER_STARTED = 0, - HANDOVER_COMPLETED = 1, - HANDOVER_FAILED = 2, - HANDOVER_CANCELED = 3 -} RIL_SrvccState; - -/* hardware configuration reported to RILJ. */ -typedef enum { - RIL_HARDWARE_CONFIG_MODEM = 0, - RIL_HARDWARE_CONFIG_SIM = 1, -} RIL_HardwareConfig_Type; - -typedef enum { - RIL_HARDWARE_CONFIG_STATE_ENABLED = 0, - RIL_HARDWARE_CONFIG_STATE_STANDBY = 1, - RIL_HARDWARE_CONFIG_STATE_DISABLED = 2, -} RIL_HardwareConfig_State; - -typedef struct { - int rilModel; - uint32_t rat; /* bitset - ref. RIL_RadioTechnology. */ - int maxVoice; - int maxData; - int maxStandby; -} RIL_HardwareConfig_Modem; - -typedef struct { - char modemUuid[MAX_UUID_LENGTH]; -} RIL_HardwareConfig_Sim; - -typedef struct { - RIL_HardwareConfig_Type type; - char uuid[MAX_UUID_LENGTH]; - RIL_HardwareConfig_State state; - union { - RIL_HardwareConfig_Modem modem; - RIL_HardwareConfig_Sim sim; - } cfg; -} RIL_HardwareConfig; - -typedef enum { - SS_CFU, - SS_CF_BUSY, - SS_CF_NO_REPLY, - SS_CF_NOT_REACHABLE, - SS_CF_ALL, - SS_CF_ALL_CONDITIONAL, - SS_CLIP, - SS_CLIR, - SS_COLP, - SS_COLR, - SS_WAIT, - SS_BAOC, - SS_BAOIC, - SS_BAOIC_EXC_HOME, - SS_BAIC, - SS_BAIC_ROAMING, - SS_ALL_BARRING, - SS_OUTGOING_BARRING, - SS_INCOMING_BARRING -} RIL_SsServiceType; - -typedef enum { - SS_ACTIVATION, - SS_DEACTIVATION, - SS_INTERROGATION, - SS_REGISTRATION, - SS_ERASURE -} RIL_SsRequestType; - -typedef enum { - SS_ALL_TELE_AND_BEARER_SERVICES, - SS_ALL_TELESEVICES, - SS_TELEPHONY, - SS_ALL_DATA_TELESERVICES, - SS_SMS_SERVICES, - SS_ALL_TELESERVICES_EXCEPT_SMS -} RIL_SsTeleserviceType; - -#define SS_INFO_MAX 4 -#define NUM_SERVICE_CLASSES 7 - -typedef struct { - int numValidIndexes; /* This gives the number of valid values in cfInfo. - For example if voice is forwarded to one number and data - is forwarded to a different one then numValidIndexes will be - 2 indicating total number of valid values in cfInfo. - Similarly if all the services are forwarded to the same - number then the value of numValidIndexes will be 1. */ - - RIL_CallForwardInfo cfInfo[NUM_SERVICE_CLASSES]; /* This is the response data - for SS request to query call - forward status. see - RIL_REQUEST_QUERY_CALL_FORWARD_STATUS */ -} RIL_CfData; - -typedef struct { - RIL_SsServiceType serviceType; - RIL_SsRequestType requestType; - RIL_SsTeleserviceType teleserviceType; - int serviceClass; - RIL_Errno result; - - union { - int ssInfo[SS_INFO_MAX]; /* This is the response data for most of the SS GET/SET - RIL requests. E.g. RIL_REQUSET_GET_CLIR returns - two ints, so first two values of ssInfo[] will be - used for response if serviceType is SS_CLIR and - requestType is SS_INTERROGATION */ - - RIL_CfData cfData; - }; -} RIL_StkCcUnsolSsResponse; - -/** - * Data connection power state - */ -typedef enum { - RIL_DC_POWER_STATE_LOW = 1, // Low power state - RIL_DC_POWER_STATE_MEDIUM = 2, // Medium power state - RIL_DC_POWER_STATE_HIGH = 3, // High power state - RIL_DC_POWER_STATE_UNKNOWN = INT32_MAX // Unknown state -} RIL_DcPowerStates; - -/** - * Data connection real time info - */ -typedef struct { - uint64_t time; // Time in nanos as returned by ril_nano_time - RIL_DcPowerStates powerState; // Current power state -} RIL_DcRtInfo; - -/** - * Data profile to modem - */ -typedef struct { - /* id of the data profile */ - int profileId; - /* the APN to connect to */ - char* apn; - /** one of the PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - */ - char* protocol; - /** authentication protocol used for this PDP context - * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) - */ - int authType; - /* the username for APN, or NULL */ - char* user; - /* the password for APN, or NULL */ - char* password; - /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */ - int type; - /* the period in seconds to limit the maximum connections */ - int maxConnsTime; - /* the maximum connections during maxConnsTime */ - int maxConns; - /** the required wait time in seconds after a successful UE initiated - * disconnect of a given PDN connection before the device can send - * a new PDN connection request for that given PDN - */ - int waitTime; - /* true to enable the profile, 0 to disable, 1 to enable */ - int enabled; -} RIL_DataProfileInfo; - -typedef struct { - /* id of the data profile */ - int profileId; - /* the APN to connect to */ - char* apn; - /** one of the PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - */ - char* protocol; - /** one of the PDP_type values in TS 27.007 section 10.1.1 used on roaming network. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - */ - char *roamingProtocol; - /** authentication protocol used for this PDP context - * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) - */ - int authType; - /* the username for APN, or NULL */ - char* user; - /* the password for APN, or NULL */ - char* password; - /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */ - int type; - /* the period in seconds to limit the maximum connections */ - int maxConnsTime; - /* the maximum connections during maxConnsTime */ - int maxConns; - /** the required wait time in seconds after a successful UE initiated - * disconnect of a given PDN connection before the device can send - * a new PDN connection request for that given PDN - */ - int waitTime; - /* true to enable the profile, 0 to disable, 1 to enable */ - int enabled; - /* supported APN types bitmask. See RIL_ApnTypes for the value of each bit. */ - int supportedTypesBitmask; - /** the bearer bitmask. See RIL_RadioAccessFamily for the value of each bit. */ - int bearerBitmask; - /** maximum transmission unit (MTU) size in bytes */ - int mtu; - /** the MVNO type: possible values are "imsi", "gid", "spn" */ - char *mvnoType; - /** MVNO match data. Can be anything defined by the carrier. For example, - * SPN like: "A MOBILE", "BEN NL", etc... - * IMSI like: "302720x94", "2060188", etc... - * GID like: "4E", "33", etc... - */ - char *mvnoMatchData; -} RIL_DataProfileInfo_v15; - -/* Tx Power Levels */ -#define RIL_NUM_TX_POWER_LEVELS 5 - -/** - * Aggregate modem activity information - */ -typedef struct { - - /* total time (in ms) when modem is in a low power or - * sleep state - */ - uint32_t sleep_mode_time_ms; - - /* total time (in ms) when modem is awake but neither - * the transmitter nor receiver are active/awake */ - uint32_t idle_mode_time_ms; - - /* total time (in ms) during which the transmitter is active/awake, - * subdivided by manufacturer-defined device-specific - * contiguous increasing ranges of transmit power between - * 0 and the transmitter's maximum transmit power. - */ - uint32_t tx_mode_time_ms[RIL_NUM_TX_POWER_LEVELS]; - - /* total time (in ms) for which receiver is active/awake and - * the transmitter is inactive */ - uint32_t rx_mode_time_ms; -} RIL_ActivityStatsInfo; - -typedef enum { - RIL_APN_TYPE_UNKNOWN = 0x0, // Unknown - RIL_APN_TYPE_DEFAULT = 0x1, // APN type for default data traffic - RIL_APN_TYPE_MMS = 0x2, // APN type for MMS traffic - RIL_APN_TYPE_SUPL = 0x4, // APN type for SUPL assisted GPS - RIL_APN_TYPE_DUN = 0x8, // APN type for DUN traffic - RIL_APN_TYPE_HIPRI = 0x10, // APN type for HiPri traffic - RIL_APN_TYPE_FOTA = 0x20, // APN type for FOTA - RIL_APN_TYPE_IMS = 0x40, // APN type for IMS - RIL_APN_TYPE_CBS = 0x80, // APN type for CBS - RIL_APN_TYPE_IA = 0x100, // APN type for IA Initial Attach APN - RIL_APN_TYPE_EMERGENCY = 0x200, // APN type for Emergency PDN. This is not an IA apn, - // but is used for access to carrier services in an - // emergency call situation. - RIL_APN_TYPE_ALL = 0xFFFFFFFF // All APN types -} RIL_ApnTypes; - -typedef enum { - RIL_DST_POWER_SAVE_MODE, // Device power save mode (provided by PowerManager) - // True indicates the device is in power save mode. - RIL_DST_CHARGING_STATE, // Device charging state (provided by BatteryManager) - // True indicates the device is charging. - RIL_DST_LOW_DATA_EXPECTED // Low data expected mode. True indicates low data traffic - // is expected, for example, when the device is idle - // (e.g. not doing tethering in the background). Note - // this doesn't mean no data is expected. -} RIL_DeviceStateType; - -typedef enum { - RIL_UR_SIGNAL_STRENGTH = 0x01, // When this bit is set, modem should always send the - // signal strength update through - // RIL_UNSOL_SIGNAL_STRENGTH, otherwise suppress it. - RIL_UR_FULL_NETWORK_STATE = 0x02, // When this bit is set, modem should always send - // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED - // when any field in - // RIL_REQUEST_VOICE_REGISTRATION_STATE or - // RIL_REQUEST_DATA_REGISTRATION_STATE changes. When - // this bit is not set, modem should suppress - // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED - // only when insignificant fields change - // (e.g. cell info). - // Modem should continue sending - // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED - // when significant fields are updated even when this - // bit is not set. The following fields are - // considered significant, registration state and - // radio technology. - RIL_UR_DATA_CALL_DORMANCY_CHANGED = 0x04 // When this bit is set, modem should send the data - // call list changed unsolicited response - // RIL_UNSOL_DATA_CALL_LIST_CHANGED whenever any - // field in RIL_Data_Call_Response changes. - // Otherwise modem should suppress the unsolicited - // response when the only changed field is 'active' - // (for data dormancy). For all other fields change, - // modem should continue sending - // RIL_UNSOL_DATA_CALL_LIST_CHANGED regardless this - // bit is set or not. -} RIL_UnsolicitedResponseFilter; - -typedef struct { - char * aidPtr; /* AID value, See ETSI 102.221 and 101.220*/ - int p2; /* P2 parameter (described in ISO 7816-4) - P2Constants:NO_P2 if to be ignored */ -} RIL_OpenChannelParams; - -typedef enum { - RIL_ONE_SHOT = 0x01, // Performs the scan only once - RIL_PERIODIC = 0x02 // Performs the scan periodically until cancelled -} RIL_ScanType; - -typedef enum { - GERAN = 0x01, // GSM EDGE Radio Access Network - UTRAN = 0x02, // Universal Terrestrial Radio Access Network - EUTRAN = 0x03, // Evolved Universal Terrestrial Radio Access Network - NGRAN = 0x04, // Next-Generation Radio Access Network -} RIL_RadioAccessNetworks; - -typedef enum { - GERAN_BAND_T380 = 1, - GERAN_BAND_T410 = 2, - GERAN_BAND_450 = 3, - GERAN_BAND_480 = 4, - GERAN_BAND_710 = 5, - GERAN_BAND_750 = 6, - GERAN_BAND_T810 = 7, - GERAN_BAND_850 = 8, - GERAN_BAND_P900 = 9, - GERAN_BAND_E900 = 10, - GERAN_BAND_R900 = 11, - GERAN_BAND_DCS1800 = 12, - GERAN_BAND_PCS1900 = 13, - GERAN_BAND_ER900 = 14, -} RIL_GeranBands; - -typedef enum { - UTRAN_BAND_1 = 1, - UTRAN_BAND_2 = 2, - UTRAN_BAND_3 = 3, - UTRAN_BAND_4 = 4, - UTRAN_BAND_5 = 5, - UTRAN_BAND_6 = 6, - UTRAN_BAND_7 = 7, - UTRAN_BAND_8 = 8, - UTRAN_BAND_9 = 9, - UTRAN_BAND_10 = 10, - UTRAN_BAND_11 = 11, - UTRAN_BAND_12 = 12, - UTRAN_BAND_13 = 13, - UTRAN_BAND_14 = 14, - UTRAN_BAND_19 = 19, - UTRAN_BAND_20 = 20, - UTRAN_BAND_21 = 21, - UTRAN_BAND_22 = 22, - UTRAN_BAND_25 = 25, - UTRAN_BAND_26 = 26, -} RIL_UtranBands; - -typedef enum { - EUTRAN_BAND_1 = 1, - EUTRAN_BAND_2 = 2, - EUTRAN_BAND_3 = 3, - EUTRAN_BAND_4 = 4, - EUTRAN_BAND_5 = 5, - EUTRAN_BAND_6 = 6, - EUTRAN_BAND_7 = 7, - EUTRAN_BAND_8 = 8, - EUTRAN_BAND_9 = 9, - EUTRAN_BAND_10 = 10, - EUTRAN_BAND_11 = 11, - EUTRAN_BAND_12 = 12, - EUTRAN_BAND_13 = 13, - EUTRAN_BAND_14 = 14, - EUTRAN_BAND_17 = 17, - EUTRAN_BAND_18 = 18, - EUTRAN_BAND_19 = 19, - EUTRAN_BAND_20 = 20, - EUTRAN_BAND_21 = 21, - EUTRAN_BAND_22 = 22, - EUTRAN_BAND_23 = 23, - EUTRAN_BAND_24 = 24, - EUTRAN_BAND_25 = 25, - EUTRAN_BAND_26 = 26, - EUTRAN_BAND_27 = 27, - EUTRAN_BAND_28 = 28, - EUTRAN_BAND_30 = 30, - EUTRAN_BAND_31 = 31, - EUTRAN_BAND_33 = 33, - EUTRAN_BAND_34 = 34, - EUTRAN_BAND_35 = 35, - EUTRAN_BAND_36 = 36, - EUTRAN_BAND_37 = 37, - EUTRAN_BAND_38 = 38, - EUTRAN_BAND_39 = 39, - EUTRAN_BAND_40 = 40, - EUTRAN_BAND_41 = 41, - EUTRAN_BAND_42 = 42, - EUTRAN_BAND_43 = 43, - EUTRAN_BAND_44 = 44, - EUTRAN_BAND_45 = 45, - EUTRAN_BAND_46 = 46, - EUTRAN_BAND_47 = 47, - EUTRAN_BAND_48 = 48, - EUTRAN_BAND_65 = 65, - EUTRAN_BAND_66 = 66, - EUTRAN_BAND_68 = 68, - EUTRAN_BAND_70 = 70, -} RIL_EutranBands; - -typedef enum { - NGRAN_BAND_1 = 1, - NGRAN_BAND_2 = 2, - NGRAN_BAND_3 = 3, - NGRAN_BAND_5 = 5, - NGRAN_BAND_7 = 7, - NGRAN_BAND_8 = 8, - NGRAN_BAND_12 = 12, - NGRAN_BAND_20 = 20, - NGRAN_BAND_25 = 25, - NGRAN_BAND_28 = 28, - NGRAN_BAND_34 = 34, - NGRAN_BAND_38 = 38, - NGRAN_BAND_39 = 39, - NGRAN_BAND_40 = 40, - NGRAN_BAND_41 = 41, - NGRAN_BAND_50 = 50, - NGRAN_BAND_51 = 51, - NGRAN_BAND_66 = 66, - NGRAN_BAND_70 = 70, - NGRAN_BAND_71 = 71, - NGRAN_BAND_74 = 74, - NGRAN_BAND_75 = 75, - NGRAN_BAND_76 = 76, - NGRAN_BAND_77 = 77, - NGRAN_BAND_78 = 78, - NGRAN_BAND_79 = 79, - NGRAN_BAND_80 = 80, - NGRAN_BAND_81 = 81, - NGRAN_BAND_82 = 82, - NGRAN_BAND_83 = 83, - NGRAN_BAND_84 = 84, - NGRAN_BAND_86 = 86, - NGRAN_BAND_257 = 257, - NGRAN_BAND_258 = 258, - NGRAN_BAND_260 = 260, - NGRAN_BAND_261 = 261, -} RIL_NgranBands; - -typedef struct { - RIL_RadioAccessNetworks radio_access_network; // The type of network to scan. - uint32_t bands_length; // Length of bands - union { - RIL_GeranBands geran_bands[MAX_BANDS]; - RIL_UtranBands utran_bands[MAX_BANDS]; - RIL_EutranBands eutran_bands[MAX_BANDS]; - RIL_NgranBands ngran_bands[MAX_BANDS]; - } bands; - uint32_t channels_length; // Length of channels - uint32_t channels[MAX_CHANNELS]; // Frequency channels to scan -} RIL_RadioAccessSpecifier; - -typedef struct { - RIL_ScanType type; // Type of the scan - int32_t interval; // Time interval in seconds - // between periodic scans, only - // valid when type=RIL_PERIODIC - uint32_t specifiers_length; // Length of specifiers - RIL_RadioAccessSpecifier specifiers[MAX_RADIO_ACCESS_NETWORKS]; // Radio access networks - // with bands/channels. -} RIL_NetworkScanRequest; - -typedef enum { - PARTIAL = 0x01, // The result contains a part of the scan results - COMPLETE = 0x02, // The result contains the last part of the scan results -} RIL_ScanStatus; - -typedef struct { - RIL_ScanStatus status; // The status of the scan - uint32_t network_infos_length; // Total length of RIL_CellInfo - RIL_CellInfo_v12* network_infos; // List of network information - RIL_Errno error; -} RIL_NetworkScanResult; - -/** - * RIL_REQUEST_GET_SIM_STATUS - * - * Requests status of the SIM interface and the SIM card - * - * "data" is NULL - * - * "response" is const RIL_CardStatus_v6 * - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_GET_SIM_STATUS 1 - -/** - * RIL_REQUEST_ENTER_SIM_PIN - * - * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state - * - * "data" is const char ** - * ((const char **)data)[0] is PIN value - * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ENTER_SIM_PIN 2 - -/** - * RIL_REQUEST_ENTER_SIM_PUK - * - * Supplies SIM PUK and new PIN. - * - * "data" is const char ** - * ((const char **)data)[0] is PUK value - * ((const char **)data)[1] is new PIN value - * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * (PUK is invalid) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ENTER_SIM_PUK 3 - -/** - * RIL_REQUEST_ENTER_SIM_PIN2 - * - * Supplies SIM PIN2. Only called following operation where SIM_PIN2 was - * returned as a a failure from a previous operation. - * - * "data" is const char ** - * ((const char **)data)[0] is PIN2 value - * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ENTER_SIM_PIN2 4 - -/** - * RIL_REQUEST_ENTER_SIM_PUK2 - * - * Supplies SIM PUK2 and new PIN2. - * - * "data" is const char ** - * ((const char **)data)[0] is PUK2 value - * ((const char **)data)[1] is new PIN2 value - * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * (PUK2 is invalid) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ENTER_SIM_PUK2 5 - -/** - * RIL_REQUEST_CHANGE_SIM_PIN - * - * Supplies old SIM PIN and new PIN. - * - * "data" is const char ** - * ((const char **)data)[0] is old PIN value - * ((const char **)data)[1] is new PIN value - * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * (old PIN is invalid) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_CHANGE_SIM_PIN 6 - - -/** - * RIL_REQUEST_CHANGE_SIM_PIN2 - * - * Supplies old SIM PIN2 and new PIN2. - * - * "data" is const char ** - * ((const char **)data)[0] is old PIN2 value - * ((const char **)data)[1] is new PIN2 value - * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * (old PIN2 is invalid) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - * - */ - -#define RIL_REQUEST_CHANGE_SIM_PIN2 7 - -/** - * RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION - * - * Requests that network personlization be deactivated - * - * "data" is const char ** - * ((const char **)(data))[0]] is network depersonlization code - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * PASSWORD_INCORRECT - * SIM_ABSENT - * (code is invalid) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8 - -/** - * RIL_REQUEST_GET_CURRENT_CALLS - * - * Requests current call list - * - * "data" is NULL - * - * "response" must be a "const RIL_Call **" - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * (request will be made again in a few hundred msec) - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_GET_CURRENT_CALLS 9 - - -/** - * RIL_REQUEST_DIAL - * - * Initiate voice call - * - * "data" is const RIL_Dial * - * "response" is NULL - * - * This method is never used for supplementary service codes - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * DIAL_MODIFIED_TO_USSD - * DIAL_MODIFIED_TO_SS - * DIAL_MODIFIED_TO_DIAL - * INVALID_ARGUMENTS - * NO_MEMORY - * INVALID_STATE - * NO_RESOURCES - * INTERNAL_ERR - * FDN_CHECK_FAILURE - * MODEM_ERR - * NO_SUBSCRIPTION - * NO_NETWORK_FOUND - * INVALID_CALL_ID - * DEVICE_IN_USE - * OPERATION_NOT_ALLOWED - * ABORTED - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_DIAL 10 - -/** - * RIL_REQUEST_GET_IMSI - * - * Get the SIM IMSI - * - * Only valid when radio state is "RADIO_STATE_ON" - * - * "data" is const char ** - * ((const char **)data)[0] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * "response" is a const char * containing the IMSI - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_SIM_STATE - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_GET_IMSI 11 - -/** - * RIL_REQUEST_HANGUP - * - * Hang up a specific line (like AT+CHLD=1x) - * - * After this HANGUP request returns, RIL should show the connection is NOT - * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. - * - * "data" is an int * - * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_ARGUMENTS - * NO_MEMORY - * INVALID_STATE - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_CALL_ID - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_HANGUP 12 - -/** - * RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND - * - * Hang up waiting or held (like AT+CHLD=0) - * - * After this HANGUP request returns, RIL should show the connection is NOT - * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_CALL_ID - * NO_RESOURCES - * OPERATION_NOT_ALLOWED - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13 - -/** - * RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND - * - * Hang up waiting or held (like AT+CHLD=1) - * - * After this HANGUP request returns, RIL should show the connection is NOT - * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * OPERATION_NOT_ALLOWED - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14 - -/** - * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE - * - * Switch waiting or holding call and active call (like AT+CHLD=2) - * - * State transitions should be is follows: - * - * If call 1 is waiting and call 2 is active, then if this re - * - * BEFORE AFTER - * Call 1 Call 2 Call 1 Call 2 - * ACTIVE HOLDING HOLDING ACTIVE - * ACTIVE WAITING HOLDING ACTIVE - * HOLDING WAITING HOLDING ACTIVE - * ACTIVE IDLE HOLDING IDLE - * IDLE IDLE IDLE IDLE - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_STATE - * INVALID_ARGUMENTS - * INVALID_CALL_ID - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15 -#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15 - -/** - * RIL_REQUEST_CONFERENCE - * - * Conference holding and active (like AT+CHLD=3) - - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_STATE - * INVALID_CALL_ID - * INVALID_ARGUMENTS - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_CONFERENCE 16 - -/** - * RIL_REQUEST_UDUB - * - * Send UDUB (user determined used busy) to ringing or - * waiting call answer)(RIL_BasicRequest r); - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_RESOURCES - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * OPERATION_NOT_ALLOWED - * INVALID_ARGUMENTS - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_UDUB 17 - -/** - * RIL_REQUEST_LAST_CALL_FAIL_CAUSE - * - * Requests the failure cause code for the most recently terminated call - * - * "data" is NULL - * "response" is a const RIL_LastCallFailCauseInfo * - * RIL_LastCallFailCauseInfo contains LastCallFailCause and vendor cause. - * The vendor cause code must be used for debugging purpose only. - * The implementation must return one of the values of LastCallFailCause - * as mentioned below. - * - * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H - * where possible. - * CDMA failure reasons codes for the possible call failure scenarios - * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. - * Any of the following reason codes if the call is failed or dropped due to reason - * mentioned with in the braces. - * - * CALL_FAIL_RADIO_OFF (Radio is OFF) - * CALL_FAIL_OUT_OF_SERVICE (No cell coverage) - * CALL_FAIL_NO_VALID_SIM (No valid SIM) - * CALL_FAIL_RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario) - * CALL_FAIL_NETWORK_RESP_TIMEOUT (No response from network) - * CALL_FAIL_NETWORK_REJECT (Explicit network reject) - * CALL_FAIL_RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH) - * CALL_FAIL_RADIO_LINK_FAILURE (Radio Link Failure) - * CALL_FAIL_RADIO_LINK_LOST (Radio link lost due to poor coverage) - * CALL_FAIL_RADIO_UPLINK_FAILURE (Radio uplink failure) - * CALL_FAIL_RADIO_SETUP_FAILURE (RRC connection setup failure) - * CALL_FAIL_RADIO_RELEASE_NORMAL (RRC connection release, normal) - * CALL_FAIL_RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal) - * CALL_FAIL_ACCESS_CLASS_BLOCKED (Access class barring) - * CALL_FAIL_NETWORK_DETACH (Explicit network detach) - * - * OEM causes (CALL_FAIL_OEM_CAUSE_XX) must be used for debug purpose only - * - * If the implementation does not have access to the exact cause codes, - * then it should return one of the values listed in RIL_LastCallFailCause, - * as the UI layer needs to distinguish these cases for tone generation or - * error notification. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - */ -#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18 - -/** - * RIL_REQUEST_SIGNAL_STRENGTH - * - * Requests current signal strength and associated information - * - * Must succeed if radio is on. - * - * "data" is NULL - * - * "response" is a const RIL_SignalStrength * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SIGNAL_STRENGTH 19 - -/** - * RIL_REQUEST_VOICE_REGISTRATION_STATE - * - * Request current registration state - * - * "data" is NULL - * "response" is a const RIL_VoiceRegistrationStateResponse * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20 - -/** - * RIL_REQUEST_DATA_REGISTRATION_STATE - * - * Request current DATA registration state - * - * "data" is NULL - * "response" is a const RIL_DataRegistrationStateResponse * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_DATA_REGISTRATION_STATE 21 - -/** - * RIL_REQUEST_OPERATOR - * - * Request current operator ONS or EONS - * - * "data" is NULL - * "response" is a "const char **" - * ((const char **)response)[0] is long alpha ONS or EONS - * or NULL if unregistered - * - * ((const char **)response)[1] is short alpha ONS or EONS - * or NULL if unregistered - * ((const char **)response)[2] is 5 or 6 digit numeric code (MCC + MNC) - * or NULL if unregistered - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_OPERATOR 22 - -/** - * RIL_REQUEST_RADIO_POWER - * - * Toggle radio on and off (for "airplane" mode) - * If the radio is is turned off/on the radio modem subsystem - * is expected return to an initialized state. For instance, - * any voice and data calls will be terminated and all associated - * lists emptied. - * - * "data" is int * - * ((int *)data)[0] is > 0 for "Radio On" - * ((int *)data)[0] is == 0 for "Radio Off" - * - * "response" is NULL - * - * Turn radio on if "on" > 0 - * Turn radio off if "on" == 0 - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * INVALID_STATE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * DEVICE_IN_USE - * OPERATION_NOT_ALLOWED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_RADIO_POWER 23 - -/** - * RIL_REQUEST_DTMF - * - * Send a DTMF tone - * - * If the implementation is currently playing a tone requested via - * RIL_REQUEST_DTMF_START, that tone should be cancelled and the new tone - * should be played instead - * - * "data" is a char * containing a single character with one of 12 values: 0-9,*,# - * "response" is NULL - * - * FIXME should this block/mute microphone? - * How does this interact with local DTMF feedback? - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_RESOURCES - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_DTMF_STOP, RIL_REQUEST_DTMF_START - * - */ -#define RIL_REQUEST_DTMF 24 - -/** - * RIL_REQUEST_SEND_SMS - * - * Send an SMS message - * - * "data" is const char ** - * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed - * by a length byte (as expected by TS 27.005) or NULL for default SMSC - * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string - * less the SMSC address - * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" - * - * "response" is a const RIL_SMS_Response * - * - * Based on the return error, caller decides to resend if sending sms - * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SMS_SEND_FAIL_RETRY - * FDN_CHECK_FAILURE - * NETWORK_REJECT - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * INVALID_SMS_FORMAT - * SYSTEM_ERR - * ENCODING_ERR - * INVALID_SMSC_ADDRESS - * MODEM_ERR - * NETWORK_ERR - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * MODE_NOT_SUPPORTED - * SIM_ABSENT - * - * FIXME how do we specify TP-Message-Reference if we need to resend? - */ -#define RIL_REQUEST_SEND_SMS 25 - - -/** - * RIL_REQUEST_SEND_SMS_EXPECT_MORE - * - * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS, - * except that more messages are expected to be sent soon. If possible, - * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command) - * - * "data" is const char ** - * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed - * by a length byte (as expected by TS 27.005) or NULL for default SMSC - * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string - * less the SMSC address - * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" - * - * "response" is a const RIL_SMS_Response * - * - * Based on the return error, caller decides to resend if sending sms - * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SMS_SEND_FAIL_RETRY - * NETWORK_REJECT - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * INVALID_SMS_FORMAT - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * FDN_CHECK_FAILURE - * MODEM_ERR - * NETWORK_ERR - * ENCODING_ERR - * INVALID_SMSC_ADDRESS - * OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * MODE_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26 - - -/** - * RIL_REQUEST_SETUP_DATA_CALL - * - * Setup a packet data connection. If RIL_Data_Call_Response_v6.status - * return success it is added to the list of data calls and a - * RIL_UNSOL_DATA_CALL_LIST_CHANGED is sent. The call remains in the - * list until RIL_REQUEST_DEACTIVATE_DATA_CALL is issued or the - * radio is powered off/on. This list is returned by RIL_REQUEST_DATA_CALL_LIST - * and RIL_UNSOL_DATA_CALL_LIST_CHANGED. - * - * The RIL is expected to: - * - Create one data call context. - * - Create and configure a dedicated interface for the context - * - The interface must be point to point. - * - The interface is configured with one or more addresses and - * is capable of sending and receiving packets. The prefix length - * of the addresses must be /32 for IPv4 and /128 for IPv6. - * - Must NOT change the linux routing table. - * - Support up to RIL_REQUEST_DATA_REGISTRATION_STATE response[5] - * number of simultaneous data call contexts. - * - * "data" is a const char ** - * ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2... - * for values above 2 this is RIL_RadioTechnology + 2. - * ((const char **)data)[1] is a RIL_DataProfile (support is optional) - * ((const char **)data)[2] is the APN to connect to if radio technology is GSM/UMTS. This APN will - * override the one in the profile. NULL indicates no APN overrride. - * ((const char **)data)[3] is the username for APN, or NULL - * ((const char **)data)[4] is the password for APN, or NULL - * ((const char **)data)[5] is the PAP / CHAP auth type. Values: - * 0 => PAP and CHAP is never performed. - * 1 => PAP may be performed; CHAP is never performed. - * 2 => CHAP may be performed; PAP is never performed. - * 3 => PAP / CHAP may be performed - baseband dependent. - * ((const char **)data)[6] is the non-roaming/home connection type to request. Must be one of the - * PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - * ((const char **)data)[7] is the roaming connection type to request. Must be one of the - * PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - * ((const char **)data)[8] is the bitmask of APN type in decimal string format. The - * bitmask will encapsulate the following values: - * ia,mms,agps,supl,hipri,fota,dun,ims,default. - * ((const char **)data)[9] is the bearer bitmask in decimal string format. Each bit is a - * RIL_RadioAccessFamily. "0" or NULL indicates all RATs. - * ((const char **)data)[10] is the boolean in string format indicating the APN setting was - * sent to the modem through RIL_REQUEST_SET_DATA_PROFILE earlier. - * ((const char **)data)[11] is the mtu size in bytes of the mobile interface to which - * the apn is connected. - * ((const char **)data)[12] is the MVNO type: - * possible values are "imsi", "gid", "spn". - * ((const char **)data)[13] is MVNO match data in string. Can be anything defined by the carrier. - * For example, - * SPN like: "A MOBILE", "BEN NL", etc... - * IMSI like: "302720x94", "2060188", etc... - * GID like: "4E", "33", etc... - * ((const char **)data)[14] is the boolean string indicating data roaming is allowed or not. "1" - * indicates data roaming is enabled by the user, "0" indicates disabled. - * - * "response" is a RIL_Data_Call_Response_v11 - * - * FIXME may need way to configure QoS settings - * - * Valid errors: - * SUCCESS should be returned on both success and failure of setup with - * the RIL_Data_Call_Response_v6.status containing the actual status. - * For all other errors the RIL_Data_Call_Resonse_v6 is ignored. - * - * Other errors could include: - * RADIO_NOT_AVAILABLE, OP_NOT_ALLOWED_BEFORE_REG_TO_NW, - * OP_NOT_ALLOWED_DURING_VOICE_CALL, REQUEST_NOT_SUPPORTED, - * INVALID_ARGUMENTS, INTERNAL_ERR, NO_MEMORY, NO_RESOURCES, - * CANCELLED and SIM_ABSENT - * - * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL - */ -#define RIL_REQUEST_SETUP_DATA_CALL 27 - - -/** - * RIL_REQUEST_SIM_IO - * - * Request SIM I/O operation. - * This is similar to the TS 27.007 "restricted SIM" operation - * where it assumes all of the EF selection will be done by the - * callee. - * - * "data" is a const RIL_SIM_IO_v6 * - * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL, - * or may specify a PIN2 for operations that require a PIN2 (eg - * updating FDN records) - * - * "response" is a const RIL_SIM_IO_Response * - * - * Arguments and responses that are unused for certain - * values of "command" should be ignored or set to NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_PIN2 - * SIM_PUK2 - * INVALID_SIM_STATE - * SIM_ERR - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_IO 28 - -/** - * RIL_REQUEST_SEND_USSD - * - * Send a USSD message - * - * If a USSD session already exists, the message should be sent in the - * context of that session. Otherwise, a new session should be created. - * - * The network reply should be reported via RIL_UNSOL_ON_USSD - * - * Only one USSD session may exist at a time, and the session is assumed - * to exist until: - * a) The android system invokes RIL_REQUEST_CANCEL_USSD - * b) The implementation sends a RIL_UNSOL_ON_USSD with a type code - * of "0" (USSD-Notify/no further action) or "2" (session terminated) - * - * "data" is a const char * containing the USSD request in UTF-8 format - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * FDN_CHECK_FAILURE - * USSD_MODIFIED_TO_DIAL - * USSD_MODIFIED_TO_SS - * USSD_MODIFIED_TO_USSD - * SIM_BUSY - * OPERATION_NOT_ALLOWED - * INVALID_ARGUMENTS - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * ABORTED - * SYSTEM_ERR - * INVALID_STATE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_CANCEL_USSD, RIL_UNSOL_ON_USSD - */ - -#define RIL_REQUEST_SEND_USSD 29 - -/** - * RIL_REQUEST_CANCEL_USSD - * - * Cancel the current USSD session if one exists - * - * "data" is null - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_BUSY - * OPERATION_NOT_ALLOWED - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_STATE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_CANCEL_USSD 30 - -/** - * RIL_REQUEST_GET_CLIR - * - * Gets current CLIR status - * "data" is NULL - * "response" is int * - * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 - * ((int *)data)[1] is "m" parameter from TS 27.007 7.7 - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * FDN_CHECK_FAILURE - * SYSTEM_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_GET_CLIR 31 - -/** - * RIL_REQUEST_SET_CLIR - * - * "data" is int * - * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * SYSTEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SET_CLIR 32 - -/** - * RIL_REQUEST_QUERY_CALL_FORWARD_STATUS - * - * "data" is const RIL_CallForwardInfo * - * - * "response" is const RIL_CallForwardInfo ** - * "response" points to an array of RIL_CallForwardInfo *'s, one for - * each distinct registered phone number. - * - * For example, if data is forwarded to +18005551212 and voice is forwarded - * to +18005559999, then two separate RIL_CallForwardInfo's should be returned - * - * If, however, both data and voice are forwarded to +18005551212, then - * a single RIL_CallForwardInfo can be returned with the service class - * set to "data + voice = 3") - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33 - - -/** - * RIL_REQUEST_SET_CALL_FORWARD - * - * Configure call forward rule - * - * "data" is const RIL_CallForwardInfo * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_STATE - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SET_CALL_FORWARD 34 - - -/** - * RIL_REQUEST_QUERY_CALL_WAITING - * - * Query current call waiting state - * - * "data" is const int * - * ((const int *)data)[0] is the TS 27.007 service class to query. - * "response" is a const int * - * ((const int *)response)[0] is 0 for "disabled" and 1 for "enabled" - * - * If ((const int *)response)[0] is = 1, then ((const int *)response)[1] - * must follow, with the TS 27.007 service class bit vector of services - * for which call waiting is enabled. - * - * For example, if ((const int *)response)[0] is 1 and - * ((const int *)response)[1] is 3, then call waiting is enabled for data - * and voice and disabled for everything else - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * FDN_CHECK_FAILURE - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_QUERY_CALL_WAITING 35 - - -/** - * RIL_REQUEST_SET_CALL_WAITING - * - * Configure current call waiting state - * - * "data" is const int * - * ((const int *)data)[0] is 0 for "disabled" and 1 for "enabled" - * ((const int *)data)[1] is the TS 27.007 service class bit vector of - * services to modify - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * INVALID_STATE - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SET_CALL_WAITING 36 - -/** - * RIL_REQUEST_SMS_ACKNOWLEDGE - * - * Acknowledge successful or failed receipt of SMS previously indicated - * via RIL_UNSOL_RESPONSE_NEW_SMS - * - * "data" is int * - * ((int *)data)[0] is 1 on successful receipt - * (basically, AT+CNMA=1 from TS 27.005 - * is 0 on failed receipt - * (basically, AT+CNMA=2 from TS 27.005) - * ((int *)data)[1] if data[0] is 0, this contains the failure cause as defined - * in TS 23.040, 9.2.3.22. Currently only 0xD3 (memory - * capacity exceeded) and 0xFF (unspecified error) are - * reported. - * - * "response" is NULL - * - * FIXME would like request that specified RP-ACK/RP-ERROR PDU - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SMS_ACKNOWLEDGE 37 - -/** - * RIL_REQUEST_GET_IMEI - DEPRECATED - * - * Get the device IMEI, including check digit - * - * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY - * Valid when RadioState is not RADIO_STATE_UNAVAILABLE - * - * "data" is NULL - * "response" is a const char * containing the IMEI - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ - -#define RIL_REQUEST_GET_IMEI 38 - -/** - * RIL_REQUEST_GET_IMEISV - DEPRECATED - * - * Get the device IMEISV, which should be two decimal digits - * - * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY - * Valid when RadioState is not RADIO_STATE_UNAVAILABLE - * - * "data" is NULL - * "response" is a const char * containing the IMEISV - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ - -#define RIL_REQUEST_GET_IMEISV 39 - - -/** - * RIL_REQUEST_ANSWER - * - * Answer incoming call - * - * Will not be called for WAITING calls. - * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE will be used in this case - * instead - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_ANSWER 40 - -/** - * RIL_REQUEST_DEACTIVATE_DATA_CALL - * - * Deactivate packet data connection and remove from the - * data call list if SUCCESS is returned. Any other return - * values should also try to remove the call from the list, - * but that may not be possible. In any event a - * RIL_REQUEST_RADIO_POWER off/on must clear the list. An - * RIL_UNSOL_DATA_CALL_LIST_CHANGED is not expected to be - * issued because of an RIL_REQUEST_DEACTIVATE_DATA_CALL. - * - * "data" is const char ** - * ((char**)data)[0] indicating CID - * ((char**)data)[1] indicating Disconnect Reason - * 0 => No specific reason specified - * 1 => Radio shutdown requested - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_CALL_ID - * INVALID_STATE - * INVALID_ARGUMENTS - * REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * SIM_ABSENT - * - * See also: RIL_REQUEST_SETUP_DATA_CALL - */ -#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41 - -/** - * RIL_REQUEST_QUERY_FACILITY_LOCK - * - * Query the status of a facility lock state - * - * "data" is const char ** - * ((const char **)data)[0] is the facility string code from TS 27.007 7.4 - * (eg "AO" for BAOC, "SC" for SIM lock) - * ((const char **)data)[1] is the password, or "" if not required - * ((const char **)data)[2] is the TS 27.007 service class bit vector of - * services to query - * ((const char **)data)[3] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * This is only applicable in the case of Fixed Dialing Numbers - * (FDN) requests. - * - * "response" is an int * - * ((const int *)response) 0 is the TS 27.007 service class bit vector of - * services for which the specified barring facility - * is active. "0" means "disabled for all" - * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_QUERY_FACILITY_LOCK 42 - -/** - * RIL_REQUEST_SET_FACILITY_LOCK - * - * Enable/disable one facility lock - * - * "data" is const char ** - * - * ((const char **)data)[0] = facility string code from TS 27.007 7.4 - * (eg "AO" for BAOC) - * ((const char **)data)[1] = "0" for "unlock" and "1" for "lock" - * ((const char **)data)[2] = password - * ((const char **)data)[3] = string representation of decimal TS 27.007 - * service class bit vector. Eg, the string - * "1" means "set this facility for voice services" - * ((const char **)data)[4] = AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. - * This is only applicable in the case of Fixed Dialing Numbers - * (FDN) requests. - * - * "response" is int * - * ((int *)response)[0] is the number of retries remaining, or -1 if unknown - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * INTERNAL_ERR - * NO_MEMORY - * MODEM_ERR - * INVALID_STATE - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_SET_FACILITY_LOCK 43 - -/** - * RIL_REQUEST_CHANGE_BARRING_PASSWORD - * - * Change call barring facility password - * - * "data" is const char ** - * - * ((const char **)data)[0] = facility string code from TS 27.007 7.4 - * (eg "AO" for BAOC) - * ((const char **)data)[1] = old password - * ((const char **)data)[2] = new password - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * INVALID_ARGUMENTS - * NO_MEMORY - * MODEM_ERR - * INTERNAL_ERR - * SYSTEM_ERR - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44 - -/** - * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE - * - * Query current network selectin mode - * - * "data" is NULL - * - * "response" is int * - * ((const int *)response)[0] is - * 0 for automatic selection - * 1 for manual selection - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45 - -/** - * RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC - * - * Specify that the network should be selected automatically - * - * "data" is NULL - * "response" is NULL - * - * This request must not respond until the new operator is selected - * and registered - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * ILLEGAL_SIM_OR_ME - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and - * no retries needed, such as illegal SIM or ME. - * - */ -#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46 - -/** - * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL - * - * Manually select a specified network. - * - * "data" is const char * specifying MCCMNC of network to select (eg "310170") - * "response" is NULL - * - * This request must not respond until the new operator is selected - * and registered - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * ILLEGAL_SIM_OR_ME - * OPERATION_NOT_ALLOWED - * INVALID_STATE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and - * no retries needed, such as illegal SIM or ME. - * - */ -#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47 - -/** - * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS - * - * Scans for available networks - * - * "data" is NULL - * "response" is const char ** that should be an array of n*4 strings, where - * n is the number of available networks - * For each available network: - * - * ((const char **)response)[n+0] is long alpha ONS or EONS - * ((const char **)response)[n+1] is short alpha ONS or EONS - * ((const char **)response)[n+2] is 5 or 6 digit numeric code (MCC + MNC) - * ((const char **)response)[n+3] is a string value of the status: - * "unknown" - * "available" - * "current" - * "forbidden" - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * ABORTED - * DEVICE_IN_USE - * INTERNAL_ERR - * NO_MEMORY - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * CANCELLED - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48 - -/** - * RIL_REQUEST_DTMF_START - * - * Start playing a DTMF tone. Continue playing DTMF tone until - * RIL_REQUEST_DTMF_STOP is received - * - * If a RIL_REQUEST_DTMF_START is received while a tone is currently playing, - * it should cancel the previous tone and play the new one. - * - * "data" is a char * - * ((char *)data)[0] is a single character with one of 12 values: 0-9,*,# - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_RESOURCES - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_STOP - */ -#define RIL_REQUEST_DTMF_START 49 - -/** - * RIL_REQUEST_DTMF_STOP - * - * Stop playing a currently playing DTMF tone. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * NO_MEMORY - * INVALID_ARGUMENTS - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_START - */ -#define RIL_REQUEST_DTMF_STOP 50 - -/** - * RIL_REQUEST_BASEBAND_VERSION - * - * Return string value indicating baseband version, eg - * response from AT+CGMR - * - * "data" is NULL - * "response" is const char * containing version string for log reporting - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * EMPTY_RECORD - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_BASEBAND_VERSION 51 - -/** - * RIL_REQUEST_SEPARATE_CONNECTION - * - * Separate a party from a multiparty call placing the multiparty call - * (less the specified party) on hold and leaving the specified party - * as the only other member of the current (active) call - * - * Like AT+CHLD=2x - * - * See TS 22.084 1.3.8.2 (iii) - * TS 22.030 6.5.5 "Entering "2X followed by send" - * TS 27.007 "AT+CHLD=2x" - * - * "data" is an int * - * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) "response" is NULL - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_ARGUMENTS - * INVALID_STATE - * NO_RESOURCES - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * INVALID_STATE - * OPERATION_NOT_ALLOWED - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SEPARATE_CONNECTION 52 - - -/** - * RIL_REQUEST_SET_MUTE - * - * Turn on or off uplink (microphone) mute. - * - * Will only be sent while voice call is active. - * Will always be reset to "disable mute" when a new voice call is initiated - * - * "data" is an int * - * (int *)data)[0] is 1 for "enable mute" and 0 for "disable mute" - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_ARGUMENTS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_SET_MUTE 53 - -/** - * RIL_REQUEST_GET_MUTE - * - * Queries the current state of the uplink mute setting - * - * "data" is NULL - * "response" is an int * - * (int *)response)[0] is 1 for "mute enabled" and 0 for "mute disabled" - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * SS_MODIFIED_TO_DIAL - * SS_MODIFIED_TO_USSD - * SS_MODIFIED_TO_SS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_GET_MUTE 54 - -/** - * RIL_REQUEST_QUERY_CLIP - * - * Queries the status of the CLIP supplementary service - * - * (for MMI code "*#30#") - * - * "data" is NULL - * "response" is an int * - * (int *)response)[0] is 1 for "CLIP provisioned" - * and 0 for "CLIP not provisioned" - * and 2 for "unknown, e.g. no network etc" - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * FDN_CHECK_FAILURE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_QUERY_CLIP 55 - -/** - * RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - Deprecated use the status - * field in RIL_Data_Call_Response_v6. - * - * Requests the failure cause code for the most recently failed PDP - * context or CDMA data connection active - * replaces RIL_REQUEST_LAST_PDP_FAIL_CAUSE - * - * "data" is NULL - * - * "response" is a "int *" - * ((int *)response)[0] is an integer cause code defined in TS 24.008 - * section 6.1.3.1.3 or close approximation - * - * If the implementation does not have access to the exact cause codes, - * then it should return one of the values listed in - * RIL_DataCallFailCause, as the UI layer needs to distinguish these - * cases for error notification - * and potential retries. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_LAST_CALL_FAIL_CAUSE - * - * Deprecated use the status field in RIL_Data_Call_Response_v6. - */ - -#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56 - -/** - * RIL_REQUEST_DATA_CALL_LIST - * - * Returns the data call list. An entry is added when a - * RIL_REQUEST_SETUP_DATA_CALL is issued and removed on a - * RIL_REQUEST_DEACTIVATE_DATA_CALL. The list is emptied - * when RIL_REQUEST_RADIO_POWER off/on is issued. - * - * "data" is NULL - * "response" is an array of RIL_Data_Call_Response_v6 - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * - * See also: RIL_UNSOL_DATA_CALL_LIST_CHANGED - */ - -#define RIL_REQUEST_DATA_CALL_LIST 57 - -/** - * RIL_REQUEST_RESET_RADIO - DEPRECATED - * - * Request a radio reset. The RIL implementation may postpone - * the reset until after this request is responded to if the baseband - * is presently busy. - * - * The request is DEPRECATED, use RIL_REQUEST_RADIO_POWER - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * REQUEST_NOT_SUPPORTED - */ - -#define RIL_REQUEST_RESET_RADIO 58 - -/** - * RIL_REQUEST_OEM_HOOK_RAW - * - * This request reserved for OEM-specific uses. It passes raw byte arrays - * back and forth. - * - * It can be invoked on the Java side from - * com.android.internal.telephony.Phone.invokeOemRilRequestRaw() - * - * "data" is a char * of bytes copied from the byte[] data argument in java - * "response" is a char * of bytes that will returned via the - * caller's "response" Message here: - * (byte[])(((AsyncResult)response.obj).result) - * - * An error response here will result in - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * Valid errors: - * All - */ - -#define RIL_REQUEST_OEM_HOOK_RAW 59 - -/** - * RIL_REQUEST_OEM_HOOK_STRINGS - * - * This request reserved for OEM-specific uses. It passes strings - * back and forth. - * - * It can be invoked on the Java side from - * com.android.internal.telephony.Phone.invokeOemRilRequestStrings() - * - * "data" is a const char **, representing an array of null-terminated UTF-8 - * strings copied from the "String[] strings" argument to - * invokeOemRilRequestStrings() - * - * "response" is a const char **, representing an array of null-terminated UTF-8 - * stings that will be returned via the caller's response message here: - * - * (String[])(((AsyncResult)response.obj).result) - * - * An error response here will result in - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * Valid errors: - * All - */ - -#define RIL_REQUEST_OEM_HOOK_STRINGS 60 - -/** - * RIL_REQUEST_SCREEN_STATE - DEPRECATED - * - * Indicates the current state of the screen. When the screen is off, the - * RIL should notify the baseband to suppress certain notifications (eg, - * signal strength and changes in LAC/CID or BID/SID/NID/latitude/longitude) - * in an effort to conserve power. These notifications should resume when the - * screen is on. - * - * Note this request is deprecated. Use RIL_REQUEST_SEND_DEVICE_STATE to report the device state - * to the modem and use RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER to turn on/off unsolicited - * response from the modem in different scenarios. - * - * "data" is int * - * ((int *)data)[0] is == 1 for "Screen On" - * ((int *)data)[0] is == 0 for "Screen Off" - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SCREEN_STATE 61 - - -/** - * RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION - * - * Enables/disables supplementary service related notifications - * from the network. - * - * Notifications are reported via RIL_UNSOL_SUPP_SVC_NOTIFICATION. - * - * "data" is int * - * ((int *)data)[0] is == 1 for notifications enabled - * ((int *)data)[0] is == 0 for notifications disabled - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_BUSY - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_UNSOL_SUPP_SVC_NOTIFICATION. - */ -#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62 - -/** - * RIL_REQUEST_WRITE_SMS_TO_SIM - * - * Stores a SMS message to SIM memory. - * - * "data" is RIL_SMS_WriteArgs * - * - * "response" is int * - * ((const int *)response)[0] is the record index where the message is stored. - * - * Valid errors: - * SUCCESS - * SIM_FULL - * INVALID_ARGUMENTS - * INVALID_SMS_FORMAT - * INTERNAL_ERR - * MODEM_ERR - * ENCODING_ERR - * NO_MEMORY - * NO_RESOURCES - * INVALID_MODEM_STATE - * OPERATION_NOT_ALLOWED - * INVALID_SMSC_ADDRESS - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_WRITE_SMS_TO_SIM 63 - -/** - * RIL_REQUEST_DELETE_SMS_ON_SIM - * - * Deletes a SMS message from SIM memory. - * - * "data" is int * - * ((int *)data)[0] is the record index of the message to delete. - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * SIM_FULL - * INVALID_ARGUMENTS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * MODEM_ERR - * NO_SUCH_ENTRY - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_DELETE_SMS_ON_SIM 64 - -/** - * RIL_REQUEST_SET_BAND_MODE - * - * Assign a specified band for RF configuration. - * - * "data" is int * - * ((int *)data)[0] is a RIL_RadioBandMode - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * See also: RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE - */ -#define RIL_REQUEST_SET_BAND_MODE 65 - -/** - * RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE - * - * Query the list of band mode supported by RF. - * - * "data" is NULL - * - * "response" is int * - * "response" points to an array of int's, the int[0] is the size of array; - * subsequent values are a list of RIL_RadioBandMode listing supported modes. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * See also: RIL_REQUEST_SET_BAND_MODE - */ -#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66 - -/** - * RIL_REQUEST_STK_GET_PROFILE - * - * Requests the profile of SIM tool kit. - * The profile indicates the SAT/USAT features supported by ME. - * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111 - * - * "data" is NULL - * - * "response" is a const char * containing SAT/USAT profile - * in hexadecimal format string starting with first byte of terminal profile - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_STK_GET_PROFILE 67 - -/** - * RIL_REQUEST_STK_SET_PROFILE - * - * Download the STK terminal profile as part of SIM initialization - * procedure - * - * "data" is a const char * containing SAT/USAT profile - * in hexadecimal format string starting with first byte of terminal profile - * - * "response" is NULL - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_STK_SET_PROFILE 68 - -/** - * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND - * - * Requests to send a SAT/USAT envelope command to SIM. - * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 - * - * "data" is a const char * containing SAT/USAT command - * in hexadecimal format string starting with command tag - * - * "response" is a const char * containing SAT/USAT response - * in hexadecimal format string starting with first byte of response - * (May be NULL) - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * SIM_BUSY - * OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69 - -/** - * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE - * - * Requests to send a terminal response to SIM for a received - * proactive command - * - * "data" is a const char * containing SAT/USAT response - * in hexadecimal format string starting with first byte of response data - * - * "response" is NULL - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * RIL_E_OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70 - -/** - * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM - * - * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has - * been initialized by ME already. (We could see the call has been in the 'call - * list') So, STK application needs to accept/reject the call according as user - * operations. - * - * "data" is int * - * ((int *)data)[0] is > 0 for "accept" the call setup - * ((int *)data)[0] is == 0 for "reject" the call setup - * - * "response" is NULL - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * RIL_E_OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71 - -/** - * RIL_REQUEST_EXPLICIT_CALL_TRANSFER - * - * Connects the two calls and disconnects the subscriber from both calls. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * INVALID_STATE - * NO_RESOURCES - * NO_MEMORY - * INVALID_ARGUMENTS - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * INVALID_STATE - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72 - -/** - * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE - * - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * - * "data" is int * which is RIL_PreferredNetworkType - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * OPERATION_NOT_ALLOWED - * MODE_NOT_SUPPORTED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73 - -/** - * RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE - * - * Query the preferred network type (CS/PS domain, RAT, and operation mode) - * for searching and registering - * - * "data" is NULL - * - * "response" is int * - * ((int *)reponse)[0] is == RIL_PreferredNetworkType - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * See also: RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE - */ -#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74 - -/** - * RIL_REQUEST_NEIGHBORING_CELL_IDS - * - * Request neighboring cell id in GSM network - * - * "data" is NULL - * "response" must be a " const RIL_NeighboringCell** " - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NO_NETWORK_FOUND - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75 - -/** - * RIL_REQUEST_SET_LOCATION_UPDATES - * - * Enables/disables network state change notifications due to changes in - * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA). - * Basically +CREG=2 vs. +CREG=1 (TS 27.007). - * - * Note: The RIL implementation should default to "updates enabled" - * when the screen is on and "updates disabled" when the screen is off. - * - * "data" is int * - * ((int *)data)[0] is == 1 for updates enabled (+CREG=2) - * ((int *)data)[0] is == 0 for updates disabled (+CREG=1) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED - */ -#define RIL_REQUEST_SET_LOCATION_UPDATES 76 - -/** - * RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE - * - * Request to set the location where the CDMA subscription shall - * be retrieved - * - * "data" is int * - * ((int *)data)[0] is == RIL_CdmaSubscriptionSource - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_ABSENT - * SUBSCRIPTION_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE - */ -#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77 - -/** - * RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE - * - * Request to set the roaming preferences in CDMA - * - * "data" is int * - * ((int *)data)[0] is == 0 for Home Networks only, as defined in PRL - * ((int *)data)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL - * ((int *)data)[0] is == 2 for Roaming on Any Network, as defined in the PRL - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78 - -/** - * RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE - * - * Request the actual setting of the roaming preferences in CDMA in the modem - * - * "data" is NULL - * - * "response" is int * - * ((int *)response)[0] is == 0 for Home Networks only, as defined in PRL - * ((int *)response)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL - * ((int *)response)[0] is == 2 for Roaming on Any Network, as defined in the PRL - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79 - -/** - * RIL_REQUEST_SET_TTY_MODE - * - * Request to set the TTY mode - * - * "data" is int * - * ((int *)data)[0] is == 0 for TTY off - * ((int *)data)[0] is == 1 for TTY Full - * ((int *)data)[0] is == 2 for TTY HCO (hearing carryover) - * ((int *)data)[0] is == 3 for TTY VCO (voice carryover) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_ARGUMENTS - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SET_TTY_MODE 80 - -/** - * RIL_REQUEST_QUERY_TTY_MODE - * - * Request the setting of TTY mode - * - * "data" is NULL - * - * "response" is int * - * ((int *)response)[0] is == 0 for TTY off - * ((int *)response)[0] is == 1 for TTY Full - * ((int *)response)[0] is == 2 for TTY HCO (hearing carryover) - * ((int *)response)[0] is == 3 for TTY VCO (voice carryover) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_QUERY_TTY_MODE 81 - -/** - * RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE - * - * Request to set the preferred voice privacy mode used in voice - * scrambling - * - * "data" is int * - * ((int *)data)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) - * ((int *)data)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_CALL_ID - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82 - -/** - * RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE - * - * Request the setting of preferred voice privacy mode - * - * "data" is NULL - * - * "response" is int * - * ((int *)response)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) - * ((int *)response)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * MODEM_ERR - * INTERNAL_ERR - * NO_MEMORY - * INVALID_ARGUMENTS - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83 - -/** - * RIL_REQUEST_CDMA_FLASH - * - * Send FLASH - * - * "data" is const char * - * ((const char *)data)[0] is a FLASH string - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * INVALID_STATE - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_FLASH 84 - -/** - * RIL_REQUEST_CDMA_BURST_DTMF - * - * Send DTMF string - * - * "data" is const char ** - * ((const char **)data)[0] is a DTMF string - * ((const char **)data)[1] is the DTMF ON length in milliseconds, or 0 to use - * default - * ((const char **)data)[2] is the DTMF OFF length in milliseconds, or 0 to use - * default - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * MODEM_ERR - * INTERNAL_ERR - * INVALID_CALL_ID - * NO_RESOURCES - * CANCELLED - * OPERATION_NOT_ALLOWED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_BURST_DTMF 85 - -/** - * RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY - * - * Takes a 26 digit string (20 digit AKEY + 6 digit checksum). - * If the checksum is valid the 20 digit AKEY is written to NV, - * replacing the existing AKEY no matter what it was before. - * - * "data" is const char * - * ((const char *)data)[0] is a 26 digit string (ASCII digits '0'-'9') - * where the last 6 digits are a checksum of the - * first 20, as specified in TR45.AHAG - * "Common Cryptographic Algorithms, Revision D.1 - * Section 2.2" - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86 - -/** - * RIL_REQUEST_CDMA_SEND_SMS - * - * Send a CDMA SMS message - * - * "data" is const RIL_CDMA_SMS_Message * - * - * "response" is a const RIL_SMS_Response * - * - * Based on the return error, caller decides to resend if sending sms - * fails. The CDMA error class is derived as follows, - * SUCCESS is error class 0 (no error) - * SMS_SEND_FAIL_RETRY is error class 2 (temporary failure) - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SMS_SEND_FAIL_RETRY - * NETWORK_REJECT - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * INVALID_SMS_FORMAT - * SYSTEM_ERR - * FDN_CHECK_FAILURE - * MODEM_ERR - * NETWORK_ERR - * ENCODING_ERR - * INVALID_SMSC_ADDRESS - * OPERATION_NOT_ALLOWED - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * MODE_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_CDMA_SEND_SMS 87 - -/** - * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE - * - * Acknowledge the success or failure in the receipt of SMS - * previously indicated via RIL_UNSOL_RESPONSE_CDMA_NEW_SMS - * - * "data" is const RIL_CDMA_SMS_Ack * - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_SMS_TO_ACK - * INVALID_STATE - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * MODEM_ERR - * INVALID_STATE - * OPERATION_NOT_ALLOWED - * NETWORK_NOT_READY - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88 - -/** - * RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG - * - * Request the setting of GSM/WCDMA Cell Broadcast SMS config. - * - * "data" is NULL - * - * "response" is a const RIL_GSM_BroadcastSmsConfigInfo ** - * "responselen" is count * sizeof (RIL_GSM_BroadcastSmsConfigInfo *) - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * NO_RESOURCES - * MODEM_ERR - * SYSTEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89 - -/** - * RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG - * - * Set GSM/WCDMA Cell Broadcast SMS config - * - * "data" is a const RIL_GSM_BroadcastSmsConfigInfo ** - * "datalen" is count * sizeof(RIL_GSM_BroadcastSmsConfigInfo *) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * SYSTEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90 - -/** - * RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION - * -* Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS - * - * "data" is const int * - * (const int *)data[0] indicates to activate or turn off the - * reception of GSM/WCDMA Cell Broadcast SMS, 0-1, - * 0 - Activate, 1 - Turn off - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * REQUEST_RATE_LIMITED -* MODEM_ERR -* INTERNAL_ERR -* NO_RESOURCES -* CANCELLED -* INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91 - -/** - * RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG - * - * Request the setting of CDMA Broadcast SMS config - * - * "data" is NULL - * - * "response" is a const RIL_CDMA_BroadcastSmsConfigInfo ** - * "responselen" is count * sizeof (RIL_CDMA_BroadcastSmsConfigInfo *) - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * NO_RESOURCES - * MODEM_ERR - * SYSTEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92 - -/** - * RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG - * - * Set CDMA Broadcast SMS config - * - * "data" is a const RIL_CDMA_BroadcastSmsConfigInfo ** - * "datalen" is count * sizeof(const RIL_CDMA_BroadcastSmsConfigInfo *) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * SYSTEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93 - -/** - * RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION - * - * Enable or disable the reception of CDMA Broadcast SMS - * - * "data" is const int * - * (const int *)data[0] indicates to activate or turn off the - * reception of CDMA Broadcast SMS, 0-1, - * 0 - Activate, 1 - Turn off - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_STATE - * INVALID_ARGUMENTS - * NO_MEMORY - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94 - -/** - * RIL_REQUEST_CDMA_SUBSCRIPTION - * - * Request the device MDN / H_SID / H_NID. - * - * The request is only allowed when CDMA subscription is available. When CDMA - * subscription is changed, application layer should re-issue the request to - * update the subscription information. - * - * If a NULL value is returned for any of the device id, it means that error - * accessing the device. - * - * "response" is const char ** - * ((const char **)response)[0] is MDN if CDMA subscription is available - * ((const char **)response)[1] is a comma separated list of H_SID (Home SID) if - * CDMA subscription is available, in decimal format - * ((const char **)response)[2] is a comma separated list of H_NID (Home NID) if - * CDMA subscription is available, in decimal format - * ((const char **)response)[3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available - * ((const char **)response)[4] is PRL version if CDMA subscription is available - * - * Valid errors: - * SUCCESS - * RIL_E_SUBSCRIPTION_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * - */ - -#define RIL_REQUEST_CDMA_SUBSCRIPTION 95 - -/** - * RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM - * - * Stores a CDMA SMS message to RUIM memory. - * - * "data" is RIL_CDMA_SMS_WriteArgs * - * - * "response" is int * - * ((const int *)response)[0] is the record index where the message is stored. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_FULL - * INVALID_ARGUMENTS - * INVALID_SMS_FORMAT - * INTERNAL_ERR - * MODEM_ERR - * ENCODING_ERR - * NO_MEMORY - * NO_RESOURCES - * INVALID_MODEM_STATE - * OPERATION_NOT_ALLOWED - * INVALID_SMSC_ADDRESS - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96 - -/** - * RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM - * - * Deletes a CDMA SMS message from RUIM memory. - * - * "data" is int * - * ((int *)data)[0] is the record index of the message to delete. - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * MODEM_ERR - * NO_SUCH_ENTRY - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97 - -/** - * RIL_REQUEST_DEVICE_IDENTITY - * - * Request the device ESN / MEID / IMEI / IMEISV. - * - * The request is always allowed and contains GSM and CDMA device identity; - * it substitutes the deprecated requests RIL_REQUEST_GET_IMEI and - * RIL_REQUEST_GET_IMEISV. - * - * If a NULL value is returned for any of the device id, it means that error - * accessing the device. - * - * When CDMA subscription is changed the ESN/MEID may change. The application - * layer should re-issue the request to update the device identity in this case. - * - * "response" is const char ** - * ((const char **)response)[0] is IMEI if GSM subscription is available - * ((const char **)response)[1] is IMEISV if GSM subscription is available - * ((const char **)response)[2] is ESN if CDMA subscription is available - * ((const char **)response)[3] is MEID if CDMA subscription is available - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_DEVICE_IDENTITY 98 - -/** - * RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE - * - * Request the radio's system selection module to exit emergency - * callback mode. RIL will not respond with SUCCESS until the modem has - * completely exited from Emergency Callback Mode. - * - * "data" is NULL - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99 - -/** - * RIL_REQUEST_GET_SMSC_ADDRESS - * - * Queries the default Short Message Service Center address on the device. - * - * "data" is NULL - * - * "response" is const char * containing the SMSC address. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * REQUEST_RATE_LIMITED - * SYSTEM_ERR - * INTERNAL_ERR - * MODEM_ERR - * INVALID_ARGUMENTS - * INVALID_MODEM_STATE - * NOT_PROVISIONED - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * - */ -#define RIL_REQUEST_GET_SMSC_ADDRESS 100 - -/** - * RIL_REQUEST_SET_SMSC_ADDRESS - * - * Sets the default Short Message Service Center address on the device. - * - * "data" is const char * containing the SMSC address. - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * INVALID_SMS_FORMAT - * NO_MEMORY - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * NO_RESOURCES - * INTERNAL_ERR - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_SET_SMSC_ADDRESS 101 - -/** - * RIL_REQUEST_REPORT_SMS_MEMORY_STATUS - * - * Indicates whether there is storage available for new SMS messages. - * - * "data" is int * - * ((int *)data)[0] is 1 if memory is available for storing new messages - * is 0 if memory capacity is exceeded - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INVALID_ARGUMENTS - * NO_MEMORY - * INVALID_STATE - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102 - -/** - * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING - * - * Indicates that the StkSerivce is running and is - * ready to receive RIL_UNSOL_STK_XXXXX commands. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103 - -/** - * RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE - * - * Request to query the location where the CDMA subscription shall - * be retrieved - * - * "data" is NULL - * - * "response" is int * - * ((int *)data)[0] is == RIL_CdmaSubscriptionSource - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SUBSCRIPTION_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - * See also: RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE - */ -#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104 - -/** - * RIL_REQUEST_ISIM_AUTHENTICATION - * - * Request the ISIM application on the UICC to perform AKA - * challenge/response algorithm for IMS authentication - * - * "data" is a const char * containing the challenge string in Base64 format - * "response" is a const char * containing the response in Base64 format - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_ISIM_AUTHENTICATION 105 - -/** - * RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU - * - * Acknowledge successful or failed receipt of SMS previously indicated - * via RIL_UNSOL_RESPONSE_NEW_SMS, including acknowledgement TPDU to send - * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU. - * - * "data" is const char ** - * ((const char **)data)[0] is "1" on successful receipt (send RP-ACK) - * is "0" on failed receipt (send RP-ERROR) - * ((const char **)data)[1] is the acknowledgement TPDU in hexadecimal format - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106 - -/** - * RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS - * - * Requests to send a SAT/USAT envelope command to SIM. - * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111. - * - * This request has one difference from RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: - * the SW1 and SW2 status bytes from the UICC response are returned along with - * the response data, using the same structure as RIL_REQUEST_SIM_IO. - * - * The RIL implementation shall perform the normal processing of a '91XX' - * response in SW1/SW2 to retrieve the pending proactive command and send it - * as an unsolicited response, as RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND does. - * - * "data" is a const char * containing the SAT/USAT command - * in hexadecimal format starting with command tag - * - * "response" is a const RIL_SIM_IO_Response * - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) - * SIM_BUSY - * OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107 - -/** - * RIL_REQUEST_VOICE_RADIO_TECH - * - * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only - * when radio state is not RADIO_STATE_UNAVAILABLE - * - * "data" is NULL - * "response" is int * - * ((int *) response)[0] is of type const RIL_RadioTechnology - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_VOICE_RADIO_TECH 108 - -/** - * RIL_REQUEST_GET_CELL_INFO_LIST - * - * Request all of the current cell information known to the radio. The radio - * must a list of all current cells, including the neighboring cells. If for a particular - * cell information isn't known then the appropriate unknown value will be returned. - * This does not cause or change the rate of RIL_UNSOL_CELL_INFO_LIST. - * - * "data" is NULL - * - * "response" is an array of RIL_CellInfo_v12. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NO_NETWORK_FOUND - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_GET_CELL_INFO_LIST 109 - -/** - * RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE - * - * Sets the minimum time between when RIL_UNSOL_CELL_INFO_LIST should be invoked. - * A value of 0, means invoke RIL_UNSOL_CELL_INFO_LIST when any of the reported - * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue - * a RIL_UNSOL_CELL_INFO_LIST. - * - * "data" is int * - * ((int *)data)[0] is minimum time in milliseconds - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 - -/** - * RIL_REQUEST_SET_INITIAL_ATTACH_APN - * - * Set an apn to initial attach network - * - * "data" is a const char ** - * ((const char **)data)[0] is the APN to connect if radio technology is LTE - * ((const char **)data)[1] is the connection type to request must be one of the - * PDP_type values in TS 27.007 section 10.1.1. - * For example, "IP", "IPV6", "IPV4V6", or "PPP". - * ((const char **)data)[2] is the PAP / CHAP auth type. Values: - * 0 => PAP and CHAP is never performed. - * 1 => PAP may be performed; CHAP is never performed. - * 2 => CHAP may be performed; PAP is never performed. - * 3 => PAP / CHAP may be performed - baseband dependent. - * ((const char **)data)[3] is the username for APN, or NULL - * ((const char **)data)[4] is the password for APN, or NULL - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * SUBSCRIPTION_NOT_AVAILABLE - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111 - -/** - * RIL_REQUEST_IMS_REGISTRATION_STATE - * - * This message is DEPRECATED and shall be removed in a future release (target: 2018); - * instead, provide IMS registration status via an IMS Service. - * - * Request current IMS registration state - * - * "data" is NULL - * - * "response" is int * - * ((int *)response)[0] is registration state: - * 0 - Not registered - * 1 - Registered - * - * If ((int*)response)[0] is = 1, then ((int *) response)[1] - * must follow with IMS SMS format: - * - * ((int *) response)[1] is of type RIL_RadioTechnologyFamily - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_IMS_REGISTRATION_STATE 112 - -/** - * RIL_REQUEST_IMS_SEND_SMS - * - * Send a SMS message over IMS - * - * "data" is const RIL_IMS_SMS_Message * - * - * "response" is a const RIL_SMS_Response * - * - * Based on the return error, caller decides to resend if sending sms - * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. - * In case of retry, data is encoded based on Voice Technology available. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SMS_SEND_FAIL_RETRY - * FDN_CHECK_FAILURE - * NETWORK_REJECT - * INVALID_ARGUMENTS - * INVALID_STATE - * NO_MEMORY - * INVALID_SMS_FORMAT - * SYSTEM_ERR - * REQUEST_RATE_LIMITED - * MODEM_ERR - * NETWORK_ERR - * ENCODING_ERR - * INVALID_SMSC_ADDRESS - * OPERATION_NOT_ALLOWED - * INTERNAL_ERR - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_IMS_SEND_SMS 113 - -/** - * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC - * - * Request APDU exchange on the basic channel. This command reflects TS 27.007 - * "generic SIM access" operation (+CSIM). The modem must ensure proper function - * of GSM/CDMA, and filter commands appropriately. It should filter - * channel management and SELECT by DF name commands. - * - * "data" is a const RIL_SIM_APDU * - * "sessionid" field should be ignored. - * - * "response" is a const RIL_SIM_IO_Response * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114 - -/** - * RIL_REQUEST_SIM_OPEN_CHANNEL - * - * Open a new logical channel and select the given application. This command - * reflects TS 27.007 "open logical channel" operation (+CCHO). This request - * also specifies the P2 parameter (described in ISO 7816-4). - * - * "data" is a const RIL_OpenChannelParam * - * - * "response" is int * - * ((int *)data)[0] contains the session id of the logical channel. - * ((int *)data)[1] onwards may optionally contain the select response for the - * open channel command with one byte per integer. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * MISSING_RESOURCE - * NO_SUCH_ELEMENT - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * SIM_ERR - * INVALID_SIM_STATE - * MISSING_RESOURCE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_OPEN_CHANNEL 115 - -/** - * RIL_REQUEST_SIM_CLOSE_CHANNEL - * - * Close a previously opened logical channel. This command reflects TS 27.007 - * "close logical channel" operation (+CCHC). - * - * "data" is int * - * ((int *)data)[0] is the session id of logical the channel to close. - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116 - -/** - * RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL - * - * Exchange APDUs with a UICC over a previously opened logical channel. This - * command reflects TS 27.007 "generic logical channel access" operation - * (+CGLA). The modem should filter channel management and SELECT by DF name - * commands. - * - * "data" is a const RIL_SIM_APDU* - * - * "response" is a const RIL_SIM_IO_Response * - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117 - -/** - * RIL_REQUEST_NV_READ_ITEM - * - * Read one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. - * This is used for device configuration by some CDMA operators. - * - * "data" is a const RIL_NV_ReadItem * - * - * "response" is const char * containing the contents of the NV item - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_NV_READ_ITEM 118 - -/** - * RIL_REQUEST_NV_WRITE_ITEM - * - * Write one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. - * This is used for device configuration by some CDMA operators. - * - * "data" is a const RIL_NV_WriteItem * - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_NV_WRITE_ITEM 119 - -/** - * RIL_REQUEST_NV_WRITE_CDMA_PRL - * - * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. - * This is used for device configuration by some CDMA operators. - * - * "data" is a const char * containing the PRL as a byte array - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120 - -/** - * RIL_REQUEST_NV_RESET_CONFIG - * - * Reset the radio NV configuration to the factory state. - * This is used for device configuration by some CDMA operators. - * - * "data" is int * - * ((int *)data)[0] is 1 to reload all NV items - * ((int *)data)[0] is 2 for erase NV reset (SCRTN) - * ((int *)data)[0] is 3 for factory reset (RTN) - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_NV_RESET_CONFIG 121 - - /** RIL_REQUEST_SET_UICC_SUBSCRIPTION - * FIXME This API needs to have more documentation. - * - * Selection/de-selection of a subscription from a SIM card - * "data" is const RIL_SelectUiccSub* - - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * SUBSCRIPTION_NOT_SUPPORTED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122 - -/** - * RIL_REQUEST_ALLOW_DATA - * - * Tells the modem whether data calls are allowed or not - * - * "data" is int * - * FIXME slotId and aid will be added. - * ((int *)data)[0] is == 0 to allow data calls - * ((int *)data)[0] is == 1 to disallow data calls - * - * "response" is NULL - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * INVALID_ARGUMENTS - * DEVICE_IN_USE - * INVALID_MODEM_STATE - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_ALLOW_DATA 123 - -/** - * RIL_REQUEST_GET_HARDWARE_CONFIG - * - * Request all of the current hardware (modem and sim) associated - * with the RIL. - * - * "data" is NULL - * - * "response" is an array of RIL_HardwareConfig. - * - * Valid errors: - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_GET_HARDWARE_CONFIG 124 - -/** - * RIL_REQUEST_SIM_AUTHENTICATION - * - * Returns the response of SIM Authentication through RIL to a - * challenge request. - * - * "data" Base64 encoded string containing challenge: - * int authContext; P2 value of authentication command, see P2 parameter in - * 3GPP TS 31.102 7.1.2 - * char *authData; the challenge string in Base64 format, see 3GPP - * TS 31.102 7.1.2 - * char *aid; AID value, See ETSI 102.221 8.1 and 101.220 4, - * NULL if no value - * - * "response" Base64 encoded strings containing response: - * int sw1; Status bytes per 3GPP TS 31.102 section 7.3 - * int sw2; - * char *simResponse; Response in Base64 format, see 3GPP TS 31.102 7.1.2 - * - * Valid errors: - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * INVALID_MODEM_STATE - * INVALID_ARGUMENTS - * SIM_ERR - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_SIM_AUTHENTICATION 125 - -/** - * RIL_REQUEST_GET_DC_RT_INFO - * - * The request is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO - * Requests the Data Connection Real Time Info - * - * "data" is NULL - * - * "response" is the most recent RIL_DcRtInfo - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * - * See also: RIL_UNSOL_DC_RT_INFO_CHANGED - */ -#define RIL_REQUEST_GET_DC_RT_INFO 126 - -/** - * RIL_REQUEST_SET_DC_RT_INFO_RATE - * - * The request is DEPRECATED - * This is the minimum number of milliseconds between successive - * RIL_UNSOL_DC_RT_INFO_CHANGED messages and defines the highest rate - * at which RIL_UNSOL_DC_RT_INFO_CHANGED's will be sent. A value of - * 0 means send as fast as possible. - * - * "data" The number of milliseconds as an int - * - * "response" is null - * - * Valid errors: - * SUCCESS must not fail - */ -#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127 - -/** - * RIL_REQUEST_SET_DATA_PROFILE - * - * Set data profile in modem - * Modem should erase existed profiles from framework, and apply new profiles - * "data" is a const RIL_DataProfileInfo ** - * "datalen" is count * sizeof(const RIL_DataProfileInfo *) - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * SUBSCRIPTION_NOT_AVAILABLE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_SET_DATA_PROFILE 128 - -/** - * RIL_REQUEST_SHUTDOWN - * - * Device is shutting down. All further commands are ignored - * and RADIO_NOT_AVAILABLE must be returned. - * - * "data" is null - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SHUTDOWN 129 - -/** - * RIL_REQUEST_GET_RADIO_CAPABILITY - * - * Used to get phone radio capablility. - * - * "data" is the RIL_RadioCapability structure - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * INVALID_STATE - * REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_GET_RADIO_CAPABILITY 130 - -/** - * RIL_REQUEST_SET_RADIO_CAPABILITY - * - * Used to set the phones radio capability. Be VERY careful - * using this request as it may cause some vendor modems to reset. Because - * of the possible modem reset any RIL commands after this one may not be - * processed. - * - * "data" is the RIL_RadioCapability structure - * - * "response" is the RIL_RadioCapability structure, used to feedback return status - * - * Valid errors: - * SUCCESS means a RIL_UNSOL_RADIO_CAPABILITY will be sent within 30 seconds. - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * MODEM_ERR - * INVALID_STATE - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_RADIO_CAPABILITY 131 - -/** - * RIL_REQUEST_START_LCE - * - * Start Link Capacity Estimate (LCE) service if supported by the radio. - * - * "data" is const int * - * ((const int*)data)[0] specifies the desired reporting interval (ms). - * ((const int*)data)[1] specifies the LCE service mode. 1: PULL; 0: PUSH. - * - * "response" is the RIL_LceStatusInfo. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * LCE_NOT_SUPPORTED - * INTERNAL_ERR - * REQUEST_NOT_SUPPORTED - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * SIM_ABSENT - */ -#define RIL_REQUEST_START_LCE 132 - -/** - * RIL_REQUEST_STOP_LCE - * - * Stop Link Capacity Estimate (LCE) service, the STOP operation should be - * idempotent for the radio modem. - * - * "response" is the RIL_LceStatusInfo. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * LCE_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_STOP_LCE 133 - -/** - * RIL_REQUEST_PULL_LCEDATA - * - * Pull LCE service for capacity information. - * - * "response" is the RIL_LceDataInfo. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * LCE_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - */ -#define RIL_REQUEST_PULL_LCEDATA 134 - -/** - * RIL_REQUEST_GET_ACTIVITY_INFO - * - * Get modem activity information for power consumption estimation. - * - * Request clear-on-read statistics information that is used for - * estimating the per-millisecond power consumption of the cellular - * modem. - * - * "data" is null - * "response" is const RIL_ActivityStatsInfo * - * - * Valid errors: - * - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * MODEM_ERR - * NOT_PROVISIONED - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES CANCELLED - */ -#define RIL_REQUEST_GET_ACTIVITY_INFO 135 - -/** - * RIL_REQUEST_SET_CARRIER_RESTRICTIONS - * - * Set carrier restrictions for this sim slot. Expected modem behavior: - * If never receives this command - * - Must allow all carriers - * Receives this command with data being NULL - * - Must allow all carriers. If a previously allowed SIM is present, modem must not reload - * the SIM. If a previously disallowed SIM is present, reload the SIM and notify Android. - * Receives this command with a list of carriers - * - Only allow specified carriers, persist across power cycles and FDR. If a present SIM - * is in the allowed list, modem must not reload the SIM. If a present SIM is *not* in - * the allowed list, modem must detach from the registered network and only keep emergency - * service, and notify Android SIM refresh reset with new SIM state being - * RIL_CARDSTATE_RESTRICTED. Emergency service must be enabled. - * - * "data" is const RIL_CarrierRestrictions * - * A list of allowed carriers and possibly a list of excluded carriers. - * If data is NULL, means to clear previous carrier restrictions and allow all carriers - * - * "response" is int * - * ((int *)data)[0] contains the number of allowed carriers which have been set correctly. - * On success, it should match the length of list data->allowed_carriers. - * If data is NULL, the value must be 0. - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_INVALID_ARGUMENTS - * RIL_E_RADIO_NOT_AVAILABLE - * RIL_E_REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS 136 - -/** - * RIL_REQUEST_GET_CARRIER_RESTRICTIONS - * - * Get carrier restrictions for this sim slot. Expected modem behavior: - * Return list of allowed carriers, or null if all carriers are allowed. - * - * "data" is NULL - * - * "response" is const RIL_CarrierRestrictions *. - * If response is NULL, it means all carriers are allowed. - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE - * RIL_E_REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS 137 - -/** - * RIL_REQUEST_SEND_DEVICE_STATE - * - * Send the updated device state. - * Modem can perform power saving based on the provided device state. - * "data" is const int * - * ((const int*)data)[0] A RIL_DeviceStateType that specifies the device state type. - * ((const int*)data)[1] Specifies the state. See RIL_DeviceStateType for the definition of each - * type. - * - * "datalen" is count * sizeof(const RIL_DeviceState *) - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * INVALID_ARGUMENTS - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SEND_DEVICE_STATE 138 - -/** - * RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER - * - * Set the unsolicited response filter - * This is used to prevent unnecessary application processor - * wake up for power saving purposes by suppressing the - * unsolicited responses in certain scenarios. - * - * "data" is an int * - * - * ((int *)data)[0] is a 32-bit bitmask of RIL_UnsolicitedResponseFilter - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * INVALID_ARGUMENTS (e.g. the requested filter doesn't exist) - * RADIO_NOT_AVAILABLE (radio resetting) - * NO_MEMORY - * INTERNAL_ERR - * SYSTEM_ERR - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER 139 - - /** - * RIL_REQUEST_SET_SIM_CARD_POWER - * - * Set SIM card power up or down - * - * Request is equivalent to inserting and removing the card, with - * an additional effect where the ability to detect card removal/insertion - * is disabled when the SIM card is powered down. - * - * This will generate RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED - * as if the SIM had been inserted or removed. - * - * "data" is int * - * ((int *)data)[0] is 1 for "SIM POWER UP" - * ((int *)data)[0] is 0 for "SIM POWER DOWN" - * - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * REQUEST_NOT_SUPPORTED - * SIM_ABSENT - * INVALID_ARGUMENTS - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_SIM_CARD_POWER 140 - -/** - * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION - * - * Provide Carrier specific information to the modem that will be used to - * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier - * switch and everytime we receive a new certificate. - * - * "data" is the RIL_CarrierInfoForImsiEncryption * structure. - * - * "response" is NULL - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE - * SIM_ABSENT - * RIL_E_REQUEST_NOT_SUPPORTED - * INVALID_ARGUMENTS - * MODEM_INTERNAL_FAILURE - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION 141 - -/** - * RIL_REQUEST_START_NETWORK_SCAN - * - * Starts a new network scan - * - * Request to start a network scan with specified radio access networks with frequency bands and/or - * channels. - * - * "data" is a const RIL_NetworkScanRequest *. - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * OPERATION_NOT_ALLOWED - * DEVICE_IN_USE - * INTERNAL_ERR - * NO_MEMORY - * MODEM_ERR - * INVALID_ARGUMENTS - * REQUEST_NOT_SUPPORTED - * NO_RESOURCES - * CANCELLED - * - */ -#define RIL_REQUEST_START_NETWORK_SCAN 142 - -/** - * RIL_REQUEST_STOP_NETWORK_SCAN - * - * Stops an ongoing network scan - * - * Request to stop the ongoing network scan. Since the modem can only perform one scan at a time, - * there is no parameter for this request. - * - * "data" is NULL - * "response" is NULL - * - * Valid errors: - * SUCCESS - * INTERNAL_ERR - * MODEM_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - * REQUEST_NOT_SUPPORTED - * - */ -#define RIL_REQUEST_STOP_NETWORK_SCAN 143 - -/** - * RIL_REQUEST_START_KEEPALIVE - * - * Start a keepalive session - * - * Request that the modem begin sending keepalive packets on a particular - * data call, with a specified source, destination, and format. - * - * "data" is a const RIL_RequestKeepalive - * "response" is RIL_KeepaliveStatus with a valid "handle" - * - * Valid errors: - * SUCCESS - * NO_RESOURCES - * INVALID_ARGUMENTS - * - */ -#define RIL_REQUEST_START_KEEPALIVE 144 - -/** - * RIL_REQUEST_STOP_KEEPALIVE - * - * Stops an ongoing keepalive session - * - * Requests that a keepalive session with the given handle be stopped. - * there is no parameter for this request. - * - * "data" is an integer handle - * "response" is NULL - * - * Valid errors: - * SUCCESS - * INVALID_ARGUMENTS - * - */ -#define RIL_REQUEST_STOP_KEEPALIVE 145 - -/** - * RIL_REQUEST_START_NETWORK_SCAN4 - * - * Starts a new network scan - * - * Request to start a network scan with specified radio access networks with frequency bands and/or - * channels. - * - * "data" is a const RIL_NetworkScanRequest *. - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * DEVICE_IN_USE - * INTERNAL_ERR - * MODEM_ERR - * INVALID_ARGUMENTS - * - */ -#define RIL_REQUEST_START_NETWORK_SCAN4 146 - -/** - * RIL_REQUEST_GET_MODEM_STACK_STATUS - * - * Request status of a logical modem - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * MODEM_ERR - * - */ -#define RIL_REQUEST_GET_MODEM_STACK_STATUS 147 - -/** - * @param info Response info struct containing response type, serial no. and error - * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ -#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP 148 - -/** - * Callback of IRadio.setPreferredNetworkTypeBitmap(int, bitfield<RadioAccessFamily>) - * - * @param info Response info struct containing response type, serial no. and error - * - * Valid errors returned: - * RadioError:NONE - * RadioError:RADIO_NOT_AVAILABLE - * RadioError:OPERATION_NOT_ALLOWED - * RadioError:MODE_NOT_SUPPORTED - * RadioError:INTERNAL_ERR - * RadioError:INVALID_ARGUMENTS - * RadioError:MODEM_ERR - * RadioError:REQUEST_NOT_SUPPORTED - * RadioError:NO_RESOURCES - */ -#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP 149 - -/** - * RIL_REQUEST_EMERGENCY_DIAL - * - * Initiate emergency voice call, with zero or more emergency service category(s), zero or - * more emergency Uniform Resource Names (URN), and routing information for handling the call. - * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial - * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android. - * - * In multi-sim scenario, if the emergency number is from a specific subscription, this radio - * request is sent through the IRadio service that serves the subscription, no matter of the - * PUK/PIN state of the subscription and the service state of the radio. - * - * Some countries or carriers require some emergency numbers that must be handled with normal - * call routing or emergency routing. If the 'routing' field is specified as - * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to - * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the - * implementation must use emergency routing to handle the call; if it is - * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call. - * - * If the dialed emergency number does not have a specified emergency service category, the - * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed - * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field - * is set to an empty list. If the underlying technology used to request emergency services - * does not support the emergency service category or emergency uniform resource names, the - * field 'categories' or 'urns' may be ignored. - * - * 'fromEmergencyDialer' indicates if this request originated from emergency dialer/shortcut, - * which means an explicit intent from the user to dial an emergency number. The modem must - * treat this as an actual emergency dial and not try to disambiguate. - * - * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real - * emergency service; otherwise it's for a real emergency call request. - * Valid errors: - * NONE - * RADIO_NOT_AVAILABLE (radio resetting) - * DIAL_MODIFIED_TO_USSD - * DIAL_MODIFIED_TO_SS - * DIAL_MODIFIED_TO_DIAL - * INVALID_ARGUMENTS - * NO_RESOURCES - * INTERNAL_ERR - * FDN_CHECK_FAILURE - * MODEM_ERR - * NO_SUBSCRIPTION - * NO_NETWORK_FOUND - * INVALID_CALL_ID - * DEVICE_IN_USE - * ABORTED - * INVALID_MODEM_STATE - */ -#define RIL_REQUEST_EMERGENCY_DIAL 150 - -/** - * Specify which bands modem's background scan must act on. - * If specifyChannels is true, it only scans bands specified in specifiers. - * If specifyChannels is false, it scans all bands. - * - * For example, CBRS is only on LTE band 48. By specifying this band, - * modem saves more power. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * - */ -#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS 151 - -/** - * RIL_REQUEST_ENABLE_MODEM - * - * Enable a logical modem - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * MODEM_ERR - * - */ -#define RIL_REQUEST_ENABLE_MODEM 152 - -/** - * RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4 - * - * Set carrier restrictions. Expected modem behavior: - * If never receives this command: - * - Must allow all carriers - * Receives this command: - * - Only allow carriers specified in carriers. The restriction persists across power cycles - * and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is - * *not* allowed, modem must detach from the registered network and only keep emergency - * service, and notify Android SIM refresh reset with new SIM state being - * CardState:RESTRICTED. Emergency service must be enabled. - * - * "data" is const RIL_CarrierRestrictionsWithPriority * - * A list of allowed carriers and possibly a list of excluded carriers with the priority and - * multisim policy. - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_INVALID_ARGUMENTS - * RIL_E_RADIO_NOT_AVAILABLE - * RIL_E_REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4 153 - -/** - * RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4 - * - * Gets the carrier restrictions. - * - * "data" is NULL - * - * "response" is const RIL_CarrierRestrictionsWithPriority *. - * - * Valid errors: - * RIL_E_SUCCESS - * RIL_E_RADIO_NOT_AVAILABLE - * RIL_E_REQUEST_NOT_SUPPORTED - * INTERNAL_ERR - * NO_MEMORY - * NO_RESOURCES - * CANCELLED - */ -#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4 154 - -/** - * Sets the signal strength reporting criteria. - * - * The resulting reporting rules are the AND of all the supplied criteria. For each RAN - * The hysteresisDb apply to only the following measured quantities: - * -GERAN - RSSI - * -CDMA2000 - RSSI - * -UTRAN - RSCP - * -EUTRAN - RSRP/RSRQ/RSSNR - * - * The thresholds apply to only the following measured quantities: - * -GERAN - RSSI - * -CDMA2000 - RSSI - * -UTRAN - RSCP - * -EUTRAN - RSRP/RSRQ/RSSNR - * -NGRAN - SSRSRP/SSRSRQ/SSSINR - * - * Note: Reporting criteria must be individually set for each RAN. For any unset reporting - * criteria, the value is implementation-defined. - * - * Note: @1.5::SignalThresholdInfo includes fields 'hysteresisDb', 'hysteresisMs', - * and 'thresholds'. As this mechanism generally only constrains reports based on one - * measured quantity per RAN, if multiple measured quantities must be used to trigger a report - * for a given RAN, the only valid field may be hysteresisMs: hysteresisDb and thresholds must - * be set to zero and length zero respectively. If either hysteresisDb or thresholds is set, - * then reports shall only be triggered by the respective measured quantity, subject to the - * applied constraints. - * - * Valid errors returned: - * RadioError:NONE - * RadioError:INVALID_ARGUMENTS - * RadioError:RADIO_NOT_AVAILABLE - */ -#define RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5 155 - -/** - * RIL_REQUEST_ENABLE_UICC_APPLICATIONS - * - * Enable or disable uicc applications. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_ABSENT - * INTERNAL_ERR - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_ENABLE_UICC_APPLICATIONS 156 - -/** - * RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED - * - * Whether uicc applications are enabled. - * - * Response: a boolean of enable or not. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * SIM_ABSENT - * INTERNAL_ERR - * REQUEST_NOT_SUPPORTED - */ -#define RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED 157 - -/** - * RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT - * - * Whether disabling / enabling uicc applications is supported - * - * Response: a boolean of whether it's supported. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - */ -#define RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT 158 - -/** - * Specify which bands modem's background scan must act on. - * If specifyChannels is true, it only scans bands specified in specifiers. - * If specifyChannels is false, it scans all bands. - * - * For example, CBRS is only on LTE band 48. By specifying this band, - * modem saves more power. - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * INTERNAL_ERR - * INVALID_ARGUMENTS - * - */ -#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5 159 - -/** - * RIL_REQUEST_START_NETWORK_SCAN5 - * - * Starts a new network scan - * - * Request to start a network scan with specified radio access networks with frequency bands and/or - * channels. - * - * "data" is a const RIL_NetworkScanRequest *. - * "response" is NULL - * - * Valid errors: - * SUCCESS - * RADIO_NOT_AVAILABLE - * DEVICE_IN_USE - * INTERNAL_ERR - * MODEM_ERR - * INVALID_ARGUMENTS - * - */ -#define RIL_REQUEST_START_NETWORK_SCAN_1_5 160 - -/***********************************************************************/ - -/** - * RIL_RESPONSE_ACKNOWLEDGEMENT - * - * This is used by Asynchronous solicited messages and Unsolicited messages - * to acknowledge the receipt of those messages in RIL.java so that the ack - * can be used to let ril.cpp to release wakelock. - * - * Valid errors - * SUCCESS - * RADIO_NOT_AVAILABLE - */ - -#define RIL_RESPONSE_ACKNOWLEDGEMENT 800 - -/***********************************************************************/ - - -#define RIL_UNSOL_RESPONSE_BASE 1000 - -/** - * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED - * - * Indicate when value of RIL_RadioState has changed. - * - * Callee will invoke RIL_RadioStateRequest method on main thread - * - * "data" is NULL - */ - -#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000 - - -/** - * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED - * - * Indicate when call state has changed - * - * Callee will invoke RIL_REQUEST_GET_CURRENT_CALLS on main thread - * - * "data" is NULL - * - * Response should be invoked on, for example, - * "RING", "BUSY", "NO CARRIER", and also call state - * transitions (DIALING->ALERTING ALERTING->ACTIVE) - * - * Redundent or extraneous invocations are tolerated - */ -#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001 - - -/** - * RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED - * - * Called when the voice network state changed - * - * Callee will invoke the following requests on main thread: - * - * RIL_REQUEST_VOICE_REGISTRATION_STATE - * RIL_REQUEST_OPERATOR - * - * "data" is NULL - * - * FIXME should this happen when SIM records are loaded? (eg, for - * EONS) - */ -#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002 - -/** - * RIL_UNSOL_RESPONSE_NEW_SMS - * - * Called when new SMS is received. - * - * "data" is const char * - * This is a pointer to a string containing the PDU of an SMS-DELIVER - * as an ascii string of hex digits. The PDU starts with the SMSC address - * per TS 27.005 (+CMT:) - * - * Callee will subsequently confirm the receipt of thei SMS with a - * RIL_REQUEST_SMS_ACKNOWLEDGE - * - * No new RIL_UNSOL_RESPONSE_NEW_SMS - * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a - * RIL_REQUEST_SMS_ACKNOWLEDGE has been received - */ - -#define RIL_UNSOL_RESPONSE_NEW_SMS 1003 - -/** - * RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT - * - * Called when new SMS Status Report is received. - * - * "data" is const char * - * This is a pointer to a string containing the PDU of an SMS-STATUS-REPORT - * as an ascii string of hex digits. The PDU starts with the SMSC address - * per TS 27.005 (+CDS:). - * - * Callee will subsequently confirm the receipt of the SMS with a - * RIL_REQUEST_SMS_ACKNOWLEDGE - * - * No new RIL_UNSOL_RESPONSE_NEW_SMS - * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a - * RIL_REQUEST_SMS_ACKNOWLEDGE has been received - */ - -#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004 - -/** - * RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM - * - * Called when new SMS has been stored on SIM card - * - * "data" is const int * - * ((const int *)data)[0] contains the slot index on the SIM that contains - * the new message - */ - -#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005 - -/** - * RIL_UNSOL_ON_USSD - * - * Called when a new USSD message is received. - * - * "data" is const char ** - * ((const char **)data)[0] points to a type code, which is - * one of these string values: - * "0" USSD-Notify -- text in ((const char **)data)[1] - * "1" USSD-Request -- text in ((const char **)data)[1] - * "2" Session terminated by network - * "3" other local client (eg, SIM Toolkit) has responded - * "4" Operation not supported - * "5" Network timeout - * - * The USSD session is assumed to persist if the type code is "1", otherwise - * the current session (if any) is assumed to have terminated. - * - * ((const char **)data)[1] points to a message string if applicable, which - * should always be in UTF-8. - */ -#define RIL_UNSOL_ON_USSD 1006 -/* Previously #define RIL_UNSOL_ON_USSD_NOTIFY 1006 */ - -/** - * RIL_UNSOL_ON_USSD_REQUEST - * - * Obsolete. Send via RIL_UNSOL_ON_USSD - */ -#define RIL_UNSOL_ON_USSD_REQUEST 1007 - -/** - * RIL_UNSOL_NITZ_TIME_RECEIVED - * - * Called when radio has received a NITZ time message - * - * "data" is const char * pointing to NITZ time string - * in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" - */ -#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008 - -/** - * RIL_UNSOL_SIGNAL_STRENGTH - * - * Radio may report signal strength rather han have it polled. - * - * "data" is a const RIL_SignalStrength * - */ -#define RIL_UNSOL_SIGNAL_STRENGTH 1009 - - -/** - * RIL_UNSOL_DATA_CALL_LIST_CHANGED - * - * "data" is an array of RIL_Data_Call_Response_v6 identical to that - * returned by RIL_REQUEST_DATA_CALL_LIST. It is the complete list - * of current data contexts including new contexts that have been - * activated. A data call is only removed from this list when the - * framework sends a RIL_REQUEST_DEACTIVATE_DATA_CALL or the radio - * is powered off/on. - * - * See also: RIL_REQUEST_DATA_CALL_LIST - */ - -#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010 - -/** - * RIL_UNSOL_SUPP_SVC_NOTIFICATION - * - * Reports supplementary service related notification from the network. - * - * "data" is a const RIL_SuppSvcNotification * - * - */ - -#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011 - -/** - * RIL_UNSOL_STK_SESSION_END - * - * Indicate when STK session is terminated by SIM. - * - * "data" is NULL - */ -#define RIL_UNSOL_STK_SESSION_END 1012 - -/** - * RIL_UNSOL_STK_PROACTIVE_COMMAND - * - * Indicate when SIM issue a STK proactive command to applications - * - * "data" is a const char * containing SAT/USAT proactive command - * in hexadecimal format string starting with command tag - * - */ -#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013 - -/** - * RIL_UNSOL_STK_EVENT_NOTIFY - * - * Indicate when SIM notifies applcations some event happens. - * Generally, application does not need to have any feedback to - * SIM but shall be able to indicate appropriate messages to users. - * - * "data" is a const char * containing SAT/USAT commands or responses - * sent by ME to SIM or commands handled by ME, in hexadecimal format string - * starting with first byte of response data or command tag - * - */ -#define RIL_UNSOL_STK_EVENT_NOTIFY 1014 - -/** - * RIL_UNSOL_STK_CALL_SETUP - * - * Indicate when SIM wants application to setup a voice call. - * - * "data" is const int * - * ((const int *)data)[0] contains timeout value (in milliseconds) - */ -#define RIL_UNSOL_STK_CALL_SETUP 1015 - -/** - * RIL_UNSOL_SIM_SMS_STORAGE_FULL - * - * Indicates that SMS storage on the SIM is full. Sent when the network - * attempts to deliver a new SMS message. Messages cannot be saved on the - * SIM until space is freed. In particular, incoming Class 2 messages - * cannot be stored. - * - * "data" is null - * - */ -#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016 - -/** - * RIL_UNSOL_SIM_REFRESH - * - * Indicates that file(s) on the SIM have been updated, or the SIM - * has been reinitialized. - * - * In the case where RIL is version 6 or older: - * "data" is an int * - * ((int *)data)[0] is a RIL_SimRefreshResult. - * ((int *)data)[1] is the EFID of the updated file if the result is - * SIM_FILE_UPDATE or NULL for any other result. - * - * In the case where RIL is version 7: - * "data" is a RIL_SimRefreshResponse_v7 * - * - * Note: If the SIM state changes as a result of the SIM refresh (eg, - * SIM_READY -> SIM_LOCKED_OR_ABSENT), RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED - * should be sent. - */ -#define RIL_UNSOL_SIM_REFRESH 1017 - -/** - * RIL_UNSOL_CALL_RING - * - * Ring indication for an incoming call (eg, RING or CRING event). - * There must be at least one RIL_UNSOL_CALL_RING at the beginning - * of a call and sending multiple is optional. If the system property - * ro.telephony.call_ring.multiple is false then the upper layers - * will generate the multiple events internally. Otherwise the vendor - * ril must generate multiple RIL_UNSOL_CALL_RING if - * ro.telephony.call_ring.multiple is true or if it is absent. - * - * The rate of these events is controlled by ro.telephony.call_ring.delay - * and has a default value of 3000 (3 seconds) if absent. - * - * "data" is null for GSM - * "data" is const RIL_CDMA_SignalInfoRecord * if CDMA - */ -#define RIL_UNSOL_CALL_RING 1018 - -/** - * RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED - * - * Indicates that SIM state changes. - * - * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread - - * "data" is null - */ -#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019 - -/** - * RIL_UNSOL_RESPONSE_CDMA_NEW_SMS - * - * Called when new CDMA SMS is received - * - * "data" is const RIL_CDMA_SMS_Message * - * - * Callee will subsequently confirm the receipt of the SMS with - * a RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE - * - * No new RIL_UNSOL_RESPONSE_CDMA_NEW_SMS should be sent until - * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE has been received - * - */ -#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020 - -/** - * RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS - * - * Called when new Broadcast SMS is received - * - * "data" can be one of the following: - * If received from GSM network, "data" is const char of 88 bytes - * which indicates each page of a CBS Message sent to the MS by the - * BTS as coded in 3GPP 23.041 Section 9.4.1.2. - * If received from UMTS network, "data" is const char of 90 up to 1252 - * bytes which contain between 1 and 15 CBS Message pages sent as one - * packet to the MS by the BTS as coded in 3GPP 23.041 Section 9.4.2.2. - * - */ -#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021 - -/** - * RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL - * - * Indicates that SMS storage on the RUIM is full. Messages - * cannot be saved on the RUIM until space is freed. - * - * "data" is null - * - */ -#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022 - -/** - * RIL_UNSOL_RESTRICTED_STATE_CHANGED - * - * Indicates a restricted state change (eg, for Domain Specific Access Control). - * - * Radio need send this msg after radio off/on cycle no matter it is changed or not. - * - * "data" is an int * - * ((int *)data)[0] contains a bitmask of RIL_RESTRICTED_STATE_* values. - */ -#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023 - -/** - * RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE - * - * Indicates that the radio system selection module has - * autonomously entered emergency callback mode. - * - * "data" is null - * - */ -#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024 - -/** - * RIL_UNSOL_CDMA_CALL_WAITING - * - * Called when CDMA radio receives a call waiting indication. - * - * "data" is const RIL_CDMA_CallWaiting * - * - */ -#define RIL_UNSOL_CDMA_CALL_WAITING 1025 - -/** - * RIL_UNSOL_CDMA_OTA_PROVISION_STATUS - * - * Called when CDMA radio receives an update of the progress of an - * OTASP/OTAPA call. - * - * "data" is const int * - * For CDMA this is an integer OTASP/OTAPA status listed in - * RIL_CDMA_OTA_ProvisionStatus. - * - */ -#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026 - -/** - * RIL_UNSOL_CDMA_INFO_REC - * - * Called when CDMA radio receives one or more info recs. - * - * "data" is const RIL_CDMA_InformationRecords * - * - */ -#define RIL_UNSOL_CDMA_INFO_REC 1027 - -/** - * RIL_UNSOL_OEM_HOOK_RAW - * - * This is for OEM specific use. - * - * "data" is a byte[] - */ -#define RIL_UNSOL_OEM_HOOK_RAW 1028 - -/** - * RIL_UNSOL_RINGBACK_TONE - * - * Indicates that nework doesn't have in-band information, need to - * play out-band tone. - * - * "data" is an int * - * ((int *)data)[0] == 0 for stop play ringback tone. - * ((int *)data)[0] == 1 for start play ringback tone. - */ -#define RIL_UNSOL_RINGBACK_TONE 1029 - -/** - * RIL_UNSOL_RESEND_INCALL_MUTE - * - * Indicates that framework/application need reset the uplink mute state. - * - * There may be situations where the mute state becomes out of sync - * between the application and device in some GSM infrastructures. - * - * "data" is null - */ -#define RIL_UNSOL_RESEND_INCALL_MUTE 1030 - -/** - * RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED - * - * Called when CDMA subscription source changed. - * - * "data" is int * - * ((int *)data)[0] is == RIL_CdmaSubscriptionSource - */ -#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031 - -/** - * RIL_UNSOL_CDMA_PRL_CHANGED - * - * Called when PRL (preferred roaming list) changes. - * - * "data" is int * - * ((int *)data)[0] is PRL_VERSION as would be returned by RIL_REQUEST_CDMA_SUBSCRIPTION - */ -#define RIL_UNSOL_CDMA_PRL_CHANGED 1032 - -/** - * RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE - * - * Called when Emergency Callback Mode Ends - * - * Indicates that the radio system selection module has - * proactively exited emergency callback mode. - * - * "data" is NULL - * - */ -#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033 - -/** - * RIL_UNSOL_RIL_CONNECTED - * - * Called the ril connects and returns the version - * - * "data" is int * - * ((int *)data)[0] is RIL_VERSION - */ -#define RIL_UNSOL_RIL_CONNECTED 1034 - -/** - * RIL_UNSOL_VOICE_RADIO_TECH_CHANGED - * - * Indicates that voice technology has changed. Contains new radio technology - * as a data in the message. - * - * "data" is int * - * ((int *)data)[0] is of type const RIL_RadioTechnology - * - */ -#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035 - -/** - * RIL_UNSOL_CELL_INFO_LIST - * - * Same information as returned by RIL_REQUEST_GET_CELL_INFO_LIST, but returned - * at the rate no greater than specified by RIL_REQUEST_SET_UNSOL_CELL_INFO_RATE. - * - * "data" is NULL - * - * "response" is an array of RIL_CellInfo_v12. - */ -#define RIL_UNSOL_CELL_INFO_LIST 1036 - -/** - * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED - * - * This message is DEPRECATED and shall be removed in a future release (target: 2018); - * instead, provide IMS registration status via an IMS Service. - * - * Called when IMS registration state has changed - * - * To get IMS registration state and IMS SMS format, callee needs to invoke the - * following request on main thread: - * - * RIL_REQUEST_IMS_REGISTRATION_STATE - * - * "data" is NULL - * - */ -#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037 - -/** - * RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED - * - * Indicated when there is a change in subscription status. - * This event will be sent in the following scenarios - * - subscription readiness at modem, which was selected by telephony layer - * - when subscription is deactivated by modem due to UICC card removal - * - When network invalidates the subscription i.e. attach reject due to authentication reject - * - * "data" is const int * - * ((const int *)data)[0] == 0 for Subscription Deactivated - * ((const int *)data)[0] == 1 for Subscription Activated - * - */ -#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038 - -/** - * RIL_UNSOL_SRVCC_STATE_NOTIFY - * - * Called when Single Radio Voice Call Continuity(SRVCC) - * progress state has changed - * - * "data" is int * - * ((int *)data)[0] is of type const RIL_SrvccState - * - */ - -#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039 - -/** - * RIL_UNSOL_HARDWARE_CONFIG_CHANGED - * - * Called when the hardware configuration associated with the RILd changes - * - * "data" is an array of RIL_HardwareConfig - * - */ -#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040 - -/** - * RIL_UNSOL_DC_RT_INFO_CHANGED - * - * The message is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO - * Sent when the DC_RT_STATE changes but the time - * between these messages must not be less than the - * value set by RIL_REQUEST_SET_DC_RT_RATE. - * - * "data" is the most recent RIL_DcRtInfo - * - */ -#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041 - -/** - * RIL_UNSOL_RADIO_CAPABILITY - * - * Sent when RIL_REQUEST_SET_RADIO_CAPABILITY completes. - * Returns the phone radio capability exactly as - * RIL_REQUEST_GET_RADIO_CAPABILITY and should be the - * same set as sent by RIL_REQUEST_SET_RADIO_CAPABILITY. - * - * "data" is the RIL_RadioCapability structure - */ -#define RIL_UNSOL_RADIO_CAPABILITY 1042 - -/* - * RIL_UNSOL_ON_SS - * - * Called when SS response is received when DIAL/USSD/SS is changed to SS by - * call control. - * - * "data" is const RIL_StkCcUnsolSsResponse * - * - */ -#define RIL_UNSOL_ON_SS 1043 - -/** - * RIL_UNSOL_STK_CC_ALPHA_NOTIFY - * - * Called when there is an ALPHA from UICC during Call Control. - * - * "data" is const char * containing ALPHA string from UICC in UTF-8 format. - * - */ -#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044 - -/** - * RIL_UNSOL_LCEDATA_RECV - * - * Called when there is an incoming Link Capacity Estimate (LCE) info report. - * - * "data" is the RIL_LceDataInfo structure. - * - */ -#define RIL_UNSOL_LCEDATA_RECV 1045 - - /** - * RIL_UNSOL_PCO_DATA - * - * Called when there is new Carrier PCO data received for a data call. Ideally - * only new data will be forwarded, though this is not required. Multiple - * boxes of carrier PCO data for a given call should result in a series of - * RIL_UNSOL_PCO_DATA calls. - * - * "data" is the RIL_PCO_Data structure. - * - */ -#define RIL_UNSOL_PCO_DATA 1046 - - /** - * RIL_UNSOL_MODEM_RESTART - * - * Called when there is a modem reset. - * - * "reason" is "const char *" containing the reason for the reset. It - * could be a crash signature if the restart was due to a crash or some - * string such as "user-initiated restart" or "AT command initiated - * restart" that explains the cause of the modem restart. - * - * When modem restarts, one of the following radio state transitions will happen - * 1) RADIO_STATE_ON->RADIO_STATE_UNAVAILABLE->RADIO_STATE_ON or - * 2) RADIO_STATE_OFF->RADIO_STATE_UNAVAILABLE->RADIO_STATE_OFF - * This message can be sent either just before the RADIO_STATE changes to RADIO_STATE_UNAVAILABLE - * or just after but should never be sent after the RADIO_STATE changes from UNAVAILABLE to - * AVAILABLE(RADIO_STATE_ON/RADIO_STATE_OFF) again. - * - * It should NOT be sent after the RADIO_STATE changes to AVAILABLE after the - * modem restart as that could be interpreted as a second modem reset by the - * framework. - */ -#define RIL_UNSOL_MODEM_RESTART 1047 - -/** - * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION - * - * Called when the modem needs Carrier specific information that will - * be used to encrypt IMSI and IMPI. - * - * "data" is NULL - * - */ -#define RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION 1048 - -/** - * RIL_UNSOL_NETWORK_SCAN_RESULT - * - * Returns incremental result for the network scan which is started by - * RIL_REQUEST_START_NETWORK_SCAN, sent to report results, status, or errors. - * - * "data" is NULL - * "response" is a const RIL_NetworkScanResult * - */ -#define RIL_UNSOL_NETWORK_SCAN_RESULT 1049 - -/** - * RIL_UNSOL_KEEPALIVE_STATUS - * - * "data" is NULL - * "response" is a const RIL_KeepaliveStatus * - */ -#define RIL_UNSOL_KEEPALIVE_STATUS 1050 - -/***********************************************************************/ - - -#if defined(ANDROID_MULTI_SIM) -/** - * RIL_Request Function pointer - * - * @param request is one of RIL_REQUEST_* - * @param data is pointer to data defined for that RIL_REQUEST_* - * data is owned by caller, and should not be modified or freed by callee - * structures passed as data may contain pointers to non-contiguous memory - * @param t should be used in subsequent call to RIL_onResponse - * @param datalen is the length of "data" which is defined as other argument. It may or may - * not be equal to sizeof(data). Refer to the documentation of individual structures - * to find if pointers listed in the structure are contiguous and counted in the datalen - * length or not. - * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) - * - */ -typedef void (*RIL_RequestFunc) (int request, void *data, - size_t datalen, RIL_Token t, RIL_SOCKET_ID socket_id); - -/** - * This function should return the current radio state synchronously - */ -typedef RIL_RadioState (*RIL_RadioStateRequest)(RIL_SOCKET_ID socket_id); - -#else -/* Backward compatible */ - -/** - * RIL_Request Function pointer - * - * @param request is one of RIL_REQUEST_* - * @param data is pointer to data defined for that RIL_REQUEST_* - * data is owned by caller, and should not be modified or freed by callee - * structures passed as data may contain pointers to non-contiguous memory - * @param t should be used in subsequent call to RIL_onResponse - * @param datalen is the length of "data" which is defined as other argument. It may or may - * not be equal to sizeof(data). Refer to the documentation of individual structures - * to find if pointers listed in the structure are contiguous and counted in the datalen - * length or not. - * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) - * - */ -typedef void (*RIL_RequestFunc) (int request, void *data, - size_t datalen, RIL_Token t); - -/** - * This function should return the current radio state synchronously - */ -typedef RIL_RadioState (*RIL_RadioStateRequest)(); - -#endif - - -/** - * This function returns "1" if the specified RIL_REQUEST code is - * supported and 0 if it is not - * - * @param requestCode is one of RIL_REQUEST codes - */ - -typedef int (*RIL_Supports)(int requestCode); - -/** - * This function is called from a separate thread--not the - * thread that calls RIL_RequestFunc--and indicates that a pending - * request should be cancelled. - * - * On cancel, the callee should do its best to abandon the request and - * call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point. - * - * Subsequent calls to RIL_onRequestComplete for this request with - * other results will be tolerated but ignored. (That is, it is valid - * to ignore the cancellation request) - * - * RIL_Cancel calls should return immediately, and not wait for cancellation - * - * Please see ITU v.250 5.6.1 for how one might implement this on a TS 27.007 - * interface - * - * @param t token wants to be canceled - */ - -typedef void (*RIL_Cancel)(RIL_Token t); - -typedef void (*RIL_TimedCallback) (void *param); - -/** - * Return a version string for your RIL implementation - */ -typedef const char * (*RIL_GetVersion) (void); - -typedef struct { - int version; /* set to RIL_VERSION */ - RIL_RequestFunc onRequest; - RIL_RadioStateRequest onStateRequest; - RIL_Supports supports; - RIL_Cancel onCancel; - RIL_GetVersion getVersion; -} RIL_RadioFunctions; - -typedef struct { - char *apn; /* the APN to connect to */ - char *protocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on - roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/ - int authtype; /* authentication protocol used for this PDP context - (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */ - char *username; /* the username for APN, or NULL */ - char *password; /* the password for APN, or NULL */ -} RIL_InitialAttachApn; - -typedef struct { - char *apn; /* the APN to connect to */ - char *protocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on - home network. For example, "IP", "IPV6", "IPV4V6", or "PPP". */ - char *roamingProtocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on - roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/ - int authtype; /* authentication protocol used for this PDP context - (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */ - char *username; /* the username for APN, or NULL */ - char *password; /* the password for APN, or NULL */ - int supportedTypesBitmask; /* supported APN types bitmask. See RIL_ApnTypes for the value of - each bit. */ - int bearerBitmask; /* the bearer bitmask. See RIL_RadioAccessFamily for the value of - each bit. */ - int modemCognitive; /* indicating the APN setting was sent to the modem through - setDataProfile earlier. */ - int mtu; /* maximum transmission unit (MTU) size in bytes */ - char *mvnoType; /* the MVNO type: possible values are "imsi", "gid", "spn" */ - char *mvnoMatchData; /* MVNO match data. Can be anything defined by the carrier. - For example, - SPN like: "A MOBILE", "BEN NL", etc... - IMSI like: "302720x94", "2060188", etc... - GID like: "4E", "33", etc... */ -} RIL_InitialAttachApn_v15; - -typedef struct { - int authContext; /* P2 value of authentication command, see P2 parameter in - 3GPP TS 31.102 7.1.2 */ - char *authData; /* the challenge string in Base64 format, see 3GPP - TS 31.102 7.1.2 */ - char *aid; /* AID value, See ETSI 102.221 8.1 and 101.220 4, - NULL if no value. */ -} RIL_SimAuthentication; - -typedef struct { - int cid; /* Context ID, uniquely identifies this call */ - char *bearer_proto; /* One of the PDP_type values in TS 27.007 section 10.1.1. - For example, "IP", "IPV6", "IPV4V6". */ - int pco_id; /* The protocol ID for this box. Note that only IDs from - FF00H - FFFFH are accepted. If more than one is included - from the network, multiple calls should be made to send all - of them. */ - int contents_length; /* The number of octets in the contents. */ - char *contents; /* Carrier-defined content. It is binary, opaque and - loosely defined in LTE Layer 3 spec 24.008 */ -} RIL_PCO_Data; - -typedef enum { - NATT_IPV4 = 0, /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv4 */ - NATT_IPV6 = 1 /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv6 */ -} RIL_KeepaliveType; - -#define MAX_INADDR_LEN 16 -typedef struct { - RIL_KeepaliveType type; /* Type of keepalive packet */ - char sourceAddress[MAX_INADDR_LEN]; /* Source address in network-byte order */ - int sourcePort; /* Source port if applicable, or 0x7FFFFFFF; - the maximum value is 65535 */ - char destinationAddress[MAX_INADDR_LEN]; /* Destination address in network-byte order */ - int destinationPort; /* Destination port if applicable or 0x7FFFFFFF; - the maximum value is 65535 */ - int maxKeepaliveIntervalMillis; /* Maximum milliseconds between two packets */ - int cid; /* Context ID, uniquely identifies this call */ -} RIL_KeepaliveRequest; - -typedef enum { - KEEPALIVE_ACTIVE, /* Keepalive session is active */ - KEEPALIVE_INACTIVE, /* Keepalive session is inactive */ - KEEPALIVE_PENDING /* Keepalive session status not available */ -} RIL_KeepaliveStatusCode; - -typedef struct { - uint32_t sessionHandle; - RIL_KeepaliveStatusCode code; -} RIL_KeepaliveStatus; - -#ifdef RIL_SHLIB -struct RIL_Env { - /** - * "t" is parameter passed in on previous call to RIL_Notification - * routine. - * - * If "e" != SUCCESS, then response can be null/is ignored - * - * "response" is owned by caller, and should not be modified or - * freed by callee - * - * RIL_onRequestComplete will return as soon as possible - */ - void (*OnRequestComplete)(RIL_Token t, RIL_Errno e, - void *response, size_t responselen); - -#if defined(ANDROID_MULTI_SIM) - /** - * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* - * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* - * - * "data" is owned by caller, and should not be modified or freed by callee - */ - void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id); -#else - /** - * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* - * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* - * - * "data" is owned by caller, and should not be modified or freed by callee - */ - void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen); -#endif - /** - * Call user-specifed "callback" function on on the same thread that - * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies - * a relative time value at which the callback is invoked. If relativeTime is - * NULL or points to a 0-filled structure, the callback will be invoked as - * soon as possible - */ - - void (*RequestTimedCallback) (RIL_TimedCallback callback, - void *param, const struct timeval *relativeTime); - /** - * "t" is parameter passed in on previous call RIL_Notification routine - * - * RIL_onRequestAck will be called by vendor when an Async RIL request was received - * by them and an ack needs to be sent back to java ril. - */ - void (*OnRequestAck) (RIL_Token t); -}; - - -/** - * RIL implementations must defined RIL_Init - * argc and argv will be command line arguments intended for the RIL implementation - * Return NULL on error - * - * @param env is environment point defined as RIL_Env - * @param argc number of arguments - * @param argv list fo arguments - * - */ -const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv); - -/** - * If BT SAP(SIM Access Profile) is supported, then RIL implementations must define RIL_SAP_Init - * for initializing RIL_RadioFunctions used for BT SAP communcations. It is called whenever RILD - * starts or modem restarts. Returns handlers for SAP related request that are made on SAP - * sepecific socket, analogous to the RIL_RadioFunctions returned by the call to RIL_Init - * and used on the general RIL socket. - * argc and argv will be command line arguments intended for the RIL implementation - * Return NULL on error. - * - * @param env is environment point defined as RIL_Env - * @param argc number of arguments - * @param argv list fo arguments - * - */ -const RIL_RadioFunctions *RIL_SAP_Init(const struct RIL_Env *env, int argc, char **argv); - -#else /* RIL_SHLIB */ - -/** - * Call this once at startup to register notification routine - * - * @param callbacks user-specifed callback function - */ -void RIL_register (const RIL_RadioFunctions *callbacks); - -void rilc_thread_pool(); - - -/** - * - * RIL_onRequestComplete will return as soon as possible - * - * @param t is parameter passed in on previous call to RIL_Notification - * routine. - * @param e error code - * if "e" != SUCCESS, then response can be null/is ignored - * @param response is owned by caller, and should not be modified or - * freed by callee - * @param responselen the length of response in byte - */ -void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, - void *response, size_t responselen); - -/** - * RIL_onRequestAck will be called by vendor when an Async RIL request was received by them and - * an ack needs to be sent back to java ril. This doesn't mark the end of the command or it's - * results, just that the command was received and will take a while. After sending this Ack - * its vendor's responsibility to make sure that AP is up whenever needed while command is - * being processed. - * - * @param t is parameter passed in on previous call to RIL_Notification - * routine. - */ -void RIL_onRequestAck(RIL_Token t); - -#if defined(ANDROID_MULTI_SIM) -/** - * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* - * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* - * "data" is owned by caller, and should not be modified or freed by callee - * @param datalen the length of data in byte - */ - -void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen, RIL_SOCKET_ID socket_id); -#else -/** - * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* - * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* - * "data" is owned by caller, and should not be modified or freed by callee - * @param datalen the length of data in byte - */ - -void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen); -#endif - -/** - * Call user-specifed "callback" function on on the same thread that - * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies - * a relative time value at which the callback is invoked. If relativeTime is - * NULL or points to a 0-filled structure, the callback will be invoked as - * soon as possible - * - * @param callback user-specifed callback function - * @param param parameter list - * @param relativeTime a relative time value at which the callback is invoked - */ - -void RIL_requestTimedCallback (RIL_TimedCallback callback, - void *param, const struct timeval *relativeTime); - -#endif /* RIL_SHLIB */ - -#ifdef __cplusplus -} -#endif - -#endif /*ANDROID_RIL_H*/ diff --git a/guest/hals/ril/libril/ril_commands.h b/guest/hals/ril/libril/ril_commands.h deleted file mode 100644 index 17cb5949..00000000 --- a/guest/hals/ril/libril/ril_commands.h +++ /dev/null @@ -1,177 +0,0 @@ -/* //guest/hals/ril/libril/ril_commands.h -** -** Copyright 2006, 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. -*/ - {0, NULL}, //none - {RIL_REQUEST_GET_SIM_STATUS, radio_1_5::getIccCardStatusResponse}, - {RIL_REQUEST_ENTER_SIM_PIN, radio_1_5::supplyIccPinForAppResponse}, - {RIL_REQUEST_ENTER_SIM_PUK, radio_1_5::supplyIccPukForAppResponse}, - {RIL_REQUEST_ENTER_SIM_PIN2, radio_1_5::supplyIccPin2ForAppResponse}, - {RIL_REQUEST_ENTER_SIM_PUK2, radio_1_5::supplyIccPuk2ForAppResponse}, - {RIL_REQUEST_CHANGE_SIM_PIN, radio_1_5::changeIccPinForAppResponse}, - {RIL_REQUEST_CHANGE_SIM_PIN2, radio_1_5::changeIccPin2ForAppResponse}, - {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, radio_1_5::supplyNetworkDepersonalizationResponse}, - {RIL_REQUEST_GET_CURRENT_CALLS, radio_1_5::getCurrentCallsResponse}, - {RIL_REQUEST_DIAL, radio_1_5::dialResponse}, - {RIL_REQUEST_GET_IMSI, radio_1_5::getIMSIForAppResponse}, - {RIL_REQUEST_HANGUP, radio_1_5::hangupConnectionResponse}, - {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, radio_1_5::hangupWaitingOrBackgroundResponse}, - {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, radio_1_5::hangupForegroundResumeBackgroundResponse}, - {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, radio_1_5::switchWaitingOrHoldingAndActiveResponse}, - {RIL_REQUEST_CONFERENCE, radio_1_5::conferenceResponse}, - {RIL_REQUEST_UDUB, radio_1_5::rejectCallResponse}, - {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, radio_1_5::getLastCallFailCauseResponse}, - {RIL_REQUEST_SIGNAL_STRENGTH, radio_1_5::getSignalStrengthResponse}, - {RIL_REQUEST_VOICE_REGISTRATION_STATE, radio_1_5::getVoiceRegistrationStateResponse}, - {RIL_REQUEST_DATA_REGISTRATION_STATE, radio_1_5::getDataRegistrationStateResponse}, - {RIL_REQUEST_OPERATOR, radio_1_5::getOperatorResponse}, - {RIL_REQUEST_RADIO_POWER, radio_1_5::setRadioPowerResponse}, - {RIL_REQUEST_DTMF, radio_1_5::sendDtmfResponse}, - {RIL_REQUEST_SEND_SMS, radio_1_5::sendSmsResponse}, - {RIL_REQUEST_SEND_SMS_EXPECT_MORE, radio_1_5::sendSMSExpectMoreResponse}, - {RIL_REQUEST_SETUP_DATA_CALL, radio_1_5::setupDataCallResponse}, - {RIL_REQUEST_SIM_IO, radio_1_5::iccIOForAppResponse}, - {RIL_REQUEST_SEND_USSD, radio_1_5::sendUssdResponse}, - {RIL_REQUEST_CANCEL_USSD, radio_1_5::cancelPendingUssdResponse}, - {RIL_REQUEST_GET_CLIR, radio_1_5::getClirResponse}, - {RIL_REQUEST_SET_CLIR, radio_1_5::setClirResponse}, - {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, radio_1_5::getCallForwardStatusResponse}, - {RIL_REQUEST_SET_CALL_FORWARD, radio_1_5::setCallForwardResponse}, - {RIL_REQUEST_QUERY_CALL_WAITING, radio_1_5::getCallWaitingResponse}, - {RIL_REQUEST_SET_CALL_WAITING, radio_1_5::setCallWaitingResponse}, - {RIL_REQUEST_SMS_ACKNOWLEDGE, radio_1_5::acknowledgeLastIncomingGsmSmsResponse}, - {RIL_REQUEST_GET_IMEI, NULL}, - {RIL_REQUEST_GET_IMEISV, NULL}, - {RIL_REQUEST_ANSWER, radio_1_5::acceptCallResponse}, - {RIL_REQUEST_DEACTIVATE_DATA_CALL, radio_1_5::deactivateDataCallResponse}, - {RIL_REQUEST_QUERY_FACILITY_LOCK, radio_1_5::getFacilityLockForAppResponse}, - {RIL_REQUEST_SET_FACILITY_LOCK, radio_1_5::setFacilityLockForAppResponse}, - {RIL_REQUEST_CHANGE_BARRING_PASSWORD, radio_1_5::setBarringPasswordResponse}, - {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, radio_1_5::getNetworkSelectionModeResponse}, - {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, radio_1_5::setNetworkSelectionModeAutomaticResponse}, - {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, radio_1_5::setNetworkSelectionModeManualResponse}, - {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , radio_1_5::getAvailableNetworksResponse}, - {RIL_REQUEST_DTMF_START, radio_1_5::startDtmfResponse}, - {RIL_REQUEST_DTMF_STOP, radio_1_5::stopDtmfResponse}, - {RIL_REQUEST_BASEBAND_VERSION, radio_1_5::getBasebandVersionResponse}, - {RIL_REQUEST_SEPARATE_CONNECTION, radio_1_5::separateConnectionResponse}, - {RIL_REQUEST_SET_MUTE, radio_1_5::setMuteResponse}, - {RIL_REQUEST_GET_MUTE, radio_1_5::getMuteResponse}, - {RIL_REQUEST_QUERY_CLIP, radio_1_5::getClipResponse}, - {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, NULL}, - {RIL_REQUEST_DATA_CALL_LIST, radio_1_5::getDataCallListResponse}, - {RIL_REQUEST_RESET_RADIO, NULL}, - {RIL_REQUEST_OEM_HOOK_RAW, radio_1_5::sendRequestRawResponse}, - {RIL_REQUEST_OEM_HOOK_STRINGS, radio_1_5::sendRequestStringsResponse}, - {RIL_REQUEST_SCREEN_STATE, radio_1_5::sendDeviceStateResponse}, // Note the response function is different. - {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, radio_1_5::setSuppServiceNotificationsResponse}, - {RIL_REQUEST_WRITE_SMS_TO_SIM, radio_1_5::writeSmsToSimResponse}, - {RIL_REQUEST_DELETE_SMS_ON_SIM, radio_1_5::deleteSmsOnSimResponse}, - {RIL_REQUEST_SET_BAND_MODE, radio_1_5::setBandModeResponse}, - {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, radio_1_5::getAvailableBandModesResponse}, - {RIL_REQUEST_STK_GET_PROFILE, NULL}, - {RIL_REQUEST_STK_SET_PROFILE, NULL}, - {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, radio_1_5::sendEnvelopeResponse}, - {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, radio_1_5::sendTerminalResponseToSimResponse}, - {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, radio_1_5::handleStkCallSetupRequestFromSimResponse}, - {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, radio_1_5::explicitCallTransferResponse}, - {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, radio_1_5::setPreferredNetworkTypeResponse}, - {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, radio_1_5::getPreferredNetworkTypeResponse}, - {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, radio_1_5::getNeighboringCidsResponse}, - {RIL_REQUEST_SET_LOCATION_UPDATES, radio_1_5::setLocationUpdatesResponse}, - {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, radio_1_5::setCdmaSubscriptionSourceResponse}, - {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, radio_1_5::setCdmaRoamingPreferenceResponse}, - {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, radio_1_5::getCdmaRoamingPreferenceResponse}, - {RIL_REQUEST_SET_TTY_MODE, radio_1_5::setTTYModeResponse}, - {RIL_REQUEST_QUERY_TTY_MODE, radio_1_5::getTTYModeResponse}, - {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, radio_1_5::setPreferredVoicePrivacyResponse}, - {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, radio_1_5::getPreferredVoicePrivacyResponse}, - {RIL_REQUEST_CDMA_FLASH, radio_1_5::sendCDMAFeatureCodeResponse}, - {RIL_REQUEST_CDMA_BURST_DTMF, radio_1_5::sendBurstDtmfResponse}, - {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, NULL}, - {RIL_REQUEST_CDMA_SEND_SMS, radio_1_5::sendCdmaSmsResponse}, - {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, radio_1_5::acknowledgeLastIncomingCdmaSmsResponse}, - {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, radio_1_5::getGsmBroadcastConfigResponse}, - {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, radio_1_5::setGsmBroadcastConfigResponse}, - {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, radio_1_5::setGsmBroadcastActivationResponse}, - {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, radio_1_5::getCdmaBroadcastConfigResponse}, - {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, radio_1_5::setCdmaBroadcastConfigResponse}, - {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, radio_1_5::setCdmaBroadcastActivationResponse}, - {RIL_REQUEST_CDMA_SUBSCRIPTION, radio_1_5::getCDMASubscriptionResponse}, - {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, radio_1_5::writeSmsToRuimResponse}, - {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, radio_1_5::deleteSmsOnRuimResponse}, - {RIL_REQUEST_DEVICE_IDENTITY, radio_1_5::getDeviceIdentityResponse}, - {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, radio_1_5::exitEmergencyCallbackModeResponse}, - {RIL_REQUEST_GET_SMSC_ADDRESS, radio_1_5::getSmscAddressResponse}, - {RIL_REQUEST_SET_SMSC_ADDRESS, radio_1_5::setSmscAddressResponse}, - {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, radio_1_5::reportSmsMemoryStatusResponse}, - {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, radio_1_5::reportStkServiceIsRunningResponse}, - {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, radio_1_5::getCdmaSubscriptionSourceResponse}, - {RIL_REQUEST_ISIM_AUTHENTICATION, radio_1_5::requestIsimAuthenticationResponse}, - {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, radio_1_5::acknowledgeIncomingGsmSmsWithPduResponse}, - {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, radio_1_5::sendEnvelopeWithStatusResponse}, - {RIL_REQUEST_VOICE_RADIO_TECH, radio_1_5::getVoiceRadioTechnologyResponse}, - {RIL_REQUEST_GET_CELL_INFO_LIST, radio_1_5::getCellInfoListResponse}, - {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, radio_1_5::setCellInfoListRateResponse}, - {RIL_REQUEST_SET_INITIAL_ATTACH_APN, radio_1_5::setInitialAttachApnResponse}, - {RIL_REQUEST_IMS_REGISTRATION_STATE, radio_1_5::getImsRegistrationStateResponse}, - {RIL_REQUEST_IMS_SEND_SMS, radio_1_5::sendImsSmsResponse}, - {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, radio_1_5::iccTransmitApduBasicChannelResponse}, - {RIL_REQUEST_SIM_OPEN_CHANNEL, radio_1_5::iccOpenLogicalChannelResponse}, - {RIL_REQUEST_SIM_CLOSE_CHANNEL, radio_1_5::iccCloseLogicalChannelResponse}, - {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, radio_1_5::iccTransmitApduLogicalChannelResponse}, - {RIL_REQUEST_NV_READ_ITEM, radio_1_5::nvReadItemResponse}, - {RIL_REQUEST_NV_WRITE_ITEM, radio_1_5::nvWriteItemResponse}, - {RIL_REQUEST_NV_WRITE_CDMA_PRL, radio_1_5::nvWriteCdmaPrlResponse}, - {RIL_REQUEST_NV_RESET_CONFIG, radio_1_5::nvResetConfigResponse}, - {RIL_REQUEST_SET_UICC_SUBSCRIPTION, radio_1_5::setUiccSubscriptionResponse}, - {RIL_REQUEST_ALLOW_DATA, radio_1_5::setDataAllowedResponse}, - {RIL_REQUEST_GET_HARDWARE_CONFIG, radio_1_5::getHardwareConfigResponse}, - {RIL_REQUEST_SIM_AUTHENTICATION, radio_1_5::requestIccSimAuthenticationResponse}, - {RIL_REQUEST_GET_DC_RT_INFO, NULL}, - {RIL_REQUEST_SET_DC_RT_INFO_RATE, NULL}, - {RIL_REQUEST_SET_DATA_PROFILE, radio_1_5::setDataProfileResponse}, - {RIL_REQUEST_SHUTDOWN, radio_1_5::requestShutdownResponse}, - {RIL_REQUEST_GET_RADIO_CAPABILITY, radio_1_5::getRadioCapabilityResponse}, - {RIL_REQUEST_SET_RADIO_CAPABILITY, radio_1_5::setRadioCapabilityResponse}, - {RIL_REQUEST_START_LCE, radio_1_5::startLceServiceResponse}, - {RIL_REQUEST_STOP_LCE, radio_1_5::stopLceServiceResponse}, - {RIL_REQUEST_PULL_LCEDATA, radio_1_5::pullLceDataResponse}, - {RIL_REQUEST_GET_ACTIVITY_INFO, radio_1_5::getModemActivityInfoResponse}, - {RIL_REQUEST_SET_CARRIER_RESTRICTIONS, radio_1_5::setAllowedCarriersResponse}, - {RIL_REQUEST_GET_CARRIER_RESTRICTIONS, radio_1_5::getAllowedCarriersResponse}, - {RIL_REQUEST_SEND_DEVICE_STATE, radio_1_5::sendDeviceStateResponse}, - {RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, radio_1_5::setIndicationFilterResponse}, - {RIL_REQUEST_SET_SIM_CARD_POWER, radio_1_5::setSimCardPowerResponse}, - {RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, radio_1_5::setCarrierInfoForImsiEncryptionResponse}, - {RIL_REQUEST_START_NETWORK_SCAN, radio_1_5::startNetworkScanResponse}, - {RIL_REQUEST_STOP_NETWORK_SCAN, radio_1_5::stopNetworkScanResponse}, - {RIL_REQUEST_START_KEEPALIVE, radio_1_5::startKeepaliveResponse}, - {RIL_REQUEST_STOP_KEEPALIVE, radio_1_5::stopKeepaliveResponse}, - {RIL_REQUEST_START_NETWORK_SCAN4, radio_1_5::startNetworkScanResponse4}, - {RIL_REQUEST_GET_MODEM_STACK_STATUS, radio_1_5::getModemStackStatusResponse}, - {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_5::getPreferredNetworkTypeBitmapResponse}, - {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_5::setPreferredNetworkTypeBitmapResponse}, - {RIL_REQUEST_EMERGENCY_DIAL, radio_1_5::emergencyDialResponse}, - {RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, radio_1_5::setSystemSelectionChannelsResponse}, - {RIL_REQUEST_ENABLE_MODEM, radio_1_5::enableModemResponse}, - {RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4, radio_1_5::setAllowedCarriersResponse4}, - {RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4, radio_1_5::getAllowedCarriersResponse4}, - {RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA_1_5, radio_1_5::setSignalStrengthReportingCriteriaResponse_1_5}, - {RIL_REQUEST_ENABLE_UICC_APPLICATIONS, radio_1_5::enableUiccApplicationsResponse}, - {RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED, radio_1_5::areUiccApplicationsEnabledResponse}, - {RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT, radio_1_5::canToggleUiccApplicationsEnablementResponse}, - {RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5, radio_1_5::setSystemSelectionChannelsResponse_1_5}, - {RIL_REQUEST_START_NETWORK_SCAN_1_5, radio_1_5::startNetworkScanResponse_1_5}, diff --git a/guest/hals/ril/libril/ril_event.cpp b/guest/hals/ril/libril/ril_event.cpp deleted file mode 100644 index 84b8b72a..00000000 --- a/guest/hals/ril/libril/ril_event.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* //device/libs/telephony/ril_event.cpp -** -** Copyright 2008, 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. -*/ - -#define LOG_TAG "RILC" - -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <utils/Log.h> -#include <ril_event.h> -#include <string.h> -#include <sys/time.h> -#include <time.h> - -#include <pthread.h> -static pthread_mutex_t listMutex; -#define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex) -#define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex) -#define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL) -#define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex) - -#ifndef timeradd -#define timeradd(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ - if ((vvp)->tv_usec >= 1000000) { \ - (vvp)->tv_sec++; \ - (vvp)->tv_usec -= 1000000; \ - } \ - } while (0) -#endif - -#ifndef timercmp -#define timercmp(a, b, op) \ - ((a)->tv_sec == (b)->tv_sec \ - ? (a)->tv_usec op (b)->tv_usec \ - : (a)->tv_sec op (b)->tv_sec) -#endif - -#ifndef timersub -#define timersub(a, b, res) \ - do { \ - (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((res)->tv_usec < 0) { \ - (res)->tv_usec += 1000000; \ - (res)->tv_sec -= 1; \ - } \ - } while(0); -#endif - -static fd_set readFds; -static int nfds = 0; - -static struct ril_event * watch_table[MAX_FD_EVENTS]; -static struct ril_event timer_list; -static struct ril_event pending_list; - -#define DEBUG 0 - -#if DEBUG -#define dlog(x...) RLOGD( x ) -static void dump_event(struct ril_event * ev) -{ - dlog("~~~~ Event %x ~~~~", (unsigned int)ev); - dlog(" next = %x", (unsigned int)ev->next); - dlog(" prev = %x", (unsigned int)ev->prev); - dlog(" fd = %d", ev->fd); - dlog(" pers = %d", ev->persist); - dlog(" timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec); - dlog(" func = %x", (unsigned int)ev->func); - dlog(" param = %x", (unsigned int)ev->param); - dlog("~~~~~~~~~~~~~~~~~~"); -} -#else -#define dlog(x...) do {} while(0) -#define dump_event(x) do {} while(0) -#endif - -static void getNow(struct timeval * tv) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - tv->tv_sec = ts.tv_sec; - tv->tv_usec = ts.tv_nsec/1000; -} - -static void init_list(struct ril_event * list) -{ - memset(list, 0, sizeof(struct ril_event)); - list->next = list; - list->prev = list; - list->fd = -1; -} - -static void addToList(struct ril_event * ev, struct ril_event * list) -{ - ev->next = list; - ev->prev = list->prev; - ev->prev->next = ev; - list->prev = ev; - dump_event(ev); -} - -static void removeFromList(struct ril_event * ev) -{ - dlog("~~~~ +removeFromList ~~~~"); - dump_event(ev); - - ev->next->prev = ev->prev; - ev->prev->next = ev->next; - ev->next = NULL; - ev->prev = NULL; - dlog("~~~~ -removeFromList ~~~~"); -} - - -static void removeWatch(struct ril_event * ev, int index) -{ - dlog("~~~~ +removeWatch ~~~~"); - watch_table[index] = NULL; - ev->index = -1; - - FD_CLR(ev->fd, &readFds); - - if (ev->fd+1 == nfds) { - int n = 0; - - for (int i = 0; i < MAX_FD_EVENTS; i++) { - struct ril_event * rev = watch_table[i]; - - if ((rev != NULL) && (rev->fd > n)) { - n = rev->fd; - } - } - nfds = n + 1; - dlog("~~~~ nfds = %d ~~~~", nfds); - } - dlog("~~~~ -removeWatch ~~~~"); -} - -static void processTimeouts() -{ - dlog("~~~~ +processTimeouts ~~~~"); - MUTEX_ACQUIRE(); - struct timeval now; - struct ril_event * tev = timer_list.next; - struct ril_event * next; - - getNow(&now); - // walk list, see if now >= ev->timeout for any events - - dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); - while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) { - // Timer expired - dlog("~~~~ firing timer ~~~~"); - next = tev->next; - removeFromList(tev); - addToList(tev, &pending_list); - tev = next; - } - MUTEX_RELEASE(); - dlog("~~~~ -processTimeouts ~~~~"); -} - -static void processReadReadies(fd_set * rfds, int n) -{ - dlog("~~~~ +processReadReadies (%d) ~~~~", n); - MUTEX_ACQUIRE(); - - for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) { - struct ril_event * rev = watch_table[i]; - if (rev != NULL && FD_ISSET(rev->fd, rfds)) { - addToList(rev, &pending_list); - if (rev->persist == false) { - removeWatch(rev, i); - } - n--; - } - } - - MUTEX_RELEASE(); - dlog("~~~~ -processReadReadies (%d) ~~~~", n); -} - -static void firePending() -{ - dlog("~~~~ +firePending ~~~~"); - struct ril_event * ev = pending_list.next; - while (ev != &pending_list) { - struct ril_event * next = ev->next; - removeFromList(ev); - ev->func(ev->fd, 0, ev->param); - ev = next; - } - dlog("~~~~ -firePending ~~~~"); -} - -static int calcNextTimeout(struct timeval * tv) -{ - struct ril_event * tev = timer_list.next; - struct timeval now; - - getNow(&now); - - // Sorted list, so calc based on first node - if (tev == &timer_list) { - // no pending timers - return -1; - } - - dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); - dlog("~~~~ next = %ds + %dus ~~~~", - (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec); - if (timercmp(&tev->timeout, &now, >)) { - timersub(&tev->timeout, &now, tv); - } else { - // timer already expired. - tv->tv_sec = tv->tv_usec = 0; - } - return 0; -} - -// Initialize internal data structs -void ril_event_init() -{ - MUTEX_INIT(); - - FD_ZERO(&readFds); - init_list(&timer_list); - init_list(&pending_list); - memset(watch_table, 0, sizeof(watch_table)); -} - -// Initialize an event -void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param) -{ - dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev); - memset(ev, 0, sizeof(struct ril_event)); - ev->fd = fd; - ev->index = -1; - ev->persist = persist; - ev->func = func; - ev->param = param; - fcntl(fd, F_SETFL, O_NONBLOCK); -} - -// Add event to watch list -void ril_event_add(struct ril_event * ev) -{ - dlog("~~~~ +ril_event_add ~~~~"); - MUTEX_ACQUIRE(); - for (int i = 0; i < MAX_FD_EVENTS; i++) { - if (watch_table[i] == NULL) { - watch_table[i] = ev; - ev->index = i; - dlog("~~~~ added at %d ~~~~", i); - dump_event(ev); - FD_SET(ev->fd, &readFds); - if (ev->fd >= nfds) nfds = ev->fd+1; - dlog("~~~~ nfds = %d ~~~~", nfds); - break; - } - } - MUTEX_RELEASE(); - dlog("~~~~ -ril_event_add ~~~~"); -} - -// Add timer event -void ril_timer_add(struct ril_event * ev, struct timeval * tv) -{ - dlog("~~~~ +ril_timer_add ~~~~"); - MUTEX_ACQUIRE(); - - struct ril_event * list; - if (tv != NULL) { - // add to timer list - list = timer_list.next; - ev->fd = -1; // make sure fd is invalid - - struct timeval now; - getNow(&now); - timeradd(&now, tv, &ev->timeout); - - // keep list sorted - while (timercmp(&list->timeout, &ev->timeout, < ) - && (list != &timer_list)) { - list = list->next; - } - // list now points to the first event older than ev - addToList(ev, list); - } - - MUTEX_RELEASE(); - dlog("~~~~ -ril_timer_add ~~~~"); -} - -// Remove event from watch or timer list -void ril_event_del(struct ril_event * ev) -{ - dlog("~~~~ +ril_event_del ~~~~"); - MUTEX_ACQUIRE(); - - if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) { - MUTEX_RELEASE(); - return; - } - - removeWatch(ev, ev->index); - - MUTEX_RELEASE(); - dlog("~~~~ -ril_event_del ~~~~"); -} - -#if DEBUG -static void printReadies(fd_set * rfds) -{ - for (int i = 0; (i < MAX_FD_EVENTS); i++) { - struct ril_event * rev = watch_table[i]; - if (rev != NULL && FD_ISSET(rev->fd, rfds)) { - dlog("DON: fd=%d is ready", rev->fd); - } - } -} -#else -#define printReadies(rfds) do {} while(0) -#endif - -void ril_event_loop() -{ - int n; - fd_set rfds; - struct timeval tv; - struct timeval * ptv; - - - for (;;) { - - // make local copy of read fd_set - memcpy(&rfds, &readFds, sizeof(fd_set)); - if (-1 == calcNextTimeout(&tv)) { - // no pending timers; block indefinitely - dlog("~~~~ no timers; blocking indefinitely ~~~~"); - ptv = NULL; - } else { - dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec); - ptv = &tv; - } - printReadies(&rfds); - n = select(nfds, &rfds, NULL, NULL, ptv); - printReadies(&rfds); - dlog("~~~~ %d events fired ~~~~", n); - if (n < 0) { - if (errno == EINTR) continue; - - RLOGE("ril_event: select error (%d)", errno); - // bail? - return; - } - - // Check for timeouts - processTimeouts(); - // Check for read-ready - processReadReadies(&rfds, n); - // Fire away - firePending(); - } -} diff --git a/guest/hals/ril/libril/ril_ex.h b/guest/hals/ril/libril/ril_ex.h deleted file mode 100644 index e0fcd7bf..00000000 --- a/guest/hals/ril/libril/ril_ex.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Copyright (C) 2014 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. -*/ - -#ifndef RIL_EX_H_INCLUDED -#define RIL_EX_H_INCLUDED - -#include <guest/hals/ril/libril/ril.h> -#include <telephony/record_stream.h> - -#define NUM_ELEMS_SOCKET(a) (sizeof (a) / sizeof (a)[0]) - -struct ril_event; - -void rilEventAddWakeup_helper(struct ril_event *ev); -int blockingWrite_helper(int fd, void* data, size_t len); - -enum SocketWakeType {DONT_WAKE, WAKE_PARTIAL}; - -typedef enum { - RIL_TELEPHONY_SOCKET, - RIL_SAP_SOCKET -} RIL_SOCKET_TYPE; - -typedef struct SocketListenParam { - RIL_SOCKET_ID socket_id; - int fdListen; - int fdCommand; - const char* processName; - struct ril_event* commands_event; - struct ril_event* listen_event; - void (*processCommandsCallback)(int fd, short flags, void *param); - RecordStream *p_rs; - RIL_SOCKET_TYPE type; -} SocketListenParam; - -#endif diff --git a/guest/hals/ril/libril/ril_service.cpp b/guest/hals/ril/libril/ril_service.cpp deleted file mode 100755 index b7b02a6e..00000000 --- a/guest/hals/ril/libril/ril_service.cpp +++ /dev/null @@ -1,9795 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#define LOG_TAG "RILC" - -#include <android/hardware/radio/1.5/IRadio.h> -#include <android/hardware/radio/1.5/IRadioResponse.h> -#include <android/hardware/radio/1.5/IRadioIndication.h> -#include <android/hardware/radio/1.5/types.h> - -#include <android/hardware/radio/deprecated/1.0/IOemHook.h> - -#include <hwbinder/IPCThreadState.h> -#include <hwbinder/ProcessState.h> -#include <guest/hals/ril/libril/ril.h> -#include <telephony/ril_mnc.h> -#include <guest/hals/ril/libril/ril_service.h> -#include <hidl/HidlTransportSupport.h> -#include <utils/SystemClock.h> -#include <inttypes.h> - -#define INVALID_HEX_CHAR 16 - -using namespace android::hardware::radio; -using namespace android::hardware::radio::V1_0; -using namespace android::hardware::radio::deprecated::V1_0; -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::joinRpcThreadpool; -using ::android::hardware::Return; -using ::android::hardware::hidl_bitfield; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::hardware::hidl_array; -using ::android::hardware::Void; -using android::CommandInfo; -using android::RequestInfo; -using android::requestToString; -using android::sp; - -#define BOOL_TO_INT(x) (x ? 1 : 0) -#define ATOI_NULL_HANDLED(x) (x ? atoi(x) : -1) -#define ATOI_NULL_HANDLED_DEF(x, defaultVal) (x ? atoi(x) : defaultVal) - -#if defined(ANDROID_MULTI_SIM) -#define CALL_ONREQUEST(a, b, c, d, e) \ - s_vendorFunctions->onRequest((a), (b), (c), (d), ((RIL_SOCKET_ID)(e))) -#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest((RIL_SOCKET_ID)(a)) -#else -#define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d)) -#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest() -#endif - -#ifdef OEM_HOOK_DISABLED -constexpr bool kOemHookEnabled = false; -#else -constexpr bool kOemHookEnabled = true; -#endif - -RIL_RadioFunctions *s_vendorFunctions = NULL; -static CommandInfo *s_commands; - -struct RadioImpl_1_5; -struct OemHookImpl; - -#if (SIM_COUNT >= 2) -sp<RadioImpl_1_5> radioService[SIM_COUNT]; -sp<OemHookImpl> oemHookService[SIM_COUNT]; -int64_t nitzTimeReceived[SIM_COUNT]; -// counter used for synchronization. It is incremented every time response callbacks are updated. -volatile int32_t mCounterRadio[SIM_COUNT]; -volatile int32_t mCounterOemHook[SIM_COUNT]; -#else -sp<RadioImpl_1_5> radioService[1]; -sp<OemHookImpl> oemHookService[1]; -int64_t nitzTimeReceived[1]; -// counter used for synchronization. It is incremented every time response callbacks are updated. -volatile int32_t mCounterRadio[1]; -volatile int32_t mCounterOemHook[1]; -#endif - -static pthread_rwlock_t radioServiceRwlock = PTHREAD_RWLOCK_INITIALIZER; - -#if (SIM_COUNT >= 2) -static pthread_rwlock_t radioServiceRwlock2 = PTHREAD_RWLOCK_INITIALIZER; -#if (SIM_COUNT >= 3) -static pthread_rwlock_t radioServiceRwlock3 = PTHREAD_RWLOCK_INITIALIZER; -#if (SIM_COUNT >= 4) -static pthread_rwlock_t radioServiceRwlock4 = PTHREAD_RWLOCK_INITIALIZER; -#endif -#endif -#endif - -void convertRilHardwareConfigListToHal(void *response, size_t responseLen, - hidl_vec<HardwareConfig>& records); - -void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc); - -void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce); - -void convertRilSignalStrengthToHal(void *response, size_t responseLen, - SignalStrength& signalStrength); - -void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, - SetupDataCallResult& dcResult); - -void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, - ::android::hardware::radio::V1_4::SetupDataCallResult& dcResult); - -void convertRilDataCallListToHal(void *response, size_t responseLen, - hidl_vec<SetupDataCallResult>& dcResultList); - -void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records); - -void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType, - RIL_Errno e); - -struct RadioImpl_1_5 : public V1_5::IRadio { - int32_t mSlotId; - sp<IRadioResponse> mRadioResponse; - sp<IRadioIndication> mRadioIndication; - sp<V1_2::IRadioResponse> mRadioResponseV1_2; - sp<V1_2::IRadioIndication> mRadioIndicationV1_2; - sp<V1_3::IRadioResponse> mRadioResponseV1_3; - sp<V1_3::IRadioIndication> mRadioIndicationV1_3; - sp<V1_4::IRadioResponse> mRadioResponseV1_4; - sp<V1_4::IRadioIndication> mRadioIndicationV1_4; - sp<V1_5::IRadioResponse> mRadioResponseV1_5; - sp<V1_5::IRadioIndication> mRadioIndicationV1_5; - - Return<void> setResponseFunctions( - const ::android::sp<IRadioResponse>& radioResponse, - const ::android::sp<IRadioIndication>& radioIndication); - - Return<void> getIccCardStatus(int32_t serial); - - Return<void> supplyIccPinForApp(int32_t serial, const hidl_string& pin, - const hidl_string& aid); - - Return<void> supplyIccPukForApp(int32_t serial, const hidl_string& puk, - const hidl_string& pin, const hidl_string& aid); - - Return<void> supplyIccPin2ForApp(int32_t serial, - const hidl_string& pin2, - const hidl_string& aid); - - Return<void> supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, - const hidl_string& pin2, const hidl_string& aid); - - Return<void> changeIccPinForApp(int32_t serial, const hidl_string& oldPin, - const hidl_string& newPin, const hidl_string& aid); - - Return<void> changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, - const hidl_string& newPin2, const hidl_string& aid); - - Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin); - - Return<void> getCurrentCalls(int32_t serial); - - Return<void> dial(int32_t serial, const Dial& dialInfo); - - Return<void> getImsiForApp(int32_t serial, - const ::android::hardware::hidl_string& aid); - - Return<void> hangup(int32_t serial, int32_t gsmIndex); - - Return<void> hangupWaitingOrBackground(int32_t serial); - - Return<void> hangupForegroundResumeBackground(int32_t serial); - - Return<void> switchWaitingOrHoldingAndActive(int32_t serial); - - Return<void> conference(int32_t serial); - - Return<void> rejectCall(int32_t serial); - - Return<void> getLastCallFailCause(int32_t serial); - - Return<void> getSignalStrength(int32_t serial); - - Return<void> getVoiceRegistrationState(int32_t serial); - - Return<void> getDataRegistrationState(int32_t serial); - - Return<void> getOperator(int32_t serial); - - Return<void> setRadioPower(int32_t serial, bool on); - - Return<void> sendDtmf(int32_t serial, - const ::android::hardware::hidl_string& s); - - Return<void> sendSms(int32_t serial, const GsmSmsMessage& message); - - Return<void> sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message); - - Return<void> setupDataCall(int32_t serial, - RadioTechnology radioTechnology, - const DataProfileInfo& profileInfo, - bool modemCognitive, - bool roamingAllowed, - bool isRoaming); - - Return<void> iccIOForApp(int32_t serial, - const IccIo& iccIo); - - Return<void> sendUssd(int32_t serial, - const ::android::hardware::hidl_string& ussd); - - Return<void> cancelPendingUssd(int32_t serial); - - Return<void> getClir(int32_t serial); - - Return<void> setClir(int32_t serial, int32_t status); - - Return<void> getCallForwardStatus(int32_t serial, - const CallForwardInfo& callInfo); - - Return<void> setCallForward(int32_t serial, - const CallForwardInfo& callInfo); - - Return<void> getCallWaiting(int32_t serial, int32_t serviceClass); - - Return<void> setCallWaiting(int32_t serial, bool enable, int32_t serviceClass); - - Return<void> acknowledgeLastIncomingGsmSms(int32_t serial, - bool success, SmsAcknowledgeFailCause cause); - - Return<void> acceptCall(int32_t serial); - - Return<void> deactivateDataCall(int32_t serial, - int32_t cid, bool reasonRadioShutDown); - - Return<void> getFacilityLockForApp(int32_t serial, - const ::android::hardware::hidl_string& facility, - const ::android::hardware::hidl_string& password, - int32_t serviceClass, - const ::android::hardware::hidl_string& appId); - - Return<void> setFacilityLockForApp(int32_t serial, - const ::android::hardware::hidl_string& facility, - bool lockState, - const ::android::hardware::hidl_string& password, - int32_t serviceClass, - const ::android::hardware::hidl_string& appId); - - Return<void> setBarringPassword(int32_t serial, - const ::android::hardware::hidl_string& facility, - const ::android::hardware::hidl_string& oldPassword, - const ::android::hardware::hidl_string& newPassword); - - Return<void> getNetworkSelectionMode(int32_t serial); - - Return<void> setNetworkSelectionModeAutomatic(int32_t serial); - - Return<void> setNetworkSelectionModeManual(int32_t serial, - const ::android::hardware::hidl_string& operatorNumeric); - - Return<void> getAvailableNetworks(int32_t serial); - - Return<void> startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request); - - Return<void> stopNetworkScan(int32_t serial); - - Return<void> startDtmf(int32_t serial, - const ::android::hardware::hidl_string& s); - - Return<void> stopDtmf(int32_t serial); - - Return<void> getBasebandVersion(int32_t serial); - - Return<void> separateConnection(int32_t serial, int32_t gsmIndex); - - Return<void> setMute(int32_t serial, bool enable); - - Return<void> getMute(int32_t serial); - - Return<void> getClip(int32_t serial); - - Return<void> getDataCallList(int32_t serial); - - Return<void> setSuppServiceNotifications(int32_t serial, bool enable); - - Return<void> writeSmsToSim(int32_t serial, - const SmsWriteArgs& smsWriteArgs); - - Return<void> deleteSmsOnSim(int32_t serial, int32_t index); - - Return<void> setBandMode(int32_t serial, RadioBandMode mode); - - Return<void> getAvailableBandModes(int32_t serial); - - Return<void> sendEnvelope(int32_t serial, - const ::android::hardware::hidl_string& command); - - Return<void> sendTerminalResponseToSim(int32_t serial, - const ::android::hardware::hidl_string& commandResponse); - - Return<void> handleStkCallSetupRequestFromSim(int32_t serial, bool accept); - - Return<void> explicitCallTransfer(int32_t serial); - - Return<void> setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType); - - Return<void> getPreferredNetworkType(int32_t serial); - - Return<void> getNeighboringCids(int32_t serial); - - Return<void> setLocationUpdates(int32_t serial, bool enable); - - Return<void> setCdmaSubscriptionSource(int32_t serial, - CdmaSubscriptionSource cdmaSub); - - Return<void> setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type); - - Return<void> getCdmaRoamingPreference(int32_t serial); - - Return<void> setTTYMode(int32_t serial, TtyMode mode); - - Return<void> getTTYMode(int32_t serial); - - Return<void> setPreferredVoicePrivacy(int32_t serial, bool enable); - - Return<void> getPreferredVoicePrivacy(int32_t serial); - - Return<void> sendCDMAFeatureCode(int32_t serial, - const ::android::hardware::hidl_string& featureCode); - - Return<void> sendBurstDtmf(int32_t serial, - const ::android::hardware::hidl_string& dtmf, - int32_t on, - int32_t off); - - Return<void> sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms); - - Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial, - const CdmaSmsAck& smsAck); - - Return<void> getGsmBroadcastConfig(int32_t serial); - - Return<void> setGsmBroadcastConfig(int32_t serial, - const hidl_vec<GsmBroadcastSmsConfigInfo>& configInfo); - - Return<void> setGsmBroadcastActivation(int32_t serial, bool activate); - - Return<void> getCdmaBroadcastConfig(int32_t serial); - - Return<void> setCdmaBroadcastConfig(int32_t serial, - const hidl_vec<CdmaBroadcastSmsConfigInfo>& configInfo); - - Return<void> setCdmaBroadcastActivation(int32_t serial, bool activate); - - Return<void> getCDMASubscription(int32_t serial); - - Return<void> writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms); - - Return<void> deleteSmsOnRuim(int32_t serial, int32_t index); - - Return<void> getDeviceIdentity(int32_t serial); - - Return<void> exitEmergencyCallbackMode(int32_t serial); - - Return<void> getSmscAddress(int32_t serial); - - Return<void> setSmscAddress(int32_t serial, - const ::android::hardware::hidl_string& smsc); - - Return<void> reportSmsMemoryStatus(int32_t serial, bool available); - - Return<void> reportStkServiceIsRunning(int32_t serial); - - Return<void> getCdmaSubscriptionSource(int32_t serial); - - Return<void> requestIsimAuthentication(int32_t serial, - const ::android::hardware::hidl_string& challenge); - - Return<void> acknowledgeIncomingGsmSmsWithPdu(int32_t serial, - bool success, - const ::android::hardware::hidl_string& ackPdu); - - Return<void> sendEnvelopeWithStatus(int32_t serial, - const ::android::hardware::hidl_string& contents); - - Return<void> getVoiceRadioTechnology(int32_t serial); - - Return<void> getCellInfoList(int32_t serial); - - Return<void> setCellInfoListRate(int32_t serial, int32_t rate); - - Return<void> setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, - bool modemCognitive, bool isRoaming); - - Return<void> getImsRegistrationState(int32_t serial); - - Return<void> sendImsSms(int32_t serial, const ImsSmsMessage& message); - - Return<void> iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message); - - Return<void> iccOpenLogicalChannel(int32_t serial, - const ::android::hardware::hidl_string& aid, int32_t p2); - - Return<void> iccCloseLogicalChannel(int32_t serial, int32_t channelId); - - Return<void> iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message); - - Return<void> nvReadItem(int32_t serial, NvItem itemId); - - Return<void> nvWriteItem(int32_t serial, const NvWriteItem& item); - - Return<void> nvWriteCdmaPrl(int32_t serial, - const ::android::hardware::hidl_vec<uint8_t>& prl); - - Return<void> nvResetConfig(int32_t serial, ResetNvType resetType); - - Return<void> setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub); - - Return<void> setDataAllowed(int32_t serial, bool allow); - - Return<void> getHardwareConfig(int32_t serial); - - Return<void> requestIccSimAuthentication(int32_t serial, - int32_t authContext, - const ::android::hardware::hidl_string& authData, - const ::android::hardware::hidl_string& aid); - - Return<void> setDataProfile(int32_t serial, - const ::android::hardware::hidl_vec<DataProfileInfo>& profiles, bool isRoaming); - - Return<void> requestShutdown(int32_t serial); - - Return<void> getRadioCapability(int32_t serial); - - Return<void> setRadioCapability(int32_t serial, const RadioCapability& rc); - - Return<void> startLceService(int32_t serial, int32_t reportInterval, bool pullMode); - - Return<void> stopLceService(int32_t serial); - - Return<void> pullLceData(int32_t serial); - - Return<void> getModemActivityInfo(int32_t serial); - - Return<void> setAllowedCarriers(int32_t serial, - bool allAllowed, - const CarrierRestrictions& carriers); - - Return<void> getAllowedCarriers(int32_t serial); - - Return<void> sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state); - - Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter); - - Return<void> startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive); - - Return<void> stopKeepalive(int32_t serial, int32_t sessionHandle); - - Return<void> setSimCardPower(int32_t serial, bool powerUp); - Return<void> setSimCardPower_1_1(int32_t serial, - const V1_1::CardPowerState state); - - Return<void> responseAcknowledgement(); - - Return<void> setCarrierInfoForImsiEncryption(int32_t serial, - const V1_1::ImsiEncryptionInfo& message); - - void checkReturnStatus(Return<void>& ret); - - // Methods from ::android::hardware::radio::V1_2::IRadio follow. - Return<void> startNetworkScan_1_2(int32_t serial, - const ::android::hardware::radio::V1_2::NetworkScanRequest& request); - Return<void> setIndicationFilter_1_2(int32_t serial, - hidl_bitfield<::android::hardware::radio::V1_2::IndicationFilter> indicationFilter); - Return<void> setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs, - int32_t hysteresisDb, const hidl_vec<int32_t>& thresholdsDbm, - ::android::hardware::radio::V1_2::AccessNetwork accessNetwork); - Return<void> setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs, - int32_t hysteresisDlKbps, int32_t hysteresisUlKbps, - const hidl_vec<int32_t>& thresholdsDownlinkKbps, - const hidl_vec<int32_t>& thresholdsUplinkKbps, - ::android::hardware::radio::V1_2::AccessNetwork accessNetwork); - Return<void> setupDataCall_1_2(int32_t serial, - ::android::hardware::radio::V1_2::AccessNetwork accessNetwork, - const ::android::hardware::radio::V1_0::DataProfileInfo& dataProfileInfo, - bool modemCognitive, bool roamingAllowed, bool isRoaming, - ::android::hardware::radio::V1_2::DataRequestReason reason, - const hidl_vec<hidl_string>& addresses, const hidl_vec<hidl_string>& dnses); - Return<void> deactivateDataCall_1_2(int32_t serial, int32_t cid, - ::android::hardware::radio::V1_2::DataRequestReason reason); - - // Methods from ::android::hardware::radio::V1_3::IRadio follow. - Return<void> setSystemSelectionChannels(int32_t serial, bool specifyChannels, - const hidl_vec<::android::hardware::radio::V1_1::RadioAccessSpecifier>& specifiers); - Return<void> enableModem(int32_t serial, bool on); - Return<void> getModemStackStatus(int32_t serial); - - // Methods from ::android::hardware::radio::V1_4::IRadio follow. - Return<void> setupDataCall_1_4(int32_t serial, - ::android::hardware::radio::V1_4::AccessNetwork accessNetwork, - const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo, - bool roamingAllowed, ::android::hardware::radio::V1_2::DataRequestReason reason, - const hidl_vec<hidl_string>& addresses, const hidl_vec<hidl_string>& dnses); - Return<void> setInitialAttachApn_1_4(int32_t serial, - const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo); - Return<void> setDataProfile_1_4(int32_t serial, - const hidl_vec<::android::hardware::radio::V1_4::DataProfileInfo>& profiles); - Return<void> emergencyDial(int32_t serial, - const ::android::hardware::radio::V1_0::Dial& dialInfo, - hidl_bitfield<android::hardware::radio::V1_4::EmergencyServiceCategory> categories, - const hidl_vec<hidl_string>& urns, - ::android::hardware::radio::V1_4::EmergencyCallRouting routing, - bool fromEmergencyDialer, bool isTesting); - Return<void> startNetworkScan_1_4(int32_t serial, - const ::android::hardware::radio::V1_2::NetworkScanRequest& request); - Return<void> getPreferredNetworkTypeBitmap(int32_t serial); - Return<void> setPreferredNetworkTypeBitmap( - int32_t serial, hidl_bitfield<RadioAccessFamily> networkTypeBitmap); - Return<void> setAllowedCarriers_1_4(int32_t serial, - const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& carriers, - ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy); - Return<void> getAllowedCarriers_1_4(int32_t serial); - Return<void> getSignalStrength_1_4(int32_t serial); - - // Methods from ::android::hardware::radio::V1_5::IRadio follow. - Return<void> setSignalStrengthReportingCriteria_1_5(int32_t serial, - const ::android::hardware::radio::V1_5::SignalThresholdInfo& signalThresholdInfo, - const ::android::hardware::radio::V1_5::AccessNetwork accessNetwork); - Return<void> enableUiccApplications(int32_t serial, bool detach); - Return<void> areUiccApplicationsEnabled(int32_t serial); - Return<void> canToggleUiccApplicationsEnablement(int32_t serial); - Return<void> setSystemSelectionChannels_1_5(int32_t serial, bool specifyChannels, - const hidl_vec<::android::hardware::radio::V1_5::RadioAccessSpecifier>& specifiers); - Return<void> startNetworkScan_1_5(int32_t serial, - const ::android::hardware::radio::V1_5::NetworkScanRequest& request); -}; - -struct OemHookImpl : public IOemHook { - int32_t mSlotId; - sp<IOemHookResponse> mOemHookResponse; - sp<IOemHookIndication> mOemHookIndication; - - Return<void> setResponseFunctions( - const ::android::sp<IOemHookResponse>& oemHookResponse, - const ::android::sp<IOemHookIndication>& oemHookIndication); - - Return<void> sendRequestRaw(int32_t serial, - const ::android::hardware::hidl_vec<uint8_t>& data); - - Return<void> sendRequestStrings(int32_t serial, - const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data); -}; - -void memsetAndFreeStrings(int numPointers, ...) { - va_list ap; - va_start(ap, numPointers); - for (int i = 0; i < numPointers; i++) { - char *ptr = va_arg(ap, char *); - if (ptr) { -#ifdef MEMSET_FREED -#define MAX_STRING_LENGTH 4096 - memset(ptr, 0, strnlen(ptr, MAX_STRING_LENGTH)); -#endif - free(ptr); - } - } - va_end(ap); -} - -void sendErrorResponse(RequestInfo *pRI, RIL_Errno err) { - pRI->pCI->responseFunction((int) pRI->socket_id, - (int) RadioResponseType::SOLICITED, pRI->token, err, NULL, 0); -} - -/** - * Copies over src to dest. If memory allocation fails, responseFunction() is called for the - * request with error RIL_E_NO_MEMORY. The size() method is used to determine the size of the - * destination buffer into which the HIDL string is copied. If there is a discrepancy between - * the string length reported by the size() method, and the length of the string returned by - * the c_str() method, the function will return false indicating a failure. - * - * Returns true on success, and false on failure. - */ -bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI, bool allowEmpty) { - size_t len = src.size(); - if (len == 0 && !allowEmpty) { - *dest = NULL; - return true; - } - *dest = (char *) calloc(len + 1, sizeof(char)); - if (*dest == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return false; - } - if (strlcpy(*dest, src.c_str(), len + 1) >= (len + 1)) { - RLOGE("Copy of the HIDL string has been truncated, as " - "the string length reported by size() does not " - "match the length of string returned by c_str()."); - free(*dest); - *dest = NULL; - sendErrorResponse(pRI, RIL_E_INTERNAL_ERR); - return false; - } - return true; -} - -bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) { - return copyHidlStringToRil(dest, src, pRI, false); -} - -hidl_string convertCharPtrToHidlString(const char *ptr) { - hidl_string ret; - if (ptr != NULL) { - // TODO: replace this with strnlen - ret.setToExternal(ptr, strlen(ptr)); - } - return ret; -} - -bool dispatchVoid(int serial, int slotId, int request) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - CALL_ONREQUEST(request, NULL, 0, pRI, slotId); - return true; -} - -bool dispatchString(int serial, int slotId, int request, const char * str) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - char *pString; - if (!copyHidlStringToRil(&pString, str, pRI)) { - return false; - } - - CALL_ONREQUEST(request, pString, sizeof(char *), pRI, slotId); - - memsetAndFreeStrings(1, pString); - return true; -} - -bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty, int countStrings, ...) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - char **pStrings; - pStrings = (char **)calloc(countStrings, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(request)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return false; - } - va_list ap; - va_start(ap, countStrings); - for (int i = 0; i < countStrings; i++) { - const char* str = va_arg(ap, const char *); - if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI, allowEmpty)) { - va_end(ap); - for (int j = 0; j < i; j++) { - memsetAndFreeStrings(1, pStrings[j]); - } - free(pStrings); - return false; - } - } - va_end(ap); - - CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); - - if (pStrings != NULL) { - for (int i = 0 ; i < countStrings ; i++) { - memsetAndFreeStrings(1, pStrings[i]); - } - -#ifdef MEMSET_FREED - memset(pStrings, 0, countStrings * sizeof(char *)); -#endif - free(pStrings); - } - return true; -} - -bool dispatchStrings(int serial, int slotId, int request, const hidl_vec<hidl_string>& data) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - int countStrings = data.size(); - char **pStrings; - pStrings = (char **)calloc(countStrings, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(request)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return false; - } - - for (int i = 0; i < countStrings; i++) { - if (!copyHidlStringToRil(&pStrings[i], data[i], pRI)) { - for (int j = 0; j < i; j++) { - memsetAndFreeStrings(1, pStrings[j]); - } - free(pStrings); - return false; - } - } - - CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); - - if (pStrings != NULL) { - for (int i = 0 ; i < countStrings ; i++) { - memsetAndFreeStrings(1, pStrings[i]); - } - -#ifdef MEMSET_FREED - memset(pStrings, 0, countStrings * sizeof(char *)); -#endif - free(pStrings); - } - return true; -} - -bool dispatchInts(int serial, int slotId, int request, int countInts, ...) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - int *pInts = (int *)calloc(countInts, sizeof(int)); - - if (pInts == NULL) { - RLOGE("Memory allocation failed for request %s", requestToString(request)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return false; - } - va_list ap; - va_start(ap, countInts); - for (int i = 0; i < countInts; i++) { - pInts[i] = va_arg(ap, int); - } - va_end(ap); - - CALL_ONREQUEST(request, pInts, countInts * sizeof(int), pRI, slotId); - - if (pInts != NULL) { -#ifdef MEMSET_FREED - memset(pInts, 0, countInts * sizeof(int)); -#endif - free(pInts); - } - return true; -} - -bool dispatchCallForwardStatus(int serial, int slotId, int request, - const CallForwardInfo& callInfo) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - RIL_CallForwardInfo cf; - cf.status = (int) callInfo.status; - cf.reason = callInfo.reason; - cf.serviceClass = callInfo.serviceClass; - cf.toa = callInfo.toa; - cf.timeSeconds = callInfo.timeSeconds; - - if (!copyHidlStringToRil(&cf.number, callInfo.number, pRI)) { - return false; - } - - CALL_ONREQUEST(request, &cf, sizeof(cf), pRI, slotId); - - memsetAndFreeStrings(1, cf.number); - - return true; -} - -bool dispatchRaw(int serial, int slotId, int request, const hidl_vec<uint8_t>& rawBytes) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - const uint8_t *uData = rawBytes.data(); - - CALL_ONREQUEST(request, (void *) uData, rawBytes.size(), pRI, slotId); - - return true; -} - -bool dispatchIccApdu(int serial, int slotId, int request, const SimApdu& message) { - RequestInfo *pRI = android::addRequestToList(serial, slotId, request); - if (pRI == NULL) { - return false; - } - - RIL_SIM_APDU apdu = {}; - - apdu.sessionid = message.sessionId; - apdu.cla = message.cla; - apdu.instruction = message.instruction; - apdu.p1 = message.p1; - apdu.p2 = message.p2; - apdu.p3 = message.p3; - - if (!copyHidlStringToRil(&apdu.data, message.data, pRI)) { - return false; - } - - CALL_ONREQUEST(request, &apdu, sizeof(apdu), pRI, slotId); - - memsetAndFreeStrings(1, apdu.data); - - return true; -} - -void checkReturnStatus(int32_t slotId, Return<void>& ret, bool isRadioService) { - if (ret.isOk() == false) { - RLOGE("checkReturnStatus: unable to call response/indication callback"); - // Remote process hosting the callbacks must be dead. Reset the callback objects; - // there's no other recovery to be done here. When the client process is back up, it will - // call setResponseFunctions() - - // Caller should already hold rdlock, release that first - // note the current counter to avoid overwriting updates made by another thread before - // write lock is acquired. - int counter = isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId]; - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock(slotId); - int ret = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(ret == 0); - - // acquire wrlock - ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); - assert(ret == 0); - - // make sure the counter value has not changed - if (counter == (isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId])) { - if (isRadioService) { - radioService[slotId]->mRadioResponse = NULL; - radioService[slotId]->mRadioIndication = NULL; - radioService[slotId]->mRadioResponseV1_2 = NULL; - radioService[slotId]->mRadioIndicationV1_2 = NULL; - radioService[slotId]->mRadioResponseV1_3 = NULL; - radioService[slotId]->mRadioIndicationV1_3 = NULL; - radioService[slotId]->mRadioResponseV1_4 = NULL; - radioService[slotId]->mRadioIndicationV1_4 = NULL; - radioService[slotId]->mRadioResponseV1_5 = NULL; - radioService[slotId]->mRadioIndicationV1_5 = NULL; - } else { - oemHookService[slotId]->mOemHookResponse = NULL; - oemHookService[slotId]->mOemHookIndication = NULL; - } - isRadioService ? mCounterRadio[slotId]++ : mCounterOemHook[slotId]++; - } else { - RLOGE("checkReturnStatus: not resetting responseFunctions as they likely " - "got updated on another thread"); - } - - // release wrlock - ret = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(ret == 0); - - // Reacquire rdlock - ret = pthread_rwlock_rdlock(radioServiceRwlockPtr); - assert(ret == 0); - } -} - -void RadioImpl_1_5::checkReturnStatus(Return<void>& ret) { - ::checkReturnStatus(mSlotId, ret, true); -} - -Return<void> RadioImpl_1_5::setResponseFunctions( - const ::android::sp<IRadioResponse>& radioResponseParam, - const ::android::sp<IRadioIndication>& radioIndicationParam) { - RLOGD("setResponseFunctions"); - - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock(mSlotId); - int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); - assert(ret == 0); - - mRadioResponse = radioResponseParam; - mRadioIndication = radioIndicationParam; - - mRadioResponseV1_5 = V1_5::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr); - mRadioIndicationV1_5 = V1_5::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr); - if (mRadioResponseV1_5 == nullptr || mRadioIndicationV1_5 == nullptr) { - mRadioResponseV1_5 = nullptr; - mRadioIndicationV1_5 = nullptr; - } - - mRadioResponseV1_4 = V1_4::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr); - mRadioIndicationV1_4 = V1_4::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr); - if (mRadioResponseV1_4 == nullptr || mRadioIndicationV1_4 == nullptr) { - mRadioResponseV1_4 = nullptr; - mRadioIndicationV1_4 = nullptr; - } - - mRadioResponseV1_3 = V1_3::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr); - mRadioIndicationV1_3 = V1_3::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr); - if (mRadioResponseV1_3 == nullptr || mRadioIndicationV1_3 == nullptr) { - mRadioResponseV1_3 = nullptr; - mRadioIndicationV1_3 = nullptr; - } - - mRadioResponseV1_2 = V1_2::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr); - mRadioIndicationV1_2 = V1_2::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr); - if (mRadioResponseV1_2 == nullptr || mRadioIndicationV1_2 == nullptr) { - mRadioResponseV1_2 = nullptr; - mRadioIndicationV1_2 = nullptr; - } - - mCounterRadio[mSlotId]++; - - ret = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(ret == 0); - - // client is connected. Send initial indications. - android::onNewCommandConnect((RIL_SOCKET_ID) mSlotId); - - return Void(); -} - -Return<void> RadioImpl_1_5::getIccCardStatus(int32_t serial) { -#if VDBG - RLOGD("getIccCardStatus: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS); - return Void(); -} - -Return<void> RadioImpl_1_5::supplyIccPinForApp(int32_t serial, const hidl_string& pin, - const hidl_string& aid) { -#if VDBG - RLOGD("supplyIccPinForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN, true, - 2, pin.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::supplyIccPukForApp(int32_t serial, const hidl_string& puk, - const hidl_string& pin, const hidl_string& aid) { -#if VDBG - RLOGD("supplyIccPukForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK, true, - 3, puk.c_str(), pin.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2, - const hidl_string& aid) { -#if VDBG - RLOGD("supplyIccPin2ForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2, true, - 2, pin2.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, - const hidl_string& pin2, const hidl_string& aid) { -#if VDBG - RLOGD("supplyIccPuk2ForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2, true, - 3, puk2.c_str(), pin2.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::changeIccPinForApp(int32_t serial, const hidl_string& oldPin, - const hidl_string& newPin, const hidl_string& aid) { -#if VDBG - RLOGD("changeIccPinForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN, true, - 3, oldPin.c_str(), newPin.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, - const hidl_string& newPin2, const hidl_string& aid) { -#if VDBG - RLOGD("changeIccPin2ForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2, true, - 3, oldPin2.c_str(), newPin2.c_str(), aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::supplyNetworkDepersonalization(int32_t serial, - const hidl_string& netPin) { -#if VDBG - RLOGD("supplyNetworkDepersonalization: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, true, - 1, netPin.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::getCurrentCalls(int32_t serial) { -#if VDBG - RLOGD("getCurrentCalls: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS); - return Void(); -} - -Return<void> RadioImpl_1_5::dial(int32_t serial, const Dial& dialInfo) { -#if VDBG - RLOGD("dial: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_DIAL); - if (pRI == NULL) { - return Void(); - } - RIL_Dial dial = {}; - RIL_UUS_Info uusInfo = {}; - int32_t sizeOfDial = sizeof(dial); - - if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) { - return Void(); - } - dial.clir = (int) dialInfo.clir; - - if (dialInfo.uusInfo.size() != 0) { - uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType; - uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs; - - if (dialInfo.uusInfo[0].uusData.size() == 0) { - uusInfo.uusData = NULL; - uusInfo.uusLength = 0; - } else { - if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) { - memsetAndFreeStrings(1, dial.address); - return Void(); - } - uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size(); - } - - dial.uusInfo = &uusInfo; - } - - CALL_ONREQUEST(RIL_REQUEST_DIAL, &dial, sizeOfDial, pRI, mSlotId); - - memsetAndFreeStrings(2, dial.address, uusInfo.uusData); - - return Void(); -} - -Return<void> RadioImpl_1_5::getImsiForApp(int32_t serial, const hidl_string& aid) { -#if VDBG - RLOGD("getImsiForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, false, - 1, aid.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::hangup(int32_t serial, int32_t gsmIndex) { -#if VDBG - RLOGD("hangup: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_HANGUP, 1, gsmIndex); - return Void(); -} - -Return<void> RadioImpl_1_5::hangupWaitingOrBackground(int32_t serial) { -#if VDBG - RLOGD("hangupWaitingOrBackground: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND); - return Void(); -} - -Return<void> RadioImpl_1_5::hangupForegroundResumeBackground(int32_t serial) { -#if VDBG - RLOGD("hangupForegroundResumeBackground: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND); - return Void(); -} - -Return<void> RadioImpl_1_5::switchWaitingOrHoldingAndActive(int32_t serial) { -#if VDBG - RLOGD("switchWaitingOrHoldingAndActive: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE); - return Void(); -} - -Return<void> RadioImpl_1_5::conference(int32_t serial) { -#if VDBG - RLOGD("conference: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE); - return Void(); -} - -Return<void> RadioImpl_1_5::rejectCall(int32_t serial) { -#if VDBG - RLOGD("rejectCall: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB); - return Void(); -} - -Return<void> RadioImpl_1_5::getLastCallFailCause(int32_t serial) { -#if VDBG - RLOGD("getLastCallFailCause: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_LAST_CALL_FAIL_CAUSE); - return Void(); -} - -Return<void> RadioImpl_1_5::getSignalStrength(int32_t serial) { -#if VDBG - RLOGD("getSignalStrength: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH); - return Void(); -} - -Return<void> RadioImpl_1_5::getVoiceRegistrationState(int32_t serial) { -#if VDBG - RLOGD("getVoiceRegistrationState: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE); - return Void(); -} - -Return<void> RadioImpl_1_5::getDataRegistrationState(int32_t serial) { -#if VDBG - RLOGD("getDataRegistrationState: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE); - return Void(); -} - -Return<void> RadioImpl_1_5::getOperator(int32_t serial) { -#if VDBG - RLOGD("getOperator: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR); - return Void(); -} - -Return<void> RadioImpl_1_5::setRadioPower(int32_t serial, bool on) { - RLOGD("setRadioPower: serial %d on %d", serial, on); - dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on)); - return Void(); -} - -Return<void> RadioImpl_1_5::sendDtmf(int32_t serial, const hidl_string& s) { -#if VDBG - RLOGD("sendDtmf: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_DTMF, s.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::sendSms(int32_t serial, const GsmSmsMessage& message) { -#if VDBG - RLOGD("sendSms: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, false, - 2, message.smscPdu.c_str(), message.pdu.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message) { -#if VDBG - RLOGD("sendSMSExpectMore: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE, false, - 2, message.smscPdu.c_str(), message.pdu.c_str()); - return Void(); -} - -static bool convertMvnoTypeToString(MvnoType type, char *&str) { - switch (type) { - case MvnoType::IMSI: - str = (char *)"imsi"; - return true; - case MvnoType::GID: - str = (char *)"gid"; - return true; - case MvnoType::SPN: - str = (char *)"spn"; - return true; - case MvnoType::NONE: - str = (char *)""; - return true; - } - return false; -} - -Return<void> RadioImpl_1_5::setupDataCall(int32_t serial, RadioTechnology radioTechnology, - const DataProfileInfo& dataProfileInfo, bool modemCognitive, - bool roamingAllowed, bool isRoaming) { - -#if VDBG - RLOGD("setupDataCall: serial %d", serial); -#endif - - if (s_vendorFunctions->version >= 4 && s_vendorFunctions->version <= 14) { - const hidl_string &protocol = - (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); - dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 7, - std::to_string((int) radioTechnology + 2).c_str(), - std::to_string((int) dataProfileInfo.profileId).c_str(), - dataProfileInfo.apn.c_str(), - dataProfileInfo.user.c_str(), - dataProfileInfo.password.c_str(), - std::to_string((int) dataProfileInfo.authType).c_str(), - protocol.c_str()); - } else if (s_vendorFunctions->version >= 15) { - char *mvnoTypeStr = NULL; - if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, mvnoTypeStr)) { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SETUP_DATA_CALL); - if (pRI != NULL) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - } - return Void(); - } - dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15, - std::to_string((int) radioTechnology + 2).c_str(), - std::to_string((int) dataProfileInfo.profileId).c_str(), - dataProfileInfo.apn.c_str(), - dataProfileInfo.user.c_str(), - dataProfileInfo.password.c_str(), - std::to_string((int) dataProfileInfo.authType).c_str(), - dataProfileInfo.protocol.c_str(), - dataProfileInfo.roamingProtocol.c_str(), - std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(), - std::to_string(dataProfileInfo.bearerBitmap).c_str(), - modemCognitive ? "1" : "0", - std::to_string(dataProfileInfo.mtu).c_str(), - mvnoTypeStr, - dataProfileInfo.mvnoMatchData.c_str(), - roamingAllowed ? "1" : "0"); - } else { - RLOGE("Unsupported RIL version %d, min version expected 4", s_vendorFunctions->version); - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SETUP_DATA_CALL); - if (pRI != NULL) { - sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); - } - } - return Void(); -} - -Return<void> RadioImpl_1_5::iccIOForApp(int32_t serial, const IccIo& iccIo) { -#if VDBG - RLOGD("iccIOForApp: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_IO); - if (pRI == NULL) { - return Void(); - } - - RIL_SIM_IO_v6 rilIccIo = {}; - rilIccIo.command = iccIo.command; - rilIccIo.fileid = iccIo.fileId; - if (!copyHidlStringToRil(&rilIccIo.path, iccIo.path, pRI)) { - return Void(); - } - - rilIccIo.p1 = iccIo.p1; - rilIccIo.p2 = iccIo.p2; - rilIccIo.p3 = iccIo.p3; - - if (!copyHidlStringToRil(&rilIccIo.data, iccIo.data, pRI)) { - memsetAndFreeStrings(1, rilIccIo.path); - return Void(); - } - - if (!copyHidlStringToRil(&rilIccIo.pin2, iccIo.pin2, pRI)) { - memsetAndFreeStrings(2, rilIccIo.path, rilIccIo.data); - return Void(); - } - - if (!copyHidlStringToRil(&rilIccIo.aidPtr, iccIo.aid, pRI)) { - memsetAndFreeStrings(3, rilIccIo.path, rilIccIo.data, rilIccIo.pin2); - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_SIM_IO, &rilIccIo, sizeof(rilIccIo), pRI, mSlotId); - - memsetAndFreeStrings(4, rilIccIo.path, rilIccIo.data, rilIccIo.pin2, rilIccIo.aidPtr); - - return Void(); -} - -Return<void> RadioImpl_1_5::sendUssd(int32_t serial, const hidl_string& ussd) { -#if VDBG - RLOGD("sendUssd: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_SEND_USSD, ussd.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::cancelPendingUssd(int32_t serial) { -#if VDBG - RLOGD("cancelPendingUssd: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD); - return Void(); -} - -Return<void> RadioImpl_1_5::getClir(int32_t serial) { -#if VDBG - RLOGD("getClir: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR); - return Void(); -} - -Return<void> RadioImpl_1_5::setClir(int32_t serial, int32_t status) { -#if VDBG - RLOGD("setClir: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CLIR, 1, status); - return Void(); -} - -Return<void> RadioImpl_1_5::getCallForwardStatus(int32_t serial, const CallForwardInfo& callInfo) { -#if VDBG - RLOGD("getCallForwardStatus: serial %d", serial); -#endif - dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, - callInfo); - return Void(); -} - -Return<void> RadioImpl_1_5::setCallForward(int32_t serial, const CallForwardInfo& callInfo) { -#if VDBG - RLOGD("setCallForward: serial %d", serial); -#endif - dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_SET_CALL_FORWARD, - callInfo); - return Void(); -} - -Return<void> RadioImpl_1_5::getCallWaiting(int32_t serial, int32_t serviceClass) { -#if VDBG - RLOGD("getCallWaiting: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_QUERY_CALL_WAITING, 1, serviceClass); - return Void(); -} - -Return<void> RadioImpl_1_5::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) { -#if VDBG - RLOGD("setCallWaiting: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CALL_WAITING, 2, BOOL_TO_INT(enable), - serviceClass); - return Void(); -} - -Return<void> RadioImpl_1_5::acknowledgeLastIncomingGsmSms(int32_t serial, - bool success, SmsAcknowledgeFailCause cause) { -#if VDBG - RLOGD("acknowledgeLastIncomingGsmSms: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SMS_ACKNOWLEDGE, 2, BOOL_TO_INT(success), - cause); - return Void(); -} - -Return<void> RadioImpl_1_5::acceptCall(int32_t serial) { -#if VDBG - RLOGD("acceptCall: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER); - return Void(); -} - -Return<void> RadioImpl_1_5::deactivateDataCall(int32_t serial, - int32_t cid, bool reasonRadioShutDown) { -#if VDBG - RLOGD("deactivateDataCall: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL, false, - 2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0"); - return Void(); -} - -Return<void> RadioImpl_1_5::getFacilityLockForApp(int32_t serial, const hidl_string& facility, - const hidl_string& password, int32_t serviceClass, - const hidl_string& appId) { -#if VDBG - RLOGD("getFacilityLockForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK, true, - 4, facility.c_str(), password.c_str(), - (std::to_string(serviceClass)).c_str(), appId.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::setFacilityLockForApp(int32_t serial, const hidl_string& facility, - bool lockState, const hidl_string& password, - int32_t serviceClass, const hidl_string& appId) { -#if VDBG - RLOGD("setFacilityLockForApp: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK, true, - 5, facility.c_str(), lockState ? "1" : "0", password.c_str(), - (std::to_string(serviceClass)).c_str(), appId.c_str() ); - return Void(); -} - -Return<void> RadioImpl_1_5::setBarringPassword(int32_t serial, const hidl_string& facility, - const hidl_string& oldPassword, - const hidl_string& newPassword) { -#if VDBG - RLOGD("setBarringPassword: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD, true, - 3, facility.c_str(), oldPassword.c_str(), newPassword.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::getNetworkSelectionMode(int32_t serial) { -#if VDBG - RLOGD("getNetworkSelectionMode: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE); - return Void(); -} - -Return<void> RadioImpl_1_5::setNetworkSelectionModeAutomatic(int32_t serial) { -#if VDBG - RLOGD("setNetworkSelectionModeAutomatic: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC); - return Void(); -} - -Return<void> RadioImpl_1_5::setNetworkSelectionModeManual(int32_t serial, - const hidl_string& operatorNumeric) { -#if VDBG - RLOGD("setNetworkSelectionModeManual: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, - operatorNumeric.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::getAvailableNetworks(int32_t serial) { -#if VDBG - RLOGD("getAvailableNetworks: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS); - return Void(); -} - -Return<void> RadioImpl_1_5::startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) { -#if VDBG - RLOGD("startNetworkScan: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN); - if (pRI == NULL) { - return Void(); - } - - if (request.specifiers.size() > MAX_RADIO_ACCESS_NETWORKS) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - - RIL_NetworkScanRequest scan_request = {}; - - scan_request.type = (RIL_ScanType) request.type; - scan_request.interval = request.interval; - scan_request.specifiers_length = request.specifiers.size(); - for (size_t i = 0; i < request.specifiers.size(); ++i) { - if (request.specifiers[i].geranBands.size() > MAX_BANDS || - request.specifiers[i].utranBands.size() > MAX_BANDS || - request.specifiers[i].eutranBands.size() > MAX_BANDS || - request.specifiers[i].channels.size() > MAX_CHANNELS) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - const V1_1::RadioAccessSpecifier& ras_from = - request.specifiers[i]; - RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i]; - - ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork; - ras_to.channels_length = ras_from.channels.size(); - - std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels); - const std::vector<uint32_t> * bands = nullptr; - switch (request.specifiers[i].radioAccessNetwork) { - case V1_1::RadioAccessNetworks::GERAN: - ras_to.bands_length = ras_from.geranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.geranBands; - break; - case V1_1::RadioAccessNetworks::UTRAN: - ras_to.bands_length = ras_from.utranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.utranBands; - break; - case V1_1::RadioAccessNetworks::EUTRAN: - ras_to.bands_length = ras_from.eutranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.eutranBands; - break; - default: - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - // safe to copy to geran_bands because it's a union member - for (size_t idx = 0; idx < ras_to.bands_length; ++idx) { - ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx]; - } - } - - CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI, - mSlotId); - - return Void(); -} - -Return<void> RadioImpl_1_5::stopNetworkScan(int32_t serial) { -#if VDBG - RLOGD("stopNetworkScan: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_NETWORK_SCAN); - return Void(); -} - -Return<void> RadioImpl_1_5::startDtmf(int32_t serial, const hidl_string& s) { -#if VDBG - RLOGD("startDtmf: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_DTMF_START, - s.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::stopDtmf(int32_t serial) { -#if VDBG - RLOGD("stopDtmf: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP); - return Void(); -} - -Return<void> RadioImpl_1_5::getBasebandVersion(int32_t serial) { -#if VDBG - RLOGD("getBasebandVersion: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION); - return Void(); -} - -Return<void> RadioImpl_1_5::separateConnection(int32_t serial, int32_t gsmIndex) { -#if VDBG - RLOGD("separateConnection: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SEPARATE_CONNECTION, 1, gsmIndex); - return Void(); -} - -Return<void> RadioImpl_1_5::setMute(int32_t serial, bool enable) { -#if VDBG - RLOGD("setMute: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_MUTE, 1, BOOL_TO_INT(enable)); - return Void(); -} - -Return<void> RadioImpl_1_5::getMute(int32_t serial) { -#if VDBG - RLOGD("getMute: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE); - return Void(); -} - -Return<void> RadioImpl_1_5::getClip(int32_t serial) { -#if VDBG - RLOGD("getClip: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP); - return Void(); -} - -Return<void> RadioImpl_1_5::getDataCallList(int32_t serial) { -#if VDBG - RLOGD("getDataCallList: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST); - return Void(); -} - -Return<void> RadioImpl_1_5::setSuppServiceNotifications(int32_t serial, bool enable) { -#if VDBG - RLOGD("setSuppServiceNotifications: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, 1, - BOOL_TO_INT(enable)); - return Void(); -} - -Return<void> RadioImpl_1_5::writeSmsToSim(int32_t serial, const SmsWriteArgs& smsWriteArgs) { -#if VDBG - RLOGD("writeSmsToSim: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_WRITE_SMS_TO_SIM); - if (pRI == NULL) { - return Void(); - } - - RIL_SMS_WriteArgs args; - args.status = (int) smsWriteArgs.status; - - if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) { - return Void(); - } - - if (!copyHidlStringToRil(&args.smsc, smsWriteArgs.smsc, pRI)) { - memsetAndFreeStrings(1, args.pdu); - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_WRITE_SMS_TO_SIM, &args, sizeof(args), pRI, mSlotId); - - memsetAndFreeStrings(2, args.smsc, args.pdu); - - return Void(); -} - -Return<void> RadioImpl_1_5::deleteSmsOnSim(int32_t serial, int32_t index) { -#if VDBG - RLOGD("deleteSmsOnSim: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_DELETE_SMS_ON_SIM, 1, index); - return Void(); -} - -Return<void> RadioImpl_1_5::setBandMode(int32_t serial, RadioBandMode mode) { -#if VDBG - RLOGD("setBandMode: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_BAND_MODE, 1, mode); - return Void(); -} - -Return<void> RadioImpl_1_5::getAvailableBandModes(int32_t serial) { -#if VDBG - RLOGD("getAvailableBandModes: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE); - return Void(); -} - -Return<void> RadioImpl_1_5::sendEnvelope(int32_t serial, const hidl_string& command) { -#if VDBG - RLOGD("sendEnvelope: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, - command.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::sendTerminalResponseToSim(int32_t serial, - const hidl_string& commandResponse) { -#if VDBG - RLOGD("sendTerminalResponseToSim: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, - commandResponse.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) { -#if VDBG - RLOGD("handleStkCallSetupRequestFromSim: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, - 1, BOOL_TO_INT(accept)); - return Void(); -} - -Return<void> RadioImpl_1_5::explicitCallTransfer(int32_t serial) { -#if VDBG - RLOGD("explicitCallTransfer: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER); - return Void(); -} - -Return<void> RadioImpl_1_5::setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType) { -#if VDBG - RLOGD("setPreferredNetworkType: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, 1, nwType); - return Void(); -} - -Return<void> RadioImpl_1_5::getPreferredNetworkType(int32_t serial) { -#if VDBG - RLOGD("getPreferredNetworkType: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE); - return Void(); -} - -Return<void> RadioImpl_1_5::getNeighboringCids(int32_t serial) { -#if VDBG - RLOGD("getNeighboringCids: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_NEIGHBORING_CELL_IDS); - return Void(); -} - -Return<void> RadioImpl_1_5::setLocationUpdates(int32_t serial, bool enable) { -#if VDBG - RLOGD("setLocationUpdates: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_LOCATION_UPDATES, 1, BOOL_TO_INT(enable)); - return Void(); -} - -Return<void> RadioImpl_1_5::setCdmaSubscriptionSource(int32_t serial, CdmaSubscriptionSource cdmaSub) { -#if VDBG - RLOGD("setCdmaSubscriptionSource: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, 1, cdmaSub); - return Void(); -} - -Return<void> RadioImpl_1_5::setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type) { -#if VDBG - RLOGD("setCdmaRoamingPreference: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, 1, type); - return Void(); -} - -Return<void> RadioImpl_1_5::getCdmaRoamingPreference(int32_t serial) { -#if VDBG - RLOGD("getCdmaRoamingPreference: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE); - return Void(); -} - -Return<void> RadioImpl_1_5::setTTYMode(int32_t serial, TtyMode mode) { -#if VDBG - RLOGD("setTTYMode: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_TTY_MODE, 1, mode); - return Void(); -} - -Return<void> RadioImpl_1_5::getTTYMode(int32_t serial) { -#if VDBG - RLOGD("getTTYMode: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE); - return Void(); -} - -Return<void> RadioImpl_1_5::setPreferredVoicePrivacy(int32_t serial, bool enable) { -#if VDBG - RLOGD("setPreferredVoicePrivacy: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, - 1, BOOL_TO_INT(enable)); - return Void(); -} - -Return<void> RadioImpl_1_5::getPreferredVoicePrivacy(int32_t serial) { -#if VDBG - RLOGD("getPreferredVoicePrivacy: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE); - return Void(); -} - -Return<void> RadioImpl_1_5::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) { -#if VDBG - RLOGD("sendCDMAFeatureCode: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_CDMA_FLASH, - featureCode.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on, - int32_t off) { -#if VDBG - RLOGD("sendBurstDtmf: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF, false, - 3, dtmf.c_str(), (std::to_string(on)).c_str(), - (std::to_string(off)).c_str()); - return Void(); -} - -void constructCdmaSms(RIL_CDMA_SMS_Message &rcsm, const CdmaSmsMessage& sms) { - rcsm.uTeleserviceID = sms.teleserviceId; - rcsm.bIsServicePresent = BOOL_TO_INT(sms.isServicePresent); - rcsm.uServicecategory = sms.serviceCategory; - rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) sms.address.digitMode; - rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) sms.address.numberMode; - rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) sms.address.numberType; - rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) sms.address.numberPlan; - - rcsm.sAddress.number_of_digits = sms.address.digits.size(); - int digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); - for (int i = 0; i < digitLimit; i++) { - rcsm.sAddress.digits[i] = sms.address.digits[i]; - } - - rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) sms.subAddress.subaddressType; - rcsm.sSubAddress.odd = BOOL_TO_INT(sms.subAddress.odd); - - rcsm.sSubAddress.number_of_digits = sms.subAddress.digits.size(); - digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); - for (int i = 0; i < digitLimit; i++) { - rcsm.sSubAddress.digits[i] = sms.subAddress.digits[i]; - } - - rcsm.uBearerDataLen = sms.bearerData.size(); - digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); - for (int i = 0; i < digitLimit; i++) { - rcsm.aBearerData[i] = sms.bearerData[i]; - } -} - -Return<void> RadioImpl_1_5::sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms) { -#if VDBG - RLOGD("sendCdmaSms: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS); - if (pRI == NULL) { - return Void(); - } - - RIL_CDMA_SMS_Message rcsm = {}; - constructCdmaSms(rcsm, sms); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) { -#if VDBG - RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE); - if (pRI == NULL) { - return Void(); - } - - RIL_CDMA_SMS_Ack rcsa = {}; - - rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) smsAck.errorClass; - rcsa.uSMSCauseCode = smsAck.smsCauseCode; - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::getGsmBroadcastConfig(int32_t serial) { -#if VDBG - RLOGD("getGsmBroadcastConfig: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG); - return Void(); -} - -Return<void> RadioImpl_1_5::setGsmBroadcastConfig(int32_t serial, - const hidl_vec<GsmBroadcastSmsConfigInfo>& - configInfo) { -#if VDBG - RLOGD("setGsmBroadcastConfig: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG); - if (pRI == NULL) { - return Void(); - } - - int num = configInfo.size(); - RIL_GSM_BroadcastSmsConfigInfo gsmBci[num]; - RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num]; - - for (int i = 0 ; i < num ; i++ ) { - gsmBciPtrs[i] = &gsmBci[i]; - gsmBci[i].fromServiceId = configInfo[i].fromServiceId; - gsmBci[i].toServiceId = configInfo[i].toServiceId; - gsmBci[i].fromCodeScheme = configInfo[i].fromCodeScheme; - gsmBci[i].toCodeScheme = configInfo[i].toCodeScheme; - gsmBci[i].selected = BOOL_TO_INT(configInfo[i].selected); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs, - num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::setGsmBroadcastActivation(int32_t serial, bool activate) { -#if VDBG - RLOGD("setGsmBroadcastActivation: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, - 1, BOOL_TO_INT(!activate)); - return Void(); -} - -Return<void> RadioImpl_1_5::getCdmaBroadcastConfig(int32_t serial) { -#if VDBG - RLOGD("getCdmaBroadcastConfig: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG); - return Void(); -} - -Return<void> RadioImpl_1_5::setCdmaBroadcastConfig(int32_t serial, - const hidl_vec<CdmaBroadcastSmsConfigInfo>& - configInfo) { -#if VDBG - RLOGD("setCdmaBroadcastConfig: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG); - if (pRI == NULL) { - return Void(); - } - - int num = configInfo.size(); - RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num]; - RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num]; - - for (int i = 0 ; i < num ; i++ ) { - cdmaBciPtrs[i] = &cdmaBci[i]; - cdmaBci[i].service_category = configInfo[i].serviceCategory; - cdmaBci[i].language = configInfo[i].language; - cdmaBci[i].selected = BOOL_TO_INT(configInfo[i].selected); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs, - num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::setCdmaBroadcastActivation(int32_t serial, bool activate) { -#if VDBG - RLOGD("setCdmaBroadcastActivation: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, - 1, BOOL_TO_INT(!activate)); - return Void(); -} - -Return<void> RadioImpl_1_5::getCDMASubscription(int32_t serial) { -#if VDBG - RLOGD("getCDMASubscription: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION); - return Void(); -} - -Return<void> RadioImpl_1_5::writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms) { -#if VDBG - RLOGD("writeSmsToRuim: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM); - if (pRI == NULL) { - return Void(); - } - - RIL_CDMA_SMS_WriteArgs rcsw = {}; - rcsw.status = (int) cdmaSms.status; - constructCdmaSms(rcsw.message, cdmaSms.message); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::deleteSmsOnRuim(int32_t serial, int32_t index) { -#if VDBG - RLOGD("deleteSmsOnRuim: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, 1, index); - return Void(); -} - -Return<void> RadioImpl_1_5::getDeviceIdentity(int32_t serial) { -#if VDBG - RLOGD("getDeviceIdentity: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY); - return Void(); -} - -Return<void> RadioImpl_1_5::exitEmergencyCallbackMode(int32_t serial) { -#if VDBG - RLOGD("exitEmergencyCallbackMode: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE); - return Void(); -} - -Return<void> RadioImpl_1_5::getSmscAddress(int32_t serial) { -#if VDBG - RLOGD("getSmscAddress: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS); - return Void(); -} - -Return<void> RadioImpl_1_5::setSmscAddress(int32_t serial, const hidl_string& smsc) { -#if VDBG - RLOGD("setSmscAddress: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_SET_SMSC_ADDRESS, - smsc.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::reportSmsMemoryStatus(int32_t serial, bool available) { -#if VDBG - RLOGD("reportSmsMemoryStatus: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, 1, - BOOL_TO_INT(available)); - return Void(); -} - -Return<void> RadioImpl_1_5::reportStkServiceIsRunning(int32_t serial) { -#if VDBG - RLOGD("reportStkServiceIsRunning: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING); - return Void(); -} - -Return<void> RadioImpl_1_5::getCdmaSubscriptionSource(int32_t serial) { -#if VDBG - RLOGD("getCdmaSubscriptionSource: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE); - return Void(); -} - -Return<void> RadioImpl_1_5::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) { -#if VDBG - RLOGD("requestIsimAuthentication: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_ISIM_AUTHENTICATION, - challenge.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success, - const hidl_string& ackPdu) { -#if VDBG - RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, false, - 2, success ? "1" : "0", ackPdu.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) { -#if VDBG - RLOGD("sendEnvelopeWithStatus: serial %d", serial); -#endif - dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, - contents.c_str()); - return Void(); -} - -Return<void> RadioImpl_1_5::getVoiceRadioTechnology(int32_t serial) { -#if VDBG - RLOGD("getVoiceRadioTechnology: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH); - return Void(); -} - -Return<void> RadioImpl_1_5::getCellInfoList(int32_t serial) { -#if VDBG - RLOGD("getCellInfoList: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CELL_INFO_LIST); - return Void(); -} - -Return<void> RadioImpl_1_5::setCellInfoListRate(int32_t serial, int32_t rate) { -#if VDBG - RLOGD("setCellInfoListRate: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, 1, rate); - return Void(); -} - -Return<void> RadioImpl_1_5::setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, - bool modemCognitive, bool isRoaming) { -#if VDBG - RLOGD("setInitialAttachApn: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_INITIAL_ATTACH_APN); - if (pRI == NULL) { - return Void(); - } - - if (s_vendorFunctions->version <= 14) { - RIL_InitialAttachApn iaa = {}; - - if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) { - return Void(); - } - - const hidl_string &protocol = - (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); - - if (!copyHidlStringToRil(&iaa.protocol, protocol, pRI)) { - memsetAndFreeStrings(1, iaa.apn); - return Void(); - } - iaa.authtype = (int) dataProfileInfo.authType; - if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { - memsetAndFreeStrings(2, iaa.apn, iaa.protocol); - return Void(); - } - if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { - memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.username); - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); - - memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.username, iaa.password); - } else { - RIL_InitialAttachApn_v15 iaa = {}; - - if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) { - return Void(); - } - - if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) { - memsetAndFreeStrings(1, iaa.apn); - return Void(); - } - if (!copyHidlStringToRil(&iaa.roamingProtocol, dataProfileInfo.roamingProtocol, pRI)) { - memsetAndFreeStrings(2, iaa.apn, iaa.protocol); - return Void(); - } - iaa.authtype = (int) dataProfileInfo.authType; - if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { - memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.roamingProtocol); - return Void(); - } - if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { - memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username); - return Void(); - } - iaa.supportedTypesBitmask = dataProfileInfo.supportedApnTypesBitmap; - iaa.bearerBitmask = dataProfileInfo.bearerBitmap; - iaa.modemCognitive = BOOL_TO_INT(modemCognitive); - iaa.mtu = dataProfileInfo.mtu; - - if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, iaa.mvnoType)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, - iaa.password); - return Void(); - } - - if (!copyHidlStringToRil(&iaa.mvnoMatchData, dataProfileInfo.mvnoMatchData, pRI)) { - memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, - iaa.password); - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); - - memsetAndFreeStrings(6, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, - iaa.password, iaa.mvnoMatchData); - } - - return Void(); -} - -Return<void> RadioImpl_1_5::getImsRegistrationState(int32_t serial) { -#if VDBG - RLOGD("getImsRegistrationState: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_IMS_REGISTRATION_STATE); - return Void(); -} - -bool dispatchImsGsmSms(const ImsSmsMessage& message, RequestInfo *pRI) { - RIL_IMS_SMS_Message rism = {}; - char **pStrings; - int countStrings = 2; - int dataLen = sizeof(char *) * countStrings; - - rism.tech = RADIO_TECH_3GPP; - rism.retry = BOOL_TO_INT(message.retry); - rism.messageRef = message.messageRef; - - if (message.gsmMessage.size() != 1) { - RLOGE("dispatchImsGsmSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return false; - } - - pStrings = (char **)calloc(countStrings, sizeof(char *)); - if (pStrings == NULL) { - RLOGE("dispatchImsGsmSms: Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return false; - } - - if (!copyHidlStringToRil(&pStrings[0], message.gsmMessage[0].smscPdu, pRI)) { -#ifdef MEMSET_FREED - memset(pStrings, 0, dataLen); -#endif - free(pStrings); - return false; - } - - if (!copyHidlStringToRil(&pStrings[1], message.gsmMessage[0].pdu, pRI)) { - memsetAndFreeStrings(1, pStrings[0]); -#ifdef MEMSET_FREED - memset(pStrings, 0, dataLen); -#endif - free(pStrings); - return false; - } - - rism.message.gsmMessage = pStrings; - CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) + - sizeof(uint8_t) + sizeof(int32_t) + dataLen, pRI, pRI->socket_id); - - for (int i = 0 ; i < countStrings ; i++) { - memsetAndFreeStrings(1, pStrings[i]); - } - -#ifdef MEMSET_FREED - memset(pStrings, 0, dataLen); -#endif - free(pStrings); - - return true; -} - -struct ImsCdmaSms { - RIL_IMS_SMS_Message imsSms; - RIL_CDMA_SMS_Message cdmaSms; -}; - -bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) { - ImsCdmaSms temp = {}; - - if (message.cdmaMessage.size() != 1) { - RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return false; - } - - temp.imsSms.tech = RADIO_TECH_3GPP2; - temp.imsSms.retry = BOOL_TO_INT(message.retry); - temp.imsSms.messageRef = message.messageRef; - temp.imsSms.message.cdmaMessage = &temp.cdmaSms; - - constructCdmaSms(temp.cdmaSms, message.cdmaMessage[0]); - - // Vendor code expects payload length to include actual msg payload - // (sizeof(RIL_CDMA_SMS_Message)) instead of (RIL_CDMA_SMS_Message *) + size of other fields in - // RIL_IMS_SMS_Message - int payloadLen = sizeof(RIL_RadioTechnologyFamily) + sizeof(uint8_t) + sizeof(int32_t) - + sizeof(RIL_CDMA_SMS_Message); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &temp.imsSms, payloadLen, pRI, pRI->socket_id); - - return true; -} - -Return<void> RadioImpl_1_5::sendImsSms(int32_t serial, const ImsSmsMessage& message) { -#if VDBG - RLOGD("sendImsSms: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_IMS_SEND_SMS); - if (pRI == NULL) { - return Void(); - } - - RIL_RadioTechnologyFamily format = (RIL_RadioTechnologyFamily) message.tech; - - if (RADIO_TECH_3GPP == format) { - dispatchImsGsmSms(message, pRI); - } else if (RADIO_TECH_3GPP2 == format) { - dispatchImsCdmaSms(message, pRI); - } else { - RLOGE("sendImsSms: Invalid radio tech %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - } - return Void(); -} - -Return<void> RadioImpl_1_5::iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message) { -#if VDBG - RLOGD("iccTransmitApduBasicChannel: serial %d", serial); -#endif - dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, message); - return Void(); -} - -Return<void> RadioImpl_1_5::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) { -#if VDBG - RLOGD("iccOpenLogicalChannel: serial %d", serial); -#endif - if (s_vendorFunctions->version < 15) { - dispatchString(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL, aid.c_str()); - } else { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL); - if (pRI == NULL) { - return Void(); - } - - RIL_OpenChannelParams params = {}; - - params.p2 = p2; - - if (!copyHidlStringToRil(¶ms.aidPtr, aid, pRI)) { - return Void(); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, ¶ms, sizeof(params), pRI, mSlotId); - - memsetAndFreeStrings(1, params.aidPtr); - } - return Void(); -} - -Return<void> RadioImpl_1_5::iccCloseLogicalChannel(int32_t serial, int32_t channelId) { -#if VDBG - RLOGD("iccCloseLogicalChannel: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SIM_CLOSE_CHANNEL, 1, channelId); - return Void(); -} - -Return<void> RadioImpl_1_5::iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message) { -#if VDBG - RLOGD("iccTransmitApduLogicalChannel: serial %d", serial); -#endif - dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, message); - return Void(); -} - -Return<void> RadioImpl_1_5::nvReadItem(int32_t serial, NvItem itemId) { -#if VDBG - RLOGD("nvReadItem: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_READ_ITEM); - if (pRI == NULL) { - return Void(); - } - - RIL_NV_ReadItem nvri = {}; - nvri.itemID = (RIL_NV_Item) itemId; - - CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::nvWriteItem(int32_t serial, const NvWriteItem& item) { -#if VDBG - RLOGD("nvWriteItem: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_WRITE_ITEM); - if (pRI == NULL) { - return Void(); - } - - RIL_NV_WriteItem nvwi = {}; - - nvwi.itemID = (RIL_NV_Item) item.itemId; - - if (!copyHidlStringToRil(&nvwi.value, item.value, pRI)) { - return Void(); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, mSlotId); - - memsetAndFreeStrings(1, nvwi.value); - return Void(); -} - -Return<void> RadioImpl_1_5::nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) { -#if VDBG - RLOGD("nvWriteCdmaPrl: serial %d", serial); -#endif - dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl); - return Void(); -} - -Return<void> RadioImpl_1_5::nvResetConfig(int32_t serial, ResetNvType resetType) { - int rilResetType = -1; -#if VDBG - RLOGD("nvResetConfig: serial %d", serial); -#endif - /* Convert ResetNvType to RIL.h values - * RIL_REQUEST_NV_RESET_CONFIG - * 1 - reload all NV items - * 2 - erase NV reset (SCRTN) - * 3 - factory reset (RTN) - */ - switch(resetType) { - case ResetNvType::RELOAD: - rilResetType = 1; - break; - case ResetNvType::ERASE: - rilResetType = 2; - break; - case ResetNvType::FACTORY_RESET: - rilResetType = 3; - break; - } - dispatchInts(serial, mSlotId, RIL_REQUEST_NV_RESET_CONFIG, 1, rilResetType); - return Void(); -} - -Return<void> RadioImpl_1_5::setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub) { -#if VDBG - RLOGD("setUiccSubscription: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_UICC_SUBSCRIPTION); - if (pRI == NULL) { - return Void(); - } - - RIL_SelectUiccSub rilUiccSub = {}; - - rilUiccSub.slot = uiccSub.slot; - rilUiccSub.app_index = uiccSub.appIndex; - rilUiccSub.sub_type = (RIL_SubscriptionType) uiccSub.subType; - rilUiccSub.act_status = (RIL_UiccSubActStatus) uiccSub.actStatus; - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rilUiccSub, sizeof(rilUiccSub), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::setDataAllowed(int32_t serial, bool allow) { -#if VDBG - RLOGD("setDataAllowed: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_ALLOW_DATA, 1, BOOL_TO_INT(allow)); - return Void(); -} - -Return<void> RadioImpl_1_5::getHardwareConfig(int32_t serial) { -#if VDBG - RLOGD("getHardwareConfig: serial %d", serial); -#endif - RLOGD("getHardwareConfig: serial %d, mSlotId = %d", serial, mSlotId); - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG); - return Void(); -} - -Return<void> RadioImpl_1_5::requestIccSimAuthentication(int32_t serial, int32_t authContext, - const hidl_string& authData, const hidl_string& aid) { -#if VDBG - RLOGD("requestIccSimAuthentication: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_AUTHENTICATION); - if (pRI == NULL) { - return Void(); - } - - RIL_SimAuthentication pf = {}; - - pf.authContext = authContext; - - if (!copyHidlStringToRil(&pf.authData, authData, pRI)) { - return Void(); - } - - if (!copyHidlStringToRil(&pf.aid, aid, pRI)) { - memsetAndFreeStrings(1, pf.authData); - return Void(); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, mSlotId); - - memsetAndFreeStrings(2, pf.authData, pf.aid); - return Void(); -} - -/** - * @param numProfiles number of data profile - * @param dataProfiles the pointer to the actual data profiles. The acceptable type is - RIL_DataProfileInfo or RIL_DataProfileInfo_v15. - * @param dataProfilePtrs the pointer to the pointers that point to each data profile structure - * @param numfields number of string-type member in the data profile structure - * @param ... the variadic parameters are pointers to each string-type member - **/ -template <typename T> -void freeSetDataProfileData(int numProfiles, T *dataProfiles, T **dataProfilePtrs, - int numfields, ...) { - va_list args; - va_start(args, numfields); - - // Iterate through each string-type field that need to be free. - for (int i = 0; i < numfields; i++) { - // Iterate through each data profile and free that specific string-type field. - // The type 'char *T::*' is a type of pointer to a 'char *' member inside T structure. - char *T::*ptr = va_arg(args, char *T::*); - for (int j = 0; j < numProfiles; j++) { - memsetAndFreeStrings(1, dataProfiles[j].*ptr); - } - } - - va_end(args); - -#ifdef MEMSET_FREED - memset(dataProfiles, 0, numProfiles * sizeof(T)); - memset(dataProfilePtrs, 0, numProfiles * sizeof(T *)); -#endif - free(dataProfiles); - free(dataProfilePtrs); -} - -Return<void> RadioImpl_1_5::setDataProfile(int32_t serial, const hidl_vec<DataProfileInfo>& profiles, - bool isRoaming) { -#if VDBG - RLOGD("setDataProfile: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_DATA_PROFILE); - if (pRI == NULL) { - return Void(); - } - - size_t num = profiles.size(); - bool success = false; - - if (s_vendorFunctions->version <= 14) { - - RIL_DataProfileInfo *dataProfiles = - (RIL_DataProfileInfo *) calloc(num, sizeof(RIL_DataProfileInfo)); - - if (dataProfiles == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return Void(); - } - - RIL_DataProfileInfo **dataProfilePtrs = - (RIL_DataProfileInfo **) calloc(num, sizeof(RIL_DataProfileInfo *)); - if (dataProfilePtrs == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - free(dataProfiles); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return Void(); - } - - for (size_t i = 0; i < num; i++) { - dataProfilePtrs[i] = &dataProfiles[i]; - - success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true); - - const hidl_string &protocol = - (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol); - - if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI, true)) { - success = false; - } - - if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI, - true)) { - success = false; - } - if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, - pRI, true)) { - success = false; - } - - if (!success) { - freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, - &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, - &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); - return Void(); - } - - dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; - dataProfiles[i].authType = (int) profiles[i].authType; - dataProfiles[i].type = (int) profiles[i].type; - dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; - dataProfiles[i].maxConns = profiles[i].maxConns; - dataProfiles[i].waitTime = profiles[i].waitTime; - dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); - } - - CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, - num * sizeof(RIL_DataProfileInfo *), pRI, mSlotId); - - freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, - &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, - &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); - } else { - RIL_DataProfileInfo_v15 *dataProfiles = - (RIL_DataProfileInfo_v15 *) calloc(num, sizeof(RIL_DataProfileInfo_v15)); - - if (dataProfiles == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return Void(); - } - - RIL_DataProfileInfo_v15 **dataProfilePtrs = - (RIL_DataProfileInfo_v15 **) calloc(num, sizeof(RIL_DataProfileInfo_v15 *)); - if (dataProfilePtrs == NULL) { - RLOGE("Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - free(dataProfiles); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return Void(); - } - - for (size_t i = 0; i < num; i++) { - dataProfilePtrs[i] = &dataProfiles[i]; - - success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true); - if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol, - pRI)) { - success = false; - } - if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol, - profiles[i].roamingProtocol, pRI, true)) { - success = false; - } - if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI, - true)) { - success = false; - } - if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, - pRI, true)) { - success = false; - } - if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData, - profiles[i].mvnoMatchData, pRI, true)) { - success = false; - } - - if (success && !convertMvnoTypeToString(profiles[i].mvnoType, - dataProfiles[i].mvnoType)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - success = false; - } - - if (!success) { - freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, - &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, - &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, - &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); - return Void(); - } - - dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; - dataProfiles[i].authType = (int) profiles[i].authType; - dataProfiles[i].type = (int) profiles[i].type; - dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; - dataProfiles[i].maxConns = profiles[i].maxConns; - dataProfiles[i].waitTime = profiles[i].waitTime; - dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); - dataProfiles[i].supportedTypesBitmask = profiles[i].supportedApnTypesBitmap; - dataProfiles[i].bearerBitmask = profiles[i].bearerBitmap; - dataProfiles[i].mtu = profiles[i].mtu; - } - - CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, - num * sizeof(RIL_DataProfileInfo_v15 *), pRI, mSlotId); - - freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, - &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, - &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, - &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); - } - - return Void(); -} - -Return<void> RadioImpl_1_5::requestShutdown(int32_t serial) { -#if VDBG - RLOGD("requestShutdown: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN); - return Void(); -} - -Return<void> RadioImpl_1_5::getRadioCapability(int32_t serial) { -#if VDBG - RLOGD("getRadioCapability: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY); - return Void(); -} - -Return<void> RadioImpl_1_5::setRadioCapability(int32_t serial, const RadioCapability& rc) { -#if VDBG - RLOGD("setRadioCapability: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_RADIO_CAPABILITY); - if (pRI == NULL) { - return Void(); - } - - RIL_RadioCapability rilRc = {}; - - // TODO : set rilRc.version using HIDL version ? - rilRc.session = rc.session; - rilRc.phase = (int) rc.phase; - rilRc.rat = (int) rc.raf; - rilRc.status = (int) rc.status; - strlcpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), sizeof(rilRc.logicalModemUuid)); - - CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId); - - return Void(); -} - -Return<void> RadioImpl_1_5::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) { -#if VDBG - RLOGD("startLceService: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_START_LCE, 2, reportInterval, - BOOL_TO_INT(pullMode)); - return Void(); -} - -Return<void> RadioImpl_1_5::stopLceService(int32_t serial) { -#if VDBG - RLOGD("stopLceService: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE); - return Void(); -} - -Return<void> RadioImpl_1_5::pullLceData(int32_t serial) { -#if VDBG - RLOGD("pullLceData: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA); - return Void(); -} - -Return<void> RadioImpl_1_5::getModemActivityInfo(int32_t serial) { -#if VDBG - RLOGD("getModemActivityInfo: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO); - return Void(); -} - -int prepareCarrierRestrictions(RIL_CarrierRestrictions &request, bool allAllowed, - const hidl_vec<Carrier>& allowedList, - const hidl_vec<Carrier>& excludedList, - RequestInfo *pRI) { - RIL_Carrier *allowedCarriers = NULL; - RIL_Carrier *excludedCarriers = NULL; - - request.len_allowed_carriers = allowedList.size(); - allowedCarriers = (RIL_Carrier *)calloc(request.len_allowed_carriers, sizeof(RIL_Carrier)); - if (allowedCarriers == NULL) { - RLOGE("prepareCarrierRestrictions: Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); - return -1; - } - request.allowed_carriers = allowedCarriers; - - request.len_excluded_carriers = excludedList.size(); - excludedCarriers = (RIL_Carrier *)calloc(request.len_excluded_carriers, sizeof(RIL_Carrier)); - if (excludedCarriers == NULL) { - RLOGE("prepareCarrierRestrictions: Memory allocation failed for request %s", - requestToString(pRI->pCI->requestNumber)); - sendErrorResponse(pRI, RIL_E_NO_MEMORY); -#ifdef MEMSET_FREED - memset(allowedCarriers, 0, request.len_allowed_carriers * sizeof(RIL_Carrier)); -#endif - free(allowedCarriers); - return -1; - } - request.excluded_carriers = excludedCarriers; - - for (int i = 0; i < request.len_allowed_carriers; i++) { - allowedCarriers[i].mcc = allowedList[i].mcc.c_str(); - allowedCarriers[i].mnc = allowedList[i].mnc.c_str(); - allowedCarriers[i].match_type = (RIL_CarrierMatchType) allowedList[i].matchType; - allowedCarriers[i].match_data = allowedList[i].matchData.c_str(); - } - - for (int i = 0; i < request.len_excluded_carriers; i++) { - excludedCarriers[i].mcc = excludedList[i].mcc.c_str(); - excludedCarriers[i].mnc = excludedList[i].mnc.c_str(); - excludedCarriers[i].match_type = - (RIL_CarrierMatchType) excludedList[i].matchType; - excludedCarriers[i].match_data = excludedList[i].matchData.c_str(); - } - - return 0; -} - -void freeCarrierRestrictions(RIL_CarrierRestrictions &request) { - if (request.allowed_carriers != NULL) { -#ifdef MEMSET_FREED - memset(request.allowed_carriers, 0, request.len_allowed_carriers * sizeof(RIL_Carrier)); -#endif - free(request.allowed_carriers); - } - if (request.excluded_carriers != NULL) { -#ifdef MEMSET_FREED - memset(request.excluded_carriers, 0, request.len_excluded_carriers * sizeof(RIL_Carrier)); -#endif - free(request.excluded_carriers); - } -} - - -Return<void> RadioImpl_1_5::setAllowedCarriers(int32_t serial, bool allAllowed, - const CarrierRestrictions& carriers) { -#if VDBG - RLOGD("setAllowedCarriers: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_CARRIER_RESTRICTIONS); - if (pRI == NULL) { - return Void(); - } - - RIL_CarrierRestrictions cr = {}; - if (prepareCarrierRestrictions(cr, allAllowed, carriers.allowedCarriers, - carriers.excludedCarriers, pRI) < 0) { - return Void(); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &cr, sizeof(RIL_CarrierRestrictions), pRI, mSlotId); - - freeCarrierRestrictions(cr); - - return Void(); -} - -Return<void> RadioImpl_1_5::setAllowedCarriers_1_4(int32_t serial, - const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& carriers, - ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy) { -#if VDBG - RLOGD("setAllowedCarriers_1_4: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4); - if (pRI == NULL) { - return Void(); - } - - // Prepare legacy structure (defined in IRadio 1.0) to re-use existing code. - RIL_CarrierRestrictions cr = {}; - if (prepareCarrierRestrictions(cr, false, carriers.allowedCarriers, - carriers.excludedCarriers, pRI) < 0) { - return Void(); - } - // Copy the legacy structure into the new structure (defined in IRadio 1.4) - RIL_CarrierRestrictionsWithPriority crExt = {}; - crExt.len_allowed_carriers = cr.len_allowed_carriers; - crExt.allowed_carriers = cr.allowed_carriers; - crExt.len_excluded_carriers = cr.len_excluded_carriers; - crExt.excluded_carriers = cr.excluded_carriers; - crExt.allowedCarriersPrioritized = BOOL_TO_INT(carriers.allowedCarriersPrioritized); - crExt.multiSimPolicy = (RIL_SimLockMultiSimPolicy)multiSimPolicy; - - CALL_ONREQUEST(pRI->pCI->requestNumber, &crExt, - sizeof(RIL_CarrierRestrictionsWithPriority), pRI, mSlotId); - - freeCarrierRestrictions(cr); - - return Void(); -} - -Return<void> RadioImpl_1_5::getAllowedCarriers(int32_t serial) { -#if VDBG - RLOGD("getAllowedCarriers: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS); - return Void(); -} - -Return<void> RadioImpl_1_5::getAllowedCarriers_1_4(int32_t serial) { -#if VDBG - RLOGD("getAllowedCarriers_1_4: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4); - return Void(); -} - -Return<void> RadioImpl_1_5::sendDeviceState(int32_t serial, DeviceStateType deviceStateType, - bool state) { -#if VDBG - RLOGD("sendDeviceState: serial %d", serial); -#endif - if (s_vendorFunctions->version < 15) { - if (deviceStateType == DeviceStateType::LOW_DATA_EXPECTED) { - RLOGD("sendDeviceState: calling screen state %d", BOOL_TO_INT(!state)); - dispatchInts(serial, mSlotId, RIL_REQUEST_SCREEN_STATE, 1, BOOL_TO_INT(!state)); - } else { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SEND_DEVICE_STATE); - sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); - } - return Void(); - } - dispatchInts(serial, mSlotId, RIL_REQUEST_SEND_DEVICE_STATE, 2, (int) deviceStateType, - BOOL_TO_INT(state)); - return Void(); -} - -Return<void> RadioImpl_1_5::setIndicationFilter(int32_t serial, int32_t indicationFilter) { -#if VDBG - RLOGD("setIndicationFilter: serial %d", serial); -#endif - if (s_vendorFunctions->version < 15) { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER); - sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); - return Void(); - } - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, 1, indicationFilter); - return Void(); -} - -Return<void> RadioImpl_1_5::setSimCardPower(int32_t serial, bool powerUp) { -#if VDBG - RLOGD("setSimCardPower: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, BOOL_TO_INT(powerUp)); - return Void(); -} - -Return<void> RadioImpl_1_5::setSimCardPower_1_1(int32_t serial, const V1_1::CardPowerState state) { -#if VDBG - RLOGD("setSimCardPower_1_1: serial %d state %d", serial, state); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, state); - return Void(); -} - -Return<void> RadioImpl_1_5::setCarrierInfoForImsiEncryption(int32_t serial, - const V1_1::ImsiEncryptionInfo& data) { -#if VDBG - RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial); -#endif - RequestInfo *pRI = android::addRequestToList( - serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION); - if (pRI == NULL) { - return Void(); - } - - RIL_CarrierInfoForImsiEncryption imsiEncryption = {}; - - if (!copyHidlStringToRil(&imsiEncryption.mnc, data.mnc, pRI)) { - return Void(); - } - if (!copyHidlStringToRil(&imsiEncryption.mcc, data.mcc, pRI)) { - memsetAndFreeStrings(1, imsiEncryption.mnc); - return Void(); - } - if (!copyHidlStringToRil(&imsiEncryption.keyIdentifier, data.keyIdentifier, pRI)) { - memsetAndFreeStrings(2, imsiEncryption.mnc, imsiEncryption.mcc); - return Void(); - } - imsiEncryption.carrierKeyLength = data.carrierKey.size(); - imsiEncryption.carrierKey = new uint8_t[imsiEncryption.carrierKeyLength]; - memcpy(imsiEncryption.carrierKey, data.carrierKey.data(), imsiEncryption.carrierKeyLength); - imsiEncryption.expirationTime = data.expirationTime; - CALL_ONREQUEST(pRI->pCI->requestNumber, &imsiEncryption, - sizeof(RIL_CarrierInfoForImsiEncryption), pRI, mSlotId); - delete(imsiEncryption.carrierKey); - return Void(); -} - -Return<void> RadioImpl_1_5::startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_KEEPALIVE); - if (pRI == NULL) { - return Void(); - } - - RIL_KeepaliveRequest kaReq = {}; - - kaReq.type = static_cast<RIL_KeepaliveType>(keepalive.type); - switch(kaReq.type) { - case NATT_IPV4: - if (keepalive.sourceAddress.size() != 4 || - keepalive.destinationAddress.size() != 4) { - RLOGE("Invalid address for keepalive!"); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - break; - case NATT_IPV6: - if (keepalive.sourceAddress.size() != 16 || - keepalive.destinationAddress.size() != 16) { - RLOGE("Invalid address for keepalive!"); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - break; - default: - RLOGE("Unknown packet keepalive type!"); - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return Void(); - } - - ::memcpy(kaReq.sourceAddress, keepalive.sourceAddress.data(), keepalive.sourceAddress.size()); - kaReq.sourcePort = keepalive.sourcePort; - - ::memcpy(kaReq.destinationAddress, - keepalive.destinationAddress.data(), keepalive.destinationAddress.size()); - kaReq.destinationPort = keepalive.destinationPort; - - kaReq.maxKeepaliveIntervalMillis = keepalive.maxKeepaliveIntervalMillis; - kaReq.cid = keepalive.cid; // This is the context ID of the data call - - CALL_ONREQUEST(pRI->pCI->requestNumber, &kaReq, sizeof(RIL_KeepaliveRequest), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::stopKeepalive(int32_t serial, int32_t sessionHandle) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_STOP_KEEPALIVE); - if (pRI == NULL) { - return Void(); - } - - CALL_ONREQUEST(pRI->pCI->requestNumber, &sessionHandle, sizeof(uint32_t), pRI, mSlotId); - return Void(); -} - -Return<void> RadioImpl_1_5::responseAcknowledgement() { - android::releaseWakeLock(); - return Void(); -} - -int prepareNetworkScanRequest_1_2(RIL_NetworkScanRequest &scan_request, - const ::android::hardware::radio::V1_2::NetworkScanRequest& request, - RequestInfo *pRI) { - - scan_request.type = (RIL_ScanType) request.type; - scan_request.interval = request.interval; - scan_request.specifiers_length = request.specifiers.size(); - - int intervalLow = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MIN); - int intervalHigh = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MAX); - int maxSearchTimeLow = - static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MIN); - int maxSearchTimeHigh = - static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MAX); - int incrementalResultsPeriodicityRangeLow = - static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MIN); - int incrementalResultsPeriodicityRangeHigh = - static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MAX); - uint maxSpecifierSize = - static_cast<uint>(::android::hardware::radio::V1_2::RadioConst - ::RADIO_ACCESS_SPECIFIER_MAX_SIZE); - - if (request.interval < intervalLow || request.interval > intervalHigh) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - // If defined, must fall in correct range. - if (request.maxSearchTime != 0 - && (request.maxSearchTime < maxSearchTimeLow - || request.maxSearchTime > maxSearchTimeHigh)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - if (request.maxSearchTime != 0 - && (request.incrementalResultsPeriodicity < incrementalResultsPeriodicityRangeLow - || request.incrementalResultsPeriodicity > incrementalResultsPeriodicityRangeHigh - || request.incrementalResultsPeriodicity > request.maxSearchTime)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - if (request.specifiers.size() == 0 || request.specifiers.size() > maxSpecifierSize) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - - for (size_t i = 0; i < request.specifiers.size(); ++i) { - if (request.specifiers[i].geranBands.size() > MAX_BANDS || - request.specifiers[i].utranBands.size() > MAX_BANDS || - request.specifiers[i].eutranBands.size() > MAX_BANDS || - request.specifiers[i].channels.size() > MAX_CHANNELS) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - const V1_1::RadioAccessSpecifier& ras_from = - request.specifiers[i]; - RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i]; - - ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork; - ras_to.channels_length = ras_from.channels.size(); - - std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels); - const std::vector<uint32_t> * bands = nullptr; - switch (request.specifiers[i].radioAccessNetwork) { - case V1_1::RadioAccessNetworks::GERAN: - ras_to.bands_length = ras_from.geranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.geranBands; - break; - case V1_1::RadioAccessNetworks::UTRAN: - ras_to.bands_length = ras_from.utranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.utranBands; - break; - case V1_1::RadioAccessNetworks::EUTRAN: - ras_to.bands_length = ras_from.eutranBands.size(); - bands = (std::vector<uint32_t> *) &ras_from.eutranBands; - break; - default: - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - // safe to copy to geran_bands because it's a union member - for (size_t idx = 0; idx < ras_to.bands_length; ++idx) { - ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx]; - } - } - - return 0; -} - -int prepareNetworkScanRequest_1_5(RIL_NetworkScanRequest &scan_request, - const ::android::hardware::radio::V1_5::NetworkScanRequest& request, - RequestInfo *pRI) { - - scan_request.type = (RIL_ScanType) request.type; - scan_request.interval = request.interval; - scan_request.specifiers_length = request.specifiers.size(); - - int intervalLow = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MIN); - int intervalHigh = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MAX); - int maxSearchTimeLow = - static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MIN); - int maxSearchTimeHigh = - static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MAX); - int incrementalResultsPeriodicityRangeLow = - static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MIN); - int incrementalResultsPeriodicityRangeHigh = - static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MAX); - uint maxSpecifierSize = - static_cast<uint>(::android::hardware::radio::V1_2::RadioConst - ::RADIO_ACCESS_SPECIFIER_MAX_SIZE); - - if (request.interval < intervalLow || request.interval > intervalHigh) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - // If defined, must fall in correct range. - if (request.maxSearchTime != 0 - && (request.maxSearchTime < maxSearchTimeLow - || request.maxSearchTime > maxSearchTimeHigh)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - if (request.maxSearchTime != 0 - && (request.incrementalResultsPeriodicity < incrementalResultsPeriodicityRangeLow - || request.incrementalResultsPeriodicity > incrementalResultsPeriodicityRangeHigh - || request.incrementalResultsPeriodicity > request.maxSearchTime)) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - if (request.specifiers.size() == 0 || request.specifiers.size() > maxSpecifierSize) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - - for (size_t i = 0; i < request.specifiers.size(); ++i) { - if (request.specifiers[i].bands.geranBands().size() > MAX_BANDS || - request.specifiers[i].bands.utranBands().size() > MAX_BANDS || - request.specifiers[i].bands.eutranBands().size() > MAX_BANDS || - request.specifiers[i].bands.ngranBands().size() > MAX_BANDS || - request.specifiers[i].channels.size() > MAX_CHANNELS) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - const V1_5::RadioAccessSpecifier& ras_from = request.specifiers[i]; - RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i]; - - ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork; - ras_to.channels_length = ras_from.channels.size(); - - std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels); - const std::vector<uint32_t> * bands = nullptr; - switch (request.specifiers[i].radioAccessNetwork) { - case V1_5::RadioAccessNetworks::GERAN: - ras_to.bands_length = ras_from.bands.geranBands().size(); - bands = (std::vector<uint32_t> *) &ras_from.bands; - break; - case V1_5::RadioAccessNetworks::UTRAN: - ras_to.bands_length = ras_from.bands.utranBands().size(); - bands = (std::vector<uint32_t> *) &ras_from.bands; - break; - case V1_5::RadioAccessNetworks::EUTRAN: - ras_to.bands_length = ras_from.bands.eutranBands().size(); - bands = (std::vector<uint32_t> *) &ras_from.bands; - break; - case V1_5::RadioAccessNetworks::NGRAN: - ras_to.bands_length = ras_from.bands.ngranBands().size(); - bands = (std::vector<uint32_t> *) &ras_from.bands; - break; - default: - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - return -1; - } - // safe to copy to geran_bands because it's a union member - for (size_t idx = 0; idx < ras_to.bands_length; ++idx) { - ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx]; - } - } - - return 0; -} - -// Methods from ::android::hardware::radio::V1_2::IRadio follow. -Return<void> RadioImpl_1_5::startNetworkScan_1_2(int32_t serial, - const ::android::hardware::radio::V1_2::NetworkScanRequest& request) { -#if VDBG - RLOGD("startNetworkScan_1_2: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN); - if (pRI == NULL) { - return Void(); - } - - // TODO: implement checks for new fields. - // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and - // mccMncs, could add more validations using request2 here. - - RIL_NetworkScanRequest scan_request = {}; - - if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) { - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI, - mSlotId); - - return Void(); -} - -Return<void> RadioImpl_1_5::setIndicationFilter_1_2(int32_t /* serial */, - hidl_bitfield<::android::hardware::radio::V1_2::IndicationFilter> /* indicationFilter */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -Return<void> RadioImpl_1_5::setSignalStrengthReportingCriteria(int32_t /* serial */, - int32_t /* hysteresisMs */, int32_t /* hysteresisDb */, - const hidl_vec<int32_t>& /* thresholdsDbm */, - ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -Return<void> RadioImpl_1_5::setLinkCapacityReportingCriteria(int32_t /* serial */, - int32_t /* hysteresisMs */, int32_t /* hysteresisDlKbps */, int32_t /* hysteresisUlKbps */, - const hidl_vec<int32_t>& /* thresholdsDownlinkKbps */, - const hidl_vec<int32_t>& /* thresholdsUplinkKbps */, - ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -Return<void> RadioImpl_1_5::setupDataCall_1_2(int32_t /* serial */, - ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */, - const ::android::hardware::radio::V1_0::DataProfileInfo& /* dataProfileInfo */, - bool /* modemCognitive */, bool /* roamingAllowed */, bool /* isRoaming */, - ::android::hardware::radio::V1_2::DataRequestReason /* reason */, - const hidl_vec<hidl_string>& /* addresses */, const hidl_vec<hidl_string>& /* dnses */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -Return<void> RadioImpl_1_5::deactivateDataCall_1_2(int32_t /* serial */, int32_t /* cid */, - ::android::hardware::radio::V1_2::DataRequestReason /* reason */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -// Methods from ::android::hardware::radio::V1_3::IRadio follow. -Return<void> RadioImpl_1_5::setSystemSelectionChannels(int32_t serial, bool /* specifyChannels */, - const hidl_vec<::android::hardware::radio::V1_1::RadioAccessSpecifier>& /* specifiers */) { -#if VDBG - RLOGD("setSystemSelectionChannels: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS); - return Void(); -} - -Return<void> RadioImpl_1_5::enableModem(int32_t serial, bool /* on */) { -#if VDBG - RLOGE("enableModem: serial = %d, enable = %s", serial, on); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_ENABLE_MODEM); - return Void(); -} - -Return<void> RadioImpl_1_5::getModemStackStatus(int32_t serial) { -#if VDBG - RLOGD("getModemStackStatus: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MODEM_STACK_STATUS); - return Void(); -} - -const char * getProtocolString(const ::android::hardware::radio::V1_4::PdpProtocolType protocolVal) { - switch(protocolVal) { - case ::android::hardware::radio::V1_4::PdpProtocolType::IP: - return "IP"; - case ::android::hardware::radio::V1_4::PdpProtocolType::IPV6: - return "IPV6"; - case ::android::hardware::radio::V1_4::PdpProtocolType::IPV4V6: - return "IPV4V6"; - case ::android::hardware::radio::V1_4::PdpProtocolType::PPP: - return "PPP"; - case ::android::hardware::radio::V1_4::PdpProtocolType::NON_IP: - return "NON_IP"; - case ::android::hardware::radio::V1_4::PdpProtocolType::UNSTRUCTURED: - return "UNSTRUCTURED"; - default: - return "UNKNOWN"; - } -} - -// Methods from ::android::hardware::radio::V1_4::IRadio follow. -Return<void> RadioImpl_1_5::setupDataCall_1_4(int32_t serial , - ::android::hardware::radio::V1_4::AccessNetwork /* accessNetwork */, - const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo, - bool roamingAllowed, ::android::hardware::radio::V1_2::DataRequestReason /* reason */, - const hidl_vec<hidl_string>& /* addresses */, const hidl_vec<hidl_string>& /* dnses */) { - -#if VDBG - RLOGD("setupDataCall_1_4: serial %d", serial); -#endif - - char *mvnoTypeStr = NULL; - if (!convertMvnoTypeToString(MvnoType::IMSI, mvnoTypeStr)) { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SETUP_DATA_CALL); - if (pRI != NULL) { - sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); - } - return Void(); - } - dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15, - std::to_string((int) RadioTechnology::UNKNOWN + 2).c_str(), - std::to_string((int) dataProfileInfo.profileId).c_str(), - dataProfileInfo.apn.c_str(), - dataProfileInfo.user.c_str(), - dataProfileInfo.password.c_str(), - std::to_string((int) dataProfileInfo.authType).c_str(), - getProtocolString(dataProfileInfo.protocol), - getProtocolString(dataProfileInfo.roamingProtocol), - std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(), - std::to_string(dataProfileInfo.bearerBitmap).c_str(), - dataProfileInfo.persistent ? "1" : "0", - std::to_string(dataProfileInfo.mtu).c_str(), - mvnoTypeStr, - "302720x94", - roamingAllowed ? "1" : "0"); - return Void(); -} - -Return<void> RadioImpl_1_5::setInitialAttachApn_1_4(int32_t serial , - const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo) { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_INITIAL_ATTACH_APN); - if (pRI == NULL) { - return Void(); - } - - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, RESPONSE_SOLICITED, RIL_E_SUCCESS); - - if (radioService[mSlotId]->mRadioResponseV1_4 != NULL) { - Return<void> retStatus - = radioService[mSlotId]->mRadioResponseV1_4->setInitialAttachApnResponse(responseInfo); - radioService[mSlotId]->checkReturnStatus(retStatus); - } else if (radioService[mSlotId]->mRadioResponse != NULL) { - Return<void> retStatus - = radioService[mSlotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo); - radioService[mSlotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL", mSlotId); - } - - return Void(); -} - -Return<void> RadioImpl_1_5::setDataProfile_1_4(int32_t serial , - const hidl_vec<::android::hardware::radio::V1_4::DataProfileInfo>& /* profiles */) { - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, - RIL_REQUEST_SET_DATA_PROFILE); - if (pRI == NULL) { - return Void(); - } - - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, RESPONSE_SOLICITED, RIL_E_SUCCESS); - - if (radioService[mSlotId]->mRadioResponseV1_4 != NULL) { - Return<void> retStatus - = radioService[mSlotId]->mRadioResponseV1_4->setDataProfileResponse(responseInfo); - radioService[mSlotId]->checkReturnStatus(retStatus); - } else if (radioService[mSlotId]->mRadioResponse != NULL) { - Return<void> retStatus - = radioService[mSlotId]->mRadioResponse->setDataProfileResponse(responseInfo); - radioService[mSlotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", mSlotId); - } - - return Void(); -} - -Return<void> RadioImpl_1_5::emergencyDial(int32_t serial, - const ::android::hardware::radio::V1_0::Dial& dialInfo, - hidl_bitfield<android::hardware::radio::V1_4::EmergencyServiceCategory> /* categories */, - const hidl_vec<hidl_string>& /* urns */, - ::android::hardware::radio::V1_4::EmergencyCallRouting /* routing */, - bool /* fromEmergencyDialer */, bool /* isTesting */) { -#if VDBG - RLOGD("emergencyDial: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_EMERGENCY_DIAL); - if (pRI == NULL) { - return Void(); - } - RIL_Dial dial = {}; - RIL_UUS_Info uusInfo = {}; - int32_t sizeOfDial = sizeof(dial); - - if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) { - return Void(); - } - dial.clir = (int) dialInfo.clir; - - if (dialInfo.uusInfo.size() != 0) { - uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType; - uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs; - - if (dialInfo.uusInfo[0].uusData.size() == 0) { - uusInfo.uusData = NULL; - uusInfo.uusLength = 0; - } else { - if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) { - memsetAndFreeStrings(1, dial.address); - return Void(); - } - uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size(); - } - - dial.uusInfo = &uusInfo; - } - - CALL_ONREQUEST(RIL_REQUEST_EMERGENCY_DIAL, &dial, sizeOfDial, pRI, mSlotId); - - memsetAndFreeStrings(2, dial.address, uusInfo.uusData); - - return Void(); -} - -Return<void> RadioImpl_1_5::startNetworkScan_1_4(int32_t serial, - const ::android::hardware::radio::V1_2::NetworkScanRequest& request) { -#if VDBG - RLOGD("startNetworkScan_1_4: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN4); - if (pRI == NULL) { - return Void(); - } - - // TODO: implement checks for new fields. - // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and - // mccMncs, could add more validations using request2 here. - - RIL_NetworkScanRequest scan_request = {}; - - if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) { - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN4, &scan_request, sizeof(scan_request), pRI, - mSlotId); - - return Void(); -} - -Return<void> RadioImpl_1_5::getPreferredNetworkTypeBitmap(int32_t serial ) { -#if VDBG - RLOGD("getPreferredNetworkTypeBitmap: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP); - return Void(); -} - -Return<void> RadioImpl_1_5::setPreferredNetworkTypeBitmap( - int32_t serial, hidl_bitfield<RadioAccessFamily> networkTypeBitmap) { -#if VDBG - RLOGD("setPreferredNetworkTypeBitmap: serial %d", serial); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP, 1, networkTypeBitmap); - return Void(); -} - -Return<void> RadioImpl_1_5::getSignalStrength_1_4(int32_t serial) { -#if VDBG - RLOGD("getSignalStrength_1_4: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH); - return Void(); -} - -// Methods from ::android::hardware::radio::IRadio::V1_5 follow. -Return<void> RadioImpl_1_5::setSignalStrengthReportingCriteria_1_5(int32_t /* serial */, - const ::android::hardware::radio::V1_5::SignalThresholdInfo& /* signalThresholdInfo */, - const ::android::hardware::radio::V1_5::AccessNetwork /* accessNetwork */) { - // TODO implement -#if VDBG - RLOGE("[%04d]< %s", serial, "Method is not implemented"); -#endif - return Void(); -} - -Return<void> RadioImpl_1_5::enableUiccApplications(int32_t serial, bool enable) { -#if VDBG - RLOGD("enableUiccApplications: serial %d enable %d", serial, enable); -#endif - dispatchInts(serial, mSlotId, RIL_REQUEST_ENABLE_UICC_APPLICATIONS, 1, BOOL_TO_INT(enable)); - return Void(); -} - -Return<void> RadioImpl_1_5::areUiccApplicationsEnabled(int32_t serial) { -#if VDBG - RLOGD("areUiccApplicationsEnabled: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED); - return Void(); -} - -Return<void> RadioImpl_1_5::canToggleUiccApplicationsEnablement(int32_t serial) { -#if VDBG - RLOGD("canToggleUiccApplicationsEnablement: serial %d.", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_CAN_TOGGLE_UICC_APPLICATIONS_ENABLEMENT); - return Void(); -} - -Return<void> RadioImpl_1_5::setSystemSelectionChannels_1_5(int32_t serial, bool /* specifyChannels */, - const hidl_vec<::android::hardware::radio::V1_5::RadioAccessSpecifier>& /* specifiers */) { -#if VDBG - RLOGD("setSystemSelectionChannels_1_5: serial %d", serial); -#endif - dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS_1_5); - return Void(); -} - -Return<void> RadioImpl_1_5::startNetworkScan_1_5(int32_t serial, - const ::android::hardware::radio::V1_5::NetworkScanRequest& request) { -#if VDBG - RLOGD("startNetworkScan_1_5: serial %d", serial); -#endif - - RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN_1_5); - if (pRI == NULL) { - return Void(); - } - - // TODO: implement checks for new fields. - // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and - // mccMncs, could add more validations using request2 here. - - RIL_NetworkScanRequest scan_request = {}; - - if (prepareNetworkScanRequest_1_5(scan_request, request, pRI) < 0) { - return Void(); - } - - CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN_1_5, &scan_request, sizeof(scan_request), pRI, - mSlotId); - - return Void(); -} - -// OEM hook methods: -Return<void> OemHookImpl::setResponseFunctions( - const ::android::sp<IOemHookResponse>& oemHookResponseParam, - const ::android::sp<IOemHookIndication>& oemHookIndicationParam) { -#if VDBG - RLOGD("OemHookImpl::setResponseFunctions"); -#endif - - pthread_rwlock_t *radioServiceRwlockPtr = radio_1_5::getRadioServiceRwlock(mSlotId); - int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); - assert(ret == 0); - - mOemHookResponse = oemHookResponseParam; - mOemHookIndication = oemHookIndicationParam; - mCounterOemHook[mSlotId]++; - - ret = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(ret == 0); - - return Void(); -} - -Return<void> OemHookImpl::sendRequestRaw(int32_t serial, const hidl_vec<uint8_t>& data) { -#if VDBG - RLOGD("OemHookImpl::sendRequestRaw: serial %d", serial); -#endif - dispatchRaw(serial, mSlotId, RIL_REQUEST_OEM_HOOK_RAW, data); - return Void(); -} - -Return<void> OemHookImpl::sendRequestStrings(int32_t serial, - const hidl_vec<hidl_string>& data) { -#if VDBG - RLOGD("OemHookImpl::sendRequestStrings: serial %d", serial); -#endif - dispatchStrings(serial, mSlotId, RIL_REQUEST_OEM_HOOK_STRINGS, data); - return Void(); -} - -/*************************************************************************************************** - * RESPONSE FUNCTIONS - * Functions above are used for requests going from framework to vendor code. The ones below are - * responses for those requests coming back from the vendor code. - **************************************************************************************************/ - -void radio_1_5::acknowledgeRequest(int slotId, int serial) { - if (radioService[slotId]->mRadioResponse != NULL) { - Return<void> retStatus = radioService[slotId]->mRadioResponse->acknowledgeRequest(serial); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acknowledgeRequest: radioService[%d]->mRadioResponse == NULL", slotId); - } -} - -void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType, - RIL_Errno e) { - responseInfo.serial = serial; - switch (responseType) { - case RESPONSE_SOLICITED: - responseInfo.type = RadioResponseType::SOLICITED; - break; - case RESPONSE_SOLICITED_ACK_EXP: - responseInfo.type = RadioResponseType::SOLICITED_ACK_EXP; - break; - } - responseInfo.error = (RadioError) e; -} - -int responseIntOrEmpty(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, - void *response, size_t responseLen) { - populateResponseInfo(responseInfo, serial, responseType, e); - int ret = -1; - - if (response == NULL && responseLen == 0) { - // Earlier RILs did not send a response for some cases although the interface - // expected an integer as response. Do not return error if response is empty. Instead - // Return -1 in those cases to maintain backward compatibility. - } else if (response == NULL || responseLen != sizeof(int)) { - RLOGE("responseIntOrEmpty: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *p_int = (int *) response; - ret = p_int[0]; - } - return ret; -} - -int responseInt(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, - void *response, size_t responseLen) { - populateResponseInfo(responseInfo, serial, responseType, e); - int ret = -1; - - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("responseInt: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *p_int = (int *) response; - ret = p_int[0]; - } - return ret; -} - -int radio_1_5::getIccCardStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { - if (radioService[slotId]->mRadioResponseV1_4 != NULL - || radioService[slotId]->mRadioResponseV1_2 != NULL - || radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - CardStatus cardStatus = {CardState::ABSENT, PinState::UNKNOWN, -1, -1, -1, {}}; - RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response); - if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6) - || p_cur->gsm_umts_subscription_app_index >= p_cur->num_applications - || p_cur->cdma_subscription_app_index >= p_cur->num_applications - || p_cur->ims_subscription_app_index >= p_cur->num_applications) { - RLOGE("getIccCardStatusResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - cardStatus.cardState = (CardState) p_cur->card_state; - cardStatus.universalPinState = (PinState) p_cur->universal_pin_state; - cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index; - cardStatus.cdmaSubscriptionAppIndex = p_cur->cdma_subscription_app_index; - cardStatus.imsSubscriptionAppIndex = p_cur->ims_subscription_app_index; - - RIL_AppStatus *rilAppStatus = p_cur->applications; - cardStatus.applications.resize(p_cur->num_applications); - AppStatus *appStatus = cardStatus.applications.data(); -#if VDBG - RLOGD("getIccCardStatusResponse: num_applications %d", p_cur->num_applications); -#endif - for (int i = 0; i < p_cur->num_applications; i++) { - appStatus[i].appType = (AppType) rilAppStatus[i].app_type; - appStatus[i].appState = (AppState) rilAppStatus[i].app_state; - appStatus[i].persoSubstate = (PersoSubstate) rilAppStatus[i].perso_substate; - appStatus[i].aidPtr = convertCharPtrToHidlString(rilAppStatus[i].aid_ptr); - appStatus[i].appLabelPtr = convertCharPtrToHidlString( - rilAppStatus[i].app_label_ptr); - appStatus[i].pin1Replaced = rilAppStatus[i].pin1_replaced; - appStatus[i].pin1 = (PinState) rilAppStatus[i].pin1; - appStatus[i].pin2 = (PinState) rilAppStatus[i].pin2; - } - } - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2; - ::android::hardware::radio::V1_4::CardStatus cardStatusV1_4; - cardStatusV1_2.base = cardStatus; - cardStatusV1_2.physicalSlotId = -1; - cardStatusV1_4.base = cardStatusV1_2; - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4-> - getIccCardStatusResponse_1_4(responseInfo, cardStatusV1_4); - radioService[slotId]->checkReturnStatus(retStatus); - } else if (radioService[slotId]->mRadioResponseV1_3 != NULL) { - ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2; - cardStatusV1_2.base = cardStatus; - cardStatusV1_2.physicalSlotId = -1; - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_3-> - getIccCardStatusResponse_1_2(responseInfo, cardStatusV1_2); - radioService[slotId]->checkReturnStatus(retStatus); - } else if (radioService[slotId]->mRadioResponseV1_2 != NULL) { - ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2; - cardStatusV1_2.base = cardStatus; - cardStatusV1_2.physicalSlotId = -1; - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_2-> - getIccCardStatusResponse_1_2(responseInfo, cardStatusV1_2); - radioService[slotId]->checkReturnStatus(retStatus); - // TODO: add 1.1 if needed. - } else { - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - getIccCardStatusResponse(responseInfo, cardStatus); - radioService[slotId]->checkReturnStatus(retStatus); - } - } else { - RLOGE("getIccCardStatusResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::supplyIccPinForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("supplyIccPinForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - supplyIccPinForAppResponse(responseInfo, ret); - RLOGE("supplyIccPinForAppResponse: amit ret %d", ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("supplyIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::supplyIccPukForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("supplyIccPukForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse->supplyIccPukForAppResponse( - responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("supplyIccPukForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::supplyIccPin2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("supplyIccPin2ForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - supplyIccPin2ForAppResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("supplyIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::supplyIccPuk2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("supplyIccPuk2ForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - supplyIccPuk2ForAppResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("supplyIccPuk2ForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::changeIccPinForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("changeIccPinForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - changeIccPinForAppResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("changeIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::changeIccPin2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("changeIccPin2ForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - changeIccPin2ForAppResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("changeIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::supplyNetworkDepersonalizationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("supplyNetworkDepersonalizationResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - supplyNetworkDepersonalizationResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("supplyNetworkDepersonalizationResponse: radioService[%d]->mRadioResponse == " - "NULL", slotId); - } - - return 0; -} - -int radio_1_5::getCurrentCallsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getCurrentCallsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - hidl_vec<Call> calls; - if ((response == NULL && responseLen != 0) - || (responseLen % sizeof(RIL_Call *)) != 0) { - RLOGE("getCurrentCallsResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int num = responseLen / sizeof(RIL_Call *); - calls.resize(num); - - for (int i = 0 ; i < num ; i++) { - RIL_Call *p_cur = ((RIL_Call **) response)[i]; - /* each call info */ - calls[i].state = (CallState) p_cur->state; - calls[i].index = p_cur->index; - calls[i].toa = p_cur->toa; - calls[i].isMpty = p_cur->isMpty; - calls[i].isMT = p_cur->isMT; - calls[i].als = p_cur->als; - calls[i].isVoice = p_cur->isVoice; - calls[i].isVoicePrivacy = p_cur->isVoicePrivacy; - calls[i].number = convertCharPtrToHidlString(p_cur->number); - calls[i].numberPresentation = (CallPresentation) p_cur->numberPresentation; - calls[i].name = convertCharPtrToHidlString(p_cur->name); - calls[i].namePresentation = (CallPresentation) p_cur->namePresentation; - if (p_cur->uusInfo != NULL && p_cur->uusInfo->uusData != NULL) { - RIL_UUS_Info *uusInfo = p_cur->uusInfo; - calls[i].uusInfo.resize(1); - calls[i].uusInfo[0].uusType = (UusType) uusInfo->uusType; - calls[i].uusInfo[0].uusDcs = (UusDcs) uusInfo->uusDcs; - // convert uusInfo->uusData to a null-terminated string - char *nullTermStr = strndup(uusInfo->uusData, uusInfo->uusLength); - calls[i].uusInfo[0].uusData = nullTermStr; - free(nullTermStr); - } - } - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - getCurrentCallsResponse(responseInfo, calls); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCurrentCallsResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::dialResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("dialResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->dialResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("dialResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getIMSIForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getIMSIForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->getIMSIForAppResponse( - responseInfo, convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getIMSIForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::hangupConnectionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("hangupConnectionResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->hangupConnectionResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("hangupConnectionResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::hangupWaitingOrBackgroundResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = - radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::hangupForegroundResumeBackgroundResponse(int slotId, int responseType, int serial, - RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = - radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::switchWaitingOrHoldingAndActiveResponse(int slotId, int responseType, int serial, - RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("switchWaitingOrHoldingAndActiveResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = - radioService[slotId]->mRadioResponse->switchWaitingOrHoldingAndActiveResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("switchWaitingOrHoldingAndActiveResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::conferenceResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responseLen) { -#if VDBG - RLOGD("conferenceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->conferenceResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("conferenceResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::rejectCallResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responseLen) { -#if VDBG - RLOGD("rejectCallResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->rejectCallResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("rejectCallResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getLastCallFailCauseResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getLastCallFailCauseResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - LastCallFailCauseInfo info = {}; - info.vendorCause = hidl_string(); - if (response == NULL) { - RLOGE("getCurrentCallsResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else if (responseLen == sizeof(int)) { - int *pInt = (int *) response; - info.causeCode = (LastCallFailCause) pInt[0]; - } else if (responseLen == sizeof(RIL_LastCallFailCauseInfo)) { - RIL_LastCallFailCauseInfo *pFailCauseInfo = (RIL_LastCallFailCauseInfo *) response; - info.causeCode = (LastCallFailCause) pFailCauseInfo->cause_code; - info.vendorCause = convertCharPtrToHidlString(pFailCauseInfo->vendor_cause); - } else { - RLOGE("getCurrentCallsResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getLastCallFailCauseResponse( - responseInfo, info); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getLastCallFailCauseResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getSignalStrengthResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getSignalStrengthResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - SignalStrength signalStrength = {}; - if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) { - RLOGE("getSignalStrengthResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilSignalStrengthToHal(response, responseLen, signalStrength); - } - - ::android::hardware::radio::V1_4::SignalStrength signalStrength_1_4; - signalStrength_1_4.gsm = signalStrength.gw; - signalStrength_1_4.cdma = signalStrength.cdma; - signalStrength_1_4.evdo = signalStrength.evdo; - signalStrength_1_4.lte = signalStrength.lte; - //TODO: future implementation needs to fill tdScdma, wcdma and nr signal strength. - - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4-> - getSignalStrengthResponse_1_4(responseInfo, signalStrength_1_4); - radioService[slotId]->checkReturnStatus(retStatus); - } else if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - SignalStrength signalStrength = {}; - if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) { - RLOGE("getSignalStrengthResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilSignalStrengthToHal(response, responseLen, signalStrength); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getSignalStrengthResponse( - responseInfo, signalStrength); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getSignalStrengthResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) { - if (rat == NULL) { - return RIL_CELL_INFO_TYPE_NONE; - } - - int radioTech = atoi(rat); - - switch(radioTech) { - - case RADIO_TECH_GPRS: - case RADIO_TECH_EDGE: - case RADIO_TECH_GSM: { - return RIL_CELL_INFO_TYPE_GSM; - } - - case RADIO_TECH_UMTS: - case RADIO_TECH_HSDPA: - case RADIO_TECH_HSUPA: - case RADIO_TECH_HSPA: - case RADIO_TECH_HSPAP: { - return RIL_CELL_INFO_TYPE_WCDMA; - } - - case RADIO_TECH_IS95A: - case RADIO_TECH_IS95B: - case RADIO_TECH_1xRTT: - case RADIO_TECH_EVDO_0: - case RADIO_TECH_EVDO_A: - case RADIO_TECH_EVDO_B: - case RADIO_TECH_EHRPD: { - return RIL_CELL_INFO_TYPE_CDMA; - } - - case RADIO_TECH_LTE: - case RADIO_TECH_LTE_CA: { - return RIL_CELL_INFO_TYPE_LTE; - } - - case RADIO_TECH_TD_SCDMA: { - return RIL_CELL_INFO_TYPE_TD_SCDMA; - } - - default: { - break; - } - } - - return RIL_CELL_INFO_TYPE_NONE; - -} - -void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) { - - cellIdentity.cellIdentityGsm.resize(0); - cellIdentity.cellIdentityWcdma.resize(0); - cellIdentity.cellIdentityCdma.resize(0); - cellIdentity.cellIdentityTdscdma.resize(0); - cellIdentity.cellIdentityLte.resize(0); - cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType; - switch(rilCellIdentity.cellInfoType) { - - case RIL_CELL_INFO_TYPE_GSM: { - cellIdentity.cellIdentityGsm.resize(1); - cellIdentity.cellIdentityGsm[0].mcc = - std::to_string(rilCellIdentity.cellIdentityGsm.mcc); - cellIdentity.cellIdentityGsm[0].mnc = - ril::util::mnc::decode(rilCellIdentity.cellIdentityGsm.mnc); - cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac; - cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid; - cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn; - cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic; - break; - } - - case RIL_CELL_INFO_TYPE_WCDMA: { - cellIdentity.cellIdentityWcdma.resize(1); - cellIdentity.cellIdentityWcdma[0].mcc = - std::to_string(rilCellIdentity.cellIdentityWcdma.mcc); - cellIdentity.cellIdentityWcdma[0].mnc = - ril::util::mnc::decode(rilCellIdentity.cellIdentityWcdma.mnc); - cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac; - cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid; - cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc; - cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn; - break; - } - - case RIL_CELL_INFO_TYPE_CDMA: { - cellIdentity.cellIdentityCdma.resize(1); - cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId; - cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId; - cellIdentity.cellIdentityCdma[0].baseStationId = - rilCellIdentity.cellIdentityCdma.basestationId; - cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude; - cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude; - break; - } - - case RIL_CELL_INFO_TYPE_LTE: { - cellIdentity.cellIdentityLte.resize(1); - cellIdentity.cellIdentityLte[0].mcc = - std::to_string(rilCellIdentity.cellIdentityLte.mcc); - cellIdentity.cellIdentityLte[0].mnc = - ril::util::mnc::decode(rilCellIdentity.cellIdentityLte.mnc); - cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci; - cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci; - cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac; - cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn; - break; - } - - case RIL_CELL_INFO_TYPE_TD_SCDMA: { - cellIdentity.cellIdentityTdscdma.resize(1); - cellIdentity.cellIdentityTdscdma[0].mcc = - std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc); - cellIdentity.cellIdentityTdscdma[0].mnc = - ril::util::mnc::decode(rilCellIdentity.cellIdentityTdscdma.mnc); - cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac; - cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid; - cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid; - break; - } - - default: { - break; - } - } -} - -int convertResponseStringEntryToInt(char **response, int index, int numStrings) { - if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { - return atoi(response[index]); - } - - return -1; -} - -int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) { - const int hexBase = 16; - if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { - return strtol(response[index], NULL, hexBase); - } - - return -1; -} - -/* Fill Cell Identity info from Voice Registration State Response. - * This fucntion is applicable only for RIL Version < 15. - * Response is a "char **". - * First and Second entries are in hex string format - * and rest are integers represented in ascii format. */ -void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity, - int numStrings, char** response) { - - RIL_CellIdentity_v16 rilCellIdentity; - memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); - - rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); - switch(rilCellIdentity.cellInfoType) { - - case RIL_CELL_INFO_TYPE_GSM: { - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityGsm.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityGsm.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - - case RIL_CELL_INFO_TYPE_WCDMA: { - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityWcdma.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityWcdma.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - rilCellIdentity.cellIdentityWcdma.psc = - convertResponseStringEntryToInt(response, 14, numStrings); - break; - } - - case RIL_CELL_INFO_TYPE_TD_SCDMA:{ - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityTdscdma.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityTdscdma.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - - case RIL_CELL_INFO_TYPE_CDMA:{ - rilCellIdentity.cellIdentityCdma.basestationId = - convertResponseStringEntryToInt(response, 4, numStrings); - /* Order of Lat. and Long. swapped between RIL and HIDL interface versions. */ - rilCellIdentity.cellIdentityCdma.latitude = - convertResponseStringEntryToInt(response, 5, numStrings); - rilCellIdentity.cellIdentityCdma.longitude = - convertResponseStringEntryToInt(response, 6, numStrings); - rilCellIdentity.cellIdentityCdma.systemId = - convertResponseStringEntryToInt(response, 8, numStrings); - rilCellIdentity.cellIdentityCdma.networkId = - convertResponseStringEntryToInt(response, 9, numStrings); - break; - } - - case RIL_CELL_INFO_TYPE_LTE:{ - /* valid TAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityLte.tac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityLte.ci = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - - default: { - break; - } - } - - fillCellIdentityResponse(cellIdentity, rilCellIdentity); -} - -/* Fill Cell Identity info from Data Registration State Response. - * This fucntion is applicable only for RIL Version < 15. - * Response is a "char **". - * First and Second entries are in hex string format - * and rest are integers represented in ascii format. */ -void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity, - int numStrings, char** response) { - - RIL_CellIdentity_v16 rilCellIdentity; - memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); - - rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); - switch(rilCellIdentity.cellInfoType) { - case RIL_CELL_INFO_TYPE_GSM: { - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityGsm.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityGsm.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - case RIL_CELL_INFO_TYPE_WCDMA: { - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityWcdma.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityWcdma.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - case RIL_CELL_INFO_TYPE_TD_SCDMA:{ - /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ - rilCellIdentity.cellIdentityTdscdma.lac = - convertResponseHexStringEntryToInt(response, 1, numStrings); - - /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ - rilCellIdentity.cellIdentityTdscdma.cid = - convertResponseHexStringEntryToInt(response, 2, numStrings); - break; - } - case RIL_CELL_INFO_TYPE_LTE: { - rilCellIdentity.cellIdentityLte.tac = - convertResponseStringEntryToInt(response, 6, numStrings); - rilCellIdentity.cellIdentityLte.pci = - convertResponseStringEntryToInt(response, 7, numStrings); - rilCellIdentity.cellIdentityLte.ci = - convertResponseStringEntryToInt(response, 8, numStrings); - break; - } - default: { - break; - } - } - - fillCellIdentityResponse(cellIdentity, rilCellIdentity); -} - -int radio_1_5::getVoiceRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getVoiceRegistrationStateResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - VoiceRegStateResult voiceRegResponse = {}; - int numStrings = responseLen / sizeof(char *); - if (response == NULL) { - RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else if (s_vendorFunctions->version <= 14) { - if (numStrings != 15) { - RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - char **resp = (char **) response; - voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); - voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]); - voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0); - voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]); - voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0); - voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0); - voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0); - fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity, - numStrings, resp); - } - } else { - RIL_VoiceRegistrationStateResponse *voiceRegState = - (RIL_VoiceRegistrationStateResponse *)response; - - if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) { - RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - voiceRegResponse.regState = (RegState) voiceRegState->regState; - voiceRegResponse.rat = voiceRegState->rat;; - voiceRegResponse.cssSupported = voiceRegState->cssSupported; - voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator; - voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl; - voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator; - voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial; - fillCellIdentityResponse(voiceRegResponse.cellIdentity, - voiceRegState->cellIdentity); - } - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponse->getVoiceRegistrationStateResponse( - responseInfo, voiceRegResponse); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getVoiceRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getDataRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getDataRegistrationStateResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - DataRegStateResult dataRegResponse = {}; - if (response == NULL) { - RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else if (s_vendorFunctions->version <= 14) { - int numStrings = responseLen / sizeof(char *); - if ((numStrings != 6) && (numStrings != 11)) { - RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - char **resp = (char **) response; - dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); - dataRegResponse.rat = ATOI_NULL_HANDLED_DEF(resp[3], 0); - dataRegResponse.reasonDataDenied = ATOI_NULL_HANDLED(resp[4]); - dataRegResponse.maxDataCalls = ATOI_NULL_HANDLED_DEF(resp[5], 1); - fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity, - numStrings, resp); - } - } else { - RIL_DataRegistrationStateResponse *dataRegState = - (RIL_DataRegistrationStateResponse *)response; - - if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) { - RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - dataRegResponse.regState = (RegState) dataRegState->regState; - dataRegResponse.rat = dataRegState->rat;; - dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied; - dataRegResponse.maxDataCalls = dataRegState->maxDataCalls; - fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity); - } - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponse->getDataRegistrationStateResponse(responseInfo, - dataRegResponse); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getDataRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getOperatorResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getOperatorResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_string longName; - hidl_string shortName; - hidl_string numeric; - int numStrings = responseLen / sizeof(char *); - if (response == NULL || numStrings != 3) { - RLOGE("getOperatorResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - - } else { - char **resp = (char **) response; - longName = convertCharPtrToHidlString(resp[0]); - shortName = convertCharPtrToHidlString(resp[1]); - numeric = convertCharPtrToHidlString(resp[2]); - } - Return<void> retStatus = radioService[slotId]->mRadioResponse->getOperatorResponse( - responseInfo, longName, shortName, numeric); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getOperatorResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setRadioPowerResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { - RLOGD("setRadioPowerResponse: serial %d", serial); - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendDtmfResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->sendDtmfResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendDtmfResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -SendSmsResult makeSendSmsResult(RadioResponseInfo& responseInfo, int serial, int responseType, - RIL_Errno e, void *response, size_t responseLen) { - populateResponseInfo(responseInfo, serial, responseType, e); - SendSmsResult result = {}; - - if (response == NULL || responseLen != sizeof(RIL_SMS_Response)) { - RLOGE("Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - result.ackPDU = hidl_string(); - } else { - RIL_SMS_Response *resp = (RIL_SMS_Response *) response; - result.messageRef = resp->messageRef; - result.ackPDU = convertCharPtrToHidlString(resp->ackPDU); - result.errorCode = resp->errorCode; - } - return result; -} - -int radio_1_5::sendSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendSmsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSmsResponse(responseInfo, - result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendSMSExpectMoreResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendSMSExpectMoreResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSMSExpectMoreResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendSMSExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setupDataCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setupDataCallResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - ::android::hardware::radio::V1_4::SetupDataCallResult result; - if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) { - if (response != NULL) { - RLOGE("setupDataCallResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } - result.cause = ::android::hardware::radio::V1_4::DataCallFailCause::ERROR_UNSPECIFIED; - result.type = ::android::hardware::radio::V1_4::PdpProtocolType::UNKNOWN; - result.ifname = hidl_string(); - result.addresses = hidl_vec<hidl_string>(); - result.dnses = hidl_vec<hidl_string>(); - result.gateways = hidl_vec<hidl_string>(); - result.pcscf = hidl_vec<hidl_string>(); - } else { - convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->setupDataCallResponse_1_4( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - SetupDataCallResult result = {}; - if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) { - if (response != NULL) { - RLOGE("setupDataCallResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } - result.status = DataCallFailCause::ERROR_UNSPECIFIED; - result.type = hidl_string(); - result.ifname = hidl_string(); - result.addresses = hidl_string(); - result.dnses = hidl_string(); - result.gateways = hidl_string(); - result.pcscf = hidl_string(); - } else { - convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->setupDataCallResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setupDataCallResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -IccIoResult responseIccIo(RadioResponseInfo& responseInfo, int serial, int responseType, - RIL_Errno e, void *response, size_t responseLen) { - populateResponseInfo(responseInfo, serial, responseType, e); - IccIoResult result = {}; - - if (response == NULL || responseLen != sizeof(RIL_SIM_IO_Response)) { - RLOGE("Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - result.simResponse = hidl_string(); - } else { - RIL_SIM_IO_Response *resp = (RIL_SIM_IO_Response *) response; - result.sw1 = resp->sw1; - result.sw2 = resp->sw2; - result.simResponse = convertCharPtrToHidlString(resp->simResponse); - } - return result; -} - -int radio_1_5::iccIOForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("iccIOForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus = radioService[slotId]->mRadioResponse->iccIOForAppResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("iccIOForAppResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendUssdResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendUssdResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->sendUssdResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendUssdResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::cancelPendingUssdResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("cancelPendingUssdResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->cancelPendingUssdResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cancelPendingUssdResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getClirResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getClirResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - int n = -1, m = -1; - int numInts = responseLen / sizeof(int); - if (response == NULL || numInts != 2) { - RLOGE("getClirResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - n = pInt[0]; - m = pInt[1]; - } - Return<void> retStatus = radioService[slotId]->mRadioResponse->getClirResponse(responseInfo, - n, m); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setClirResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setClirResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->setClirResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getCallForwardStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getCallForwardStatusResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<CallForwardInfo> callForwardInfos; - - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_CallForwardInfo *) != 0) { - RLOGE("getCallForwardStatusResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int num = responseLen / sizeof(RIL_CallForwardInfo *); - callForwardInfos.resize(num); - for (int i = 0 ; i < num; i++) { - RIL_CallForwardInfo *resp = ((RIL_CallForwardInfo **) response)[i]; - callForwardInfos[i].status = (CallForwardInfoStatus) resp->status; - callForwardInfos[i].reason = resp->reason; - callForwardInfos[i].serviceClass = resp->serviceClass; - callForwardInfos[i].toa = resp->toa; - callForwardInfos[i].number = convertCharPtrToHidlString(resp->number); - callForwardInfos[i].timeSeconds = resp->timeSeconds; - } - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallForwardStatusResponse( - responseInfo, callForwardInfos); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCallForwardStatusResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setCallForwardResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setCallForwardResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallForwardResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCallForwardResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getCallWaitingResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getCallWaitingResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - bool enable = false; - int serviceClass = -1; - int numInts = responseLen / sizeof(int); - if (response == NULL || numInts != 2) { - RLOGE("getCallWaitingResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - enable = pInt[0] == 1 ? true : false; - serviceClass = pInt[1]; - } - Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallWaitingResponse( - responseInfo, enable, serviceClass); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setCallWaitingResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setCallWaitingResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallWaitingResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::acknowledgeLastIncomingGsmSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("acknowledgeLastIncomingGsmSmsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = - radioService[slotId]->mRadioResponse->acknowledgeLastIncomingGsmSmsResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acknowledgeLastIncomingGsmSmsResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::acceptCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("acceptCallResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->acceptCallResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acceptCallResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::deactivateDataCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("deactivateDataCallResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->deactivateDataCallResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("deactivateDataCallResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getFacilityLockForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getFacilityLockForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - getFacilityLockForAppResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setFacilityLockForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setFacilityLockForAppResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setFacilityLockForAppResponse(responseInfo, - ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setBarringPasswordResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("acceptCallResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setBarringPasswordResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setBarringPasswordResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getNetworkSelectionModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getNetworkSelectionModeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - bool manual = false; - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("getNetworkSelectionModeResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - manual = pInt[0] == 1 ? true : false; - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getNetworkSelectionModeResponse( - responseInfo, - manual); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getNetworkSelectionModeResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setNetworkSelectionModeAutomaticResponse(int slotId, int responseType, int serial, - RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setNetworkSelectionModeAutomaticResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setNetworkSelectionModeAutomaticResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setNetworkSelectionModeAutomaticResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::setNetworkSelectionModeManualResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse " - "== NULL", slotId); - } - - return 0; -} - -int convertOperatorStatusToInt(const char *str) { - if (strncmp("unknown", str, 9) == 0) { - return (int) OperatorStatus::UNKNOWN; - } else if (strncmp("available", str, 9) == 0) { - return (int) OperatorStatus::AVAILABLE; - } else if (strncmp("current", str, 9) == 0) { - return (int) OperatorStatus::CURRENT; - } else if (strncmp("forbidden", str, 9) == 0) { - return (int) OperatorStatus::FORBIDDEN; - } else { - return -1; - } -} - -int radio_1_5::getAvailableNetworksResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getAvailableNetworksResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<OperatorInfo> networks; - if ((response == NULL && responseLen != 0) - || responseLen % (4 * sizeof(char *))!= 0) { - RLOGE("getAvailableNetworksResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - char **resp = (char **) response; - int numStrings = responseLen / sizeof(char *); - networks.resize(numStrings/4); - for (int i = 0, j = 0; i < numStrings; i = i + 4, j++) { - networks[j].alphaLong = convertCharPtrToHidlString(resp[i]); - networks[j].alphaShort = convertCharPtrToHidlString(resp[i + 1]); - networks[j].operatorNumeric = convertCharPtrToHidlString(resp[i + 2]); - int status = convertOperatorStatusToInt(resp[i + 3]); - if (status == -1) { - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - networks[j].status = (OperatorStatus) status; - } - } - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getAvailableNetworksResponse(responseInfo, - networks); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getAvailableNetworksResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::startDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("startDtmfResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->startDtmfResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("startDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stopDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("stopDtmfResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->stopDtmfResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stopDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getBasebandVersionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getBasebandVersionResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getBasebandVersionResponse(responseInfo, - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getBasebandVersionResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::separateConnectionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("separateConnectionResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->separateConnectionResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("separateConnectionResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setMuteResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setMuteResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setMuteResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getMuteResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getMuteResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - bool enable = false; - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("getMuteResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - enable = pInt[0] == 1 ? true : false; - } - Return<void> retStatus = radioService[slotId]->mRadioResponse->getMuteResponse(responseInfo, - enable); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getClipResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getClipResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus = radioService[slotId]->mRadioResponse->getClipResponse(responseInfo, - (ClipStatus) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getClipResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getDataCallListResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getDataCallListResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - hidl_vec<SetupDataCallResult> ret; - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) { - RLOGE("getDataCallListResponse: invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilDataCallListToHal(response, responseLen, ret); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getDataCallListResponse( - responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getDataCallListResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setSuppServiceNotificationsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setSuppServiceNotificationsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setSuppServiceNotificationsResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setSuppServiceNotificationsResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::deleteSmsOnSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("deleteSmsOnSimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->deleteSmsOnSimResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("deleteSmsOnSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setBandModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setBandModeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setBandModeResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setBandModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::writeSmsToSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("writeSmsToSimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->writeSmsToSimResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("writeSmsToSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getAvailableBandModesResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getAvailableBandModesResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<RadioBandMode> modes; - if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) { - RLOGE("getAvailableBandModesResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - int numInts = responseLen / sizeof(int); - modes.resize(numInts); - for (int i = 0; i < numInts; i++) { - modes[i] = (RadioBandMode) pInt[i]; - } - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getAvailableBandModesResponse(responseInfo, - modes); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getAvailableBandModesResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendEnvelopeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendEnvelopeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendEnvelopeResponse(responseInfo, - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendEnvelopeResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendTerminalResponseToSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendTerminalResponseToSimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendTerminalResponseToSimResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendTerminalResponseToSimResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::handleStkCallSetupRequestFromSimResponse(int slotId, - int responseType, int serial, - RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("handleStkCallSetupRequestFromSimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->handleStkCallSetupRequestFromSimResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("handleStkCallSetupRequestFromSimResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::explicitCallTransferResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("explicitCallTransferResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->explicitCallTransferResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("explicitCallTransferResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setPreferredNetworkTypeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setPreferredNetworkTypeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setPreferredNetworkTypeResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - - -int radio_1_5::getPreferredNetworkTypeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getPreferredNetworkTypeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getPreferredNetworkTypeResponse( - responseInfo, (PreferredNetworkType) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setPreferredNetworkTypeBitmapResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setPreferredNetworkTypeBitmapResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->setPreferredNetworkTypeBitmapResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setPreferredNetworkTypeBitmapResponse: radioService[%d]->mRadioResponseV1_4 == NULL", - slotId); - } - - return 0; -} - - -int radio_1_5::getPreferredNetworkTypeBitmapResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getPreferredNetworkTypeBitmapResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->getPreferredNetworkTypeBitmapResponse( - responseInfo, - (const ::android::hardware::hidl_bitfield< - ::android::hardware::radio::V1_4::RadioAccessFamily>) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getPreferredNetworkTypeBitmapResponse: radioService[%d]->mRadioResponseV1_4 == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getNeighboringCidsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getNeighboringCidsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<NeighboringCell> cells; - - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_NeighboringCell *) != 0) { - RLOGE("getNeighboringCidsResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int num = responseLen / sizeof(RIL_NeighboringCell *); - cells.resize(num); - for (int i = 0 ; i < num; i++) { - RIL_NeighboringCell *resp = ((RIL_NeighboringCell **) response)[i]; - cells[i].cid = convertCharPtrToHidlString(resp->cid); - cells[i].rssi = resp->rssi; - } - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getNeighboringCidsResponse(responseInfo, - cells); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getNeighboringCidsResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setLocationUpdatesResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setLocationUpdatesResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setLocationUpdatesResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setLocationUpdatesResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setCdmaSubscriptionSourceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setCdmaSubscriptionSourceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setCdmaSubscriptionSourceResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setCdmaRoamingPreferenceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setCdmaRoamingPreferenceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setCdmaRoamingPreferenceResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getCdmaRoamingPreferenceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getCdmaRoamingPreferenceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getCdmaRoamingPreferenceResponse( - responseInfo, (CdmaRoamingType) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setTTYModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setTTYModeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setTTYModeResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getTTYModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getTTYModeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getTTYModeResponse(responseInfo, - (TtyMode) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setPreferredVoicePrivacyResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setPreferredVoicePrivacyResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setPreferredVoicePrivacyResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getPreferredVoicePrivacyResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getPreferredVoicePrivacyResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - bool enable = false; - int numInts = responseLen / sizeof(int); - if (response == NULL || numInts != 1) { - RLOGE("getPreferredVoicePrivacyResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - enable = pInt[0] == 1 ? true : false; - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getPreferredVoicePrivacyResponse( - responseInfo, enable); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendCDMAFeatureCodeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendCDMAFeatureCodeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendCDMAFeatureCodeResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendCDMAFeatureCodeResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendBurstDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendBurstDtmfResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendBurstDtmfResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendBurstDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendCdmaSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendCdmaSmsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendCdmaSmsResponse(responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendCdmaSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::acknowledgeLastIncomingCdmaSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("acknowledgeLastIncomingCdmaSmsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->acknowledgeLastIncomingCdmaSmsResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acknowledgeLastIncomingCdmaSmsResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::getGsmBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getGsmBroadcastConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<GsmBroadcastSmsConfigInfo> configs; - - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) { - RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int num = responseLen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *); - configs.resize(num); - for (int i = 0 ; i < num; i++) { - RIL_GSM_BroadcastSmsConfigInfo *resp = - ((RIL_GSM_BroadcastSmsConfigInfo **) response)[i]; - configs[i].fromServiceId = resp->fromServiceId; - configs[i].toServiceId = resp->toServiceId; - configs[i].fromCodeScheme = resp->fromCodeScheme; - configs[i].toCodeScheme = resp->toCodeScheme; - configs[i].selected = resp->selected == 1 ? true : false; - } - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getGsmBroadcastConfigResponse(responseInfo, - configs); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setGsmBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setGsmBroadcastConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setGsmBroadcastConfigResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setGsmBroadcastActivationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setGsmBroadcastActivationResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setGsmBroadcastActivationResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setGsmBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getCdmaBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getCdmaBroadcastConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<CdmaBroadcastSmsConfigInfo> configs; - - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) { - RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int num = responseLen / sizeof(RIL_CDMA_BroadcastSmsConfigInfo *); - configs.resize(num); - for (int i = 0 ; i < num; i++) { - RIL_CDMA_BroadcastSmsConfigInfo *resp = - ((RIL_CDMA_BroadcastSmsConfigInfo **) response)[i]; - configs[i].serviceCategory = resp->service_category; - configs[i].language = resp->language; - configs[i].selected = resp->selected == 1 ? true : false; - } - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getCdmaBroadcastConfigResponse(responseInfo, - configs); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setCdmaBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setCdmaBroadcastConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setCdmaBroadcastConfigResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setCdmaBroadcastActivationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setCdmaBroadcastActivationResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setCdmaBroadcastActivationResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCdmaBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getCDMASubscriptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getCDMASubscriptionResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - int numStrings = responseLen / sizeof(char *); - hidl_string emptyString; - if (response == NULL || numStrings != 5) { - RLOGE("getOperatorResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( - responseInfo, emptyString, emptyString, emptyString, emptyString, emptyString); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - char **resp = (char **) response; - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( - responseInfo, - convertCharPtrToHidlString(resp[0]), - convertCharPtrToHidlString(resp[1]), - convertCharPtrToHidlString(resp[2]), - convertCharPtrToHidlString(resp[3]), - convertCharPtrToHidlString(resp[4])); - radioService[slotId]->checkReturnStatus(retStatus); - } - } else { - RLOGE("getCDMASubscriptionResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::writeSmsToRuimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("writeSmsToRuimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->writeSmsToRuimResponse(responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("writeSmsToRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::deleteSmsOnRuimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("deleteSmsOnRuimResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->deleteSmsOnRuimResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("deleteSmsOnRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getDeviceIdentityResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getDeviceIdentityResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - int numStrings = responseLen / sizeof(char *); - hidl_string emptyString; - if (response == NULL || numStrings != 4) { - RLOGE("getDeviceIdentityResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, - emptyString, emptyString, emptyString, emptyString); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - char **resp = (char **) response; - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, - convertCharPtrToHidlString(resp[0]), - convertCharPtrToHidlString(resp[1]), - convertCharPtrToHidlString(resp[2]), - convertCharPtrToHidlString(resp[3])); - radioService[slotId]->checkReturnStatus(retStatus); - } - } else { - RLOGE("getDeviceIdentityResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::exitEmergencyCallbackModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("exitEmergencyCallbackModeResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->exitEmergencyCallbackModeResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("exitEmergencyCallbackModeResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getSmscAddressResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getSmscAddressResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getSmscAddressResponse(responseInfo, - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setSmscAddressResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setSmscAddressResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setSmscAddressResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::reportSmsMemoryStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("reportSmsMemoryStatusResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->reportSmsMemoryStatusResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("reportSmsMemoryStatusResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::reportStkServiceIsRunningResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("reportStkServiceIsRunningResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse-> - reportStkServiceIsRunningResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("reportStkServiceIsRunningResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getCdmaSubscriptionSourceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getCdmaSubscriptionSourceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getCdmaSubscriptionSourceResponse( - responseInfo, (CdmaSubscriptionSource) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::requestIsimAuthenticationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("requestIsimAuthenticationResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->requestIsimAuthenticationResponse( - responseInfo, - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("requestIsimAuthenticationResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::acknowledgeIncomingGsmSmsWithPduResponse(int slotId, - int responseType, - int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("acknowledgeIncomingGsmSmsWithPduResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("acknowledgeIncomingGsmSmsWithPduResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendEnvelopeWithStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendEnvelopeWithStatusResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, - response, responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendEnvelopeWithStatusResponse(responseInfo, - result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendEnvelopeWithStatusResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getVoiceRadioTechnologyResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getVoiceRadioTechnologyResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getVoiceRadioTechnologyResponse( - responseInfo, (RadioTechnology) ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getVoiceRadioTechnologyResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getCellInfoListResponse(int slotId, - int responseType, - int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("getCellInfoListResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - hidl_vec<CellInfo> ret; - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_CellInfo_v12) != 0) { - RLOGE("getCellInfoListResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilCellInfoListToHal(response, responseLen, ret); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getCellInfoListResponse( - responseInfo, ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getCellInfoListResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setCellInfoListRateResponse(int slotId, - int responseType, - int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("setCellInfoListRateResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setCellInfoListRateResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCellInfoListRateResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setInitialAttachApnResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setInitialAttachApnResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getImsRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getImsRegistrationStateResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - bool isRegistered = false; - int ratFamily = 0; - int numInts = responseLen / sizeof(int); - if (response == NULL || numInts != 2) { - RLOGE("getImsRegistrationStateResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - int *pInt = (int *) response; - isRegistered = pInt[0] == 1 ? true : false; - ratFamily = pInt[1]; - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getImsRegistrationStateResponse( - responseInfo, isRegistered, (RadioTechnologyFamily) ratFamily); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getImsRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendImsSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("sendImsSmsResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendImsSmsResponse(responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::iccTransmitApduBasicChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("iccTransmitApduBasicChannelResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->iccTransmitApduBasicChannelResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("iccTransmitApduBasicChannelResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::iccOpenLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("iccOpenLogicalChannelResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - int channelId = -1; - hidl_vec<int8_t> selectResponse; - int numInts = responseLen / sizeof(int); - if (response == NULL || responseLen % sizeof(int) != 0) { - RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL"); - if (response != NULL) { - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } - } else { - int *pInt = (int *) response; - channelId = pInt[0]; - selectResponse.resize(numInts - 1); - for (int i = 1; i < numInts; i++) { - selectResponse[i - 1] = (int8_t) pInt[i]; - } - } - Return<void> retStatus - = radioService[slotId]->mRadioResponse->iccOpenLogicalChannelResponse(responseInfo, - channelId, selectResponse); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("iccOpenLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::iccCloseLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("iccCloseLogicalChannelResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->iccCloseLogicalChannelResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("iccCloseLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::iccTransmitApduLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("iccTransmitApduLogicalChannelResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->iccTransmitApduLogicalChannelResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("iccTransmitApduLogicalChannelResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::nvReadItemResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("nvReadItemResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponse->nvReadItemResponse( - responseInfo, - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("nvReadItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::nvWriteItemResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("nvWriteItemResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->nvWriteItemResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("nvWriteItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::nvWriteCdmaPrlResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("nvWriteCdmaPrlResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->nvWriteCdmaPrlResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("nvWriteCdmaPrlResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::nvResetConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("nvResetConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->nvResetConfigResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("nvResetConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setUiccSubscriptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setUiccSubscriptionResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setUiccSubscriptionResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setUiccSubscriptionResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setDataAllowedResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setDataAllowedResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setDataAllowedResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setDataAllowedResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getHardwareConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getHardwareConfigResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - hidl_vec<HardwareConfig> result; - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_HardwareConfig) != 0) { - RLOGE("hardwareConfigChangedInd: invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilHardwareConfigListToHal(response, responseLen, result); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->getHardwareConfigResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getHardwareConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::requestIccSimAuthenticationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("requestIccSimAuthenticationResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, - responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->requestIccSimAuthenticationResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("requestIccSimAuthenticationResponse: radioService[%d]->mRadioResponse " - "== NULL", slotId); - } - - return 0; -} - -int radio_1_5::setDataProfileResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setDataProfileResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setDataProfileResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::requestShutdownResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("requestShutdownResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->requestShutdownResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("requestShutdownResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -void responseRadioCapability(RadioResponseInfo& responseInfo, int serial, - int responseType, RIL_Errno e, void *response, size_t responseLen, RadioCapability& rc) { - populateResponseInfo(responseInfo, serial, responseType, e); - - if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { - RLOGE("responseRadioCapability: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - rc.logicalModemUuid = hidl_string(); - } else { - convertRilRadioCapabilityToHal(response, responseLen, rc); - } -} - -int radio_1_5::getRadioCapabilityResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getRadioCapabilityResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - RadioCapability result = {}; - responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, - result); - Return<void> retStatus = radioService[slotId]->mRadioResponse->getRadioCapabilityResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setRadioCapabilityResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setRadioCapabilityResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - RadioCapability result = {}; - responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, - result); - Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioCapabilityResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -LceStatusInfo responseLceStatusInfo(RadioResponseInfo& responseInfo, int serial, int responseType, - RIL_Errno e, void *response, size_t responseLen) { - populateResponseInfo(responseInfo, serial, responseType, e); - LceStatusInfo result = {}; - - if (response == NULL || responseLen != sizeof(RIL_LceStatusInfo)) { - RLOGE("Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - RIL_LceStatusInfo *resp = (RIL_LceStatusInfo *) response; - result.lceStatus = (LceStatus) resp->lce_status; - result.actualIntervalMs = (uint8_t) resp->actual_interval_ms; - } - return result; -} - -int radio_1_5::startLceServiceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("startLceServiceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, - response, responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->startLceServiceResponse(responseInfo, - result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("startLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stopLceServiceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("stopLceServiceResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, - response, responseLen); - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->stopLceServiceResponse(responseInfo, - result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stopLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::pullLceDataResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("pullLceDataResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - LceDataInfo result = {}; - if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { - RLOGE("pullLceDataResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilLceDataInfoToHal(response, responseLen, result); - } - - Return<void> retStatus = radioService[slotId]->mRadioResponse->pullLceDataResponse( - responseInfo, result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("pullLceDataResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::getModemActivityInfoResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getModemActivityInfoResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - ActivityStatsInfo info; - if (response == NULL || responseLen != sizeof(RIL_ActivityStatsInfo)) { - RLOGE("getModemActivityInfoResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - RIL_ActivityStatsInfo *resp = (RIL_ActivityStatsInfo *)response; - info.sleepModeTimeMs = resp->sleep_mode_time_ms; - info.idleModeTimeMs = resp->idle_mode_time_ms; - for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) { - info.txmModetimeMs[i] = resp->tx_mode_time_ms[i]; - } - info.rxModeTimeMs = resp->rx_mode_time_ms; - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getModemActivityInfoResponse(responseInfo, - info); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getModemActivityInfoResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setAllowedCarriersResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setAllowedCarriersResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo, - ret); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setAllowedCarriersResponse4(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setAllowedCarriersResponse4: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->setAllowedCarriersResponse_1_4(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - - return 0; -} - -void prepareCarrierRestrictionsResponse(hidl_vec<Carrier>& allowedCarriers, - hidl_vec<Carrier>& excludedCarriers, - bool& allAllowed, - const RIL_CarrierRestrictions* pCr) { - if (pCr->len_allowed_carriers > 0 || pCr->len_excluded_carriers > 0) { - allAllowed = false; - } - allowedCarriers.resize(pCr->len_allowed_carriers); - for(int i = 0; i < pCr->len_allowed_carriers; i++) { - RIL_Carrier *carrier = pCr->allowed_carriers + i; - allowedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); - allowedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); - allowedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; - allowedCarriers[i].matchData = - convertCharPtrToHidlString(carrier->match_data); - } - - excludedCarriers.resize(pCr->len_excluded_carriers); - for(int i = 0; i < pCr->len_excluded_carriers; i++) { - RIL_Carrier *carrier = pCr->excluded_carriers + i; - excludedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); - excludedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); - excludedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; - excludedCarriers[i].matchData = - convertCharPtrToHidlString(carrier->match_data); - } -} - -int radio_1_5::getAllowedCarriersResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getAllowedCarriersResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - CarrierRestrictions carrierInfo = {}; - bool allAllowed = true; - if (response == NULL) { -#if VDBG - RLOGD("getAllowedCarriersResponse response is NULL: all allowed"); -#endif - carrierInfo.allowedCarriers.resize(0); - carrierInfo.excludedCarriers.resize(0); - } else if (responseLen != sizeof(RIL_CarrierRestrictions)) { - RLOGE("getAllowedCarriersResponse Invalid response"); - if (e == RIL_E_SUCCESS) { - responseInfo.error = RadioError::INVALID_RESPONSE; - } - } else { - RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response; - prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, pCr); - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo, - allAllowed, carrierInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::getAllowedCarriersResponse4(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("getAllowedCarriersResponse4: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierInfo = {}; - ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy = - ::android::hardware::radio::V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY; - bool allAllowed = true; - - if (response == NULL) { -#if VDBG - RLOGD("getAllowedCarriersResponse4 response is NULL: all allowed"); -#endif - carrierInfo.allowedCarriers.resize(0); - carrierInfo.excludedCarriers.resize(0); - carrierInfo.allowedCarriersPrioritized = false; - } else if (responseLen != sizeof(RIL_CarrierRestrictionsWithPriority)) { - RLOGE("getAllowedCarriersResponse4 Invalid response"); - if (e == RIL_E_SUCCESS) { - responseInfo.error = RadioError::INVALID_RESPONSE; - } - } else { - RIL_CarrierRestrictionsWithPriority *pCrExt = (RIL_CarrierRestrictionsWithPriority *)response; - - // Convert into the structure used in IRadio 1.0 to re-use existing code - RIL_CarrierRestrictions cr = {}; - cr.len_allowed_carriers = pCrExt->len_allowed_carriers; - cr.len_excluded_carriers = pCrExt->len_excluded_carriers; - cr.allowed_carriers = pCrExt->allowed_carriers; - cr.excluded_carriers = pCrExt->excluded_carriers; - prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, &cr); - - carrierInfo.allowedCarriersPrioritized = (bool)pCrExt->allowedCarriersPrioritized; - multiSimPolicy = (::android::hardware::radio::V1_4::SimLockMultiSimPolicy)pCrExt->multiSimPolicy; - } - - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->getAllowedCarriersResponse_1_4(responseInfo, - carrierInfo, multiSimPolicy); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("getAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - - return 0; -} - -int radio_1_5::sendDeviceStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen) { -#if VDBG - RLOGD("sendDeviceStateResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->sendDeviceStateResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("sendDeviceStateResponse: radioService[%d]->mRadioResponse == NULL", slotId); - } - - return 0; -} - -int radio_1_5::setCarrierInfoForImsiEncryptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { - RLOGD("setCarrierInfoForImsiEncryptionResponse: serial %d", serial); - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4-> - setCarrierInfoForImsiEncryptionResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setCarrierInfoForImsiEncryptionResponse: radioService[%d]->mRadioResponseV1_4 == " - "NULL", slotId); - } - return 0; -} - -int radio_1_5::setIndicationFilterResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen) { -#if VDBG - RLOGD("setIndicationFilterResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::setSimCardPowerResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("setSimCardPowerResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponse != NULL - || radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4-> - setSimCardPowerResponse_1_1(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGD("setSimCardPowerResponse: radioService[%d]->mRadioResponseV1_4 == NULL", - slotId); - Return<void> retStatus - = radioService[slotId]->mRadioResponse->setSimCardPowerResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } - } else { - RLOGE("setSimCardPowerResponse: radioService[%d]->mRadioResponse == NULL && " - "radioService[%d]->mRadioResponseV1_4 == NULL", slotId, slotId); - } - return 0; -} - -int radio_1_5::startNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("startNetworkScanResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - - return 0; -} - -int radio_1_5::startNetworkScanResponse4(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("startNetworkScanResponse4: serial %d", serial); -#endif - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse_1_4(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stopNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("stopNetworkScanResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->stopNetworkScanResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stopNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - - return 0; -} - -int radio_1_5::emergencyDialResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("emergencyDialResponse: serial %d", serial); -#endif - - if (radioService[slotId]->mRadioResponseV1_4 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_4->emergencyDialResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("emergencyDialResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId); - } - return 0; -} - -void convertRilKeepaliveStatusToHal(const RIL_KeepaliveStatus *rilStatus, - V1_1::KeepaliveStatus& halStatus) { - halStatus.sessionHandle = rilStatus->sessionHandle; - halStatus.code = static_cast<V1_1::KeepaliveStatusCode>(rilStatus->code); -} - -int radio_1_5::startKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_4 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_4 == NULL", __FUNCTION__, slotId); - return 0; - } - - V1_1::KeepaliveStatus ks = {}; - if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) { - RLOGE("%s: invalid response - %d", __FUNCTION__, static_cast<int>(e)); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - convertRilKeepaliveStatusToHal(static_cast<RIL_KeepaliveStatus*>(response), ks); - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_4->startKeepaliveResponse(responseInfo, ks); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::stopKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_4 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_4 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_4->stopKeepaliveResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::getModemStackStatusResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_3 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_3->getModemStackStatusResponse( - responseInfo, true); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::enableModemResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_3 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_3->enableModemResponse(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::sendRequestRawResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendRequestRawResponse: serial %d", serial); -#endif - - if (!kOemHookEnabled) return 0; - - if (oemHookService[slotId]->mOemHookResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<uint8_t> data; - - if (response == NULL) { - RLOGE("sendRequestRawResponse: Invalid response"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - data.setToExternal((uint8_t *) response, responseLen); - } - Return<void> retStatus = oemHookService[slotId]->mOemHookResponse-> - sendRequestRawResponse(responseInfo, data); - checkReturnStatus(slotId, retStatus, false); - } else { - RLOGE("sendRequestRawResponse: oemHookService[%d]->mOemHookResponse == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::sendRequestStringsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("sendRequestStringsResponse: serial %d", serial); -#endif - - if (!kOemHookEnabled) return 0; - - if (oemHookService[slotId]->mOemHookResponse != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - hidl_vec<hidl_string> data; - - if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) { - RLOGE("sendRequestStringsResponse Invalid response: NULL"); - if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; - } else { - char **resp = (char **) response; - int numStrings = responseLen / sizeof(char *); - data.resize(numStrings); - for (int i = 0; i < numStrings; i++) { - data[i] = convertCharPtrToHidlString(resp[i]); - } - } - Return<void> retStatus - = oemHookService[slotId]->mOemHookResponse->sendRequestStringsResponse( - responseInfo, data); - checkReturnStatus(slotId, retStatus, false); - } else { - RLOGE("sendRequestStringsResponse: oemHookService[%d]->mOemHookResponse == " - "NULL", slotId); - } - - return 0; -} - -int radio_1_5::setSystemSelectionChannelsResponse(int slotId, int responseType, int serial, - RIL_Errno e, void* /* response */, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_3 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_3->setSystemSelectionChannelsResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::setSignalStrengthReportingCriteriaResponse_1_5(int slotId, int responseType, - int serial, RIL_Errno e, void* /* response */, - size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - if (radioService[slotId]->mRadioResponseV1_5 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId); - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_5->setSignalStrengthReportingCriteriaResponse_1_5( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } - return 0; -} - -int radio_1_5::enableUiccApplicationsResponse(int slotId, int responseType, int serial, - RIL_Errno e, void* /* response */, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_5 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_5->enableUiccApplicationsResponse( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::areUiccApplicationsEnabledResponse(int slotId, int responseType, int serial, - RIL_Errno e, void* response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_5 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId); - return 0; - } - - bool enable = false; - if (response == NULL || responseLen != sizeof(bool)) { - RLOGE("isSimDetachedFromNetwork Invalid response."); - } else { - enable = (*((bool *) response)); - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_5->areUiccApplicationsEnabledResponse( - responseInfo, enable); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::canToggleUiccApplicationsEnablementResponse(int slotId, int responseType, - int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_5 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_5->canToggleUiccApplicationsEnablementResponse( - responseInfo, true); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::setSystemSelectionChannelsResponse_1_5(int slotId, int responseType, int serial, - RIL_Errno e, void* /* response */, size_t responseLen) { -#if VDBG - RLOGD("%s(): %d", __FUNCTION__, serial); -#endif - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - - // If we don't have a radio service, there's nothing we can do - if (radioService[slotId]->mRadioResponseV1_5 == NULL) { - RLOGE("%s: radioService[%d]->mRadioResponseV1_5 == NULL", __FUNCTION__, slotId); - return 0; - } - - Return<void> retStatus = - radioService[slotId]->mRadioResponseV1_5->setSystemSelectionChannelsResponse_1_5( - responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::startNetworkScanResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen) { -#if VDBG - RLOGD("startNetworkScanResponse_1_5: serial %d", serial); -#endif - if (radioService[slotId]->mRadioResponseV1_5 != NULL) { - RadioResponseInfo responseInfo = {}; - populateResponseInfo(responseInfo, serial, responseType, e); - Return<void> retStatus - = radioService[slotId]->mRadioResponseV1_5->startNetworkScanResponse_1_5(responseInfo); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_5 == NULL", slotId); - } - return 0; -} - -/*************************************************************************************************** - * INDICATION FUNCTIONS - * The below function handle unsolicited messages coming from the Radio - * (messages for which there is no pending request) - **************************************************************************************************/ - -RadioIndicationType convertIntToRadioIndicationType(int indicationType) { - return indicationType == RESPONSE_UNSOLICITED ? (RadioIndicationType::UNSOLICITED) : - (RadioIndicationType::UNSOLICITED_ACK_EXP); -} - -int radio_1_5::radioStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - RadioState radioState = - (RadioState) CALL_ONSTATEREQUEST(slotId); - RLOGD("radioStateChangedInd: radioState %d", radioState); - Return<void> retStatus = radioService[slotId]->mRadioIndication->radioStateChanged( - convertIntToRadioIndicationType(indicationType), radioState); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("radioStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::callStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("callStateChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->callStateChanged( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("callStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::networkStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("networkStateChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->networkStateChanged( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("networkStateChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -uint8_t hexCharToInt(uint8_t c) { - if (c >= '0' && c <= '9') return (c - '0'); - if (c >= 'A' && c <= 'F') return (c - 'A' + 10); - if (c >= 'a' && c <= 'f') return (c - 'a' + 10); - - return INVALID_HEX_CHAR; -} - -uint8_t * convertHexStringToBytes(void *response, size_t responseLen) { - if (responseLen % 2 != 0) { - return NULL; - } - - uint8_t *bytes = (uint8_t *)calloc(responseLen/2, sizeof(uint8_t)); - if (bytes == NULL) { - RLOGE("convertHexStringToBytes: cannot allocate memory for bytes string"); - return NULL; - } - uint8_t *hexString = (uint8_t *)response; - - for (size_t i = 0; i < responseLen; i += 2) { - uint8_t hexChar1 = hexCharToInt(hexString[i]); - uint8_t hexChar2 = hexCharToInt(hexString[i + 1]); - - if (hexChar1 == INVALID_HEX_CHAR || hexChar2 == INVALID_HEX_CHAR) { - RLOGE("convertHexStringToBytes: invalid hex char %d %d", - hexString[i], hexString[i + 1]); - free(bytes); - return NULL; - } - bytes[i/2] = ((hexChar1 << 4) | hexChar2); - } - - return bytes; -} - -int radio_1_5::newSmsInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("newSmsInd: invalid response"); - return 0; - } - - uint8_t *bytes = convertHexStringToBytes(response, responseLen); - if (bytes == NULL) { - RLOGE("newSmsInd: convertHexStringToBytes failed"); - return 0; - } - - hidl_vec<uint8_t> pdu; - pdu.setToExternal(bytes, responseLen/2); -#if VDBG - RLOGD("newSmsInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->newSms( - convertIntToRadioIndicationType(indicationType), pdu); - radioService[slotId]->checkReturnStatus(retStatus); - free(bytes); - } else { - RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::newSmsStatusReportInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("newSmsStatusReportInd: invalid response"); - return 0; - } - - uint8_t *bytes = convertHexStringToBytes(response, responseLen); - if (bytes == NULL) { - RLOGE("newSmsStatusReportInd: convertHexStringToBytes failed"); - return 0; - } - - hidl_vec<uint8_t> pdu; - pdu.setToExternal(bytes, responseLen/2); -#if VDBG - RLOGD("newSmsStatusReportInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsStatusReport( - convertIntToRadioIndicationType(indicationType), pdu); - radioService[slotId]->checkReturnStatus(retStatus); - free(bytes); - } else { - RLOGE("newSmsStatusReportInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::newSmsOnSimInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("newSmsOnSimInd: invalid response"); - return 0; - } - int32_t recordNumber = ((int32_t *) response)[0]; -#if VDBG - RLOGD("newSmsOnSimInd: slotIndex %d", recordNumber); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsOnSim( - convertIntToRadioIndicationType(indicationType), recordNumber); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("newSmsOnSimInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::onUssdInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != 2 * sizeof(char *)) { - RLOGE("onUssdInd: invalid response"); - return 0; - } - char **strings = (char **) response; - char *mode = strings[0]; - hidl_string msg = convertCharPtrToHidlString(strings[1]); - UssdModeType modeType = (UssdModeType) atoi(mode); -#if VDBG - RLOGD("onUssdInd: mode %s", mode); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->onUssd( - convertIntToRadioIndicationType(indicationType), modeType, msg); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("onUssdInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::nitzTimeReceivedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("nitzTimeReceivedInd: invalid response"); - return 0; - } - hidl_string nitzTime = convertCharPtrToHidlString((char *) response); -#if VDBG - RLOGD("nitzTimeReceivedInd: nitzTime %s receivedTime %" PRId64, nitzTime.c_str(), - nitzTimeReceived[slotId]); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->nitzTimeReceived( - convertIntToRadioIndicationType(indicationType), nitzTime, - nitzTimeReceived[slotId]); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("nitzTimeReceivedInd: radioService[%d]->mRadioIndication == NULL", slotId); - return -1; - } - - return 0; -} - -void convertRilSignalStrengthToHal(void *response, size_t responseLen, - SignalStrength& signalStrength) { - RIL_SignalStrength_v10 *rilSignalStrength = (RIL_SignalStrength_v10 *) response; - - // Fixup LTE for backwards compatibility - // signalStrength: -1 -> 99 - if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) { - rilSignalStrength->LTE_SignalStrength.signalStrength = 99; - } - // rsrp: -1 -> INT_MAX all other negative value to positive. - // So remap here - if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) { - rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX; - } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) { - rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp; - } - // rsrq: -1 -> INT_MAX - if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) { - rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX; - } - // Not remapping rssnr is already using INT_MAX - // cqi: -1 -> INT_MAX - if (rilSignalStrength->LTE_SignalStrength.cqi == -1) { - rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX; - } - - signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength; - signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate; - // RIL_SignalStrength_v10 not support gw.timingAdvance. Set to INT_MAX as - // invalid value. - signalStrength.gw.timingAdvance = INT_MAX; - - signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm; - signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio; - signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm; - signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio; - signalStrength.evdo.signalNoiseRatio = - rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio; - signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength; - signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp; - signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq; - signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr; - signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi; - signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance; - signalStrength.tdScdma.rscp = rilSignalStrength->TD_SCDMA_SignalStrength.rscp; -} - -int radio_1_5::currentSignalStrengthInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) { - RLOGE("currentSignalStrengthInd: invalid response"); - return 0; - } - - SignalStrength signalStrength = {}; - convertRilSignalStrengthToHal(response, responseLen, signalStrength); - -#if VDBG - RLOGD("currentSignalStrengthInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->currentSignalStrength( - convertIntToRadioIndicationType(indicationType), signalStrength); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("currentSignalStrengthInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, - SetupDataCallResult& dcResult) { - dcResult.status = (DataCallFailCause) dcResponse->status; - dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; - dcResult.cid = dcResponse->cid; - dcResult.active = dcResponse->active; - dcResult.type = convertCharPtrToHidlString(dcResponse->type); - dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); - dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); - dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); - dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); - dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf); - dcResult.mtu = dcResponse->mtu; -} - -hidl_vec<hidl_string> split(hidl_string str) { - std::vector<hidl_string> ret; - std::stringstream ss(static_cast<std::string>(str)); - - std::string tok; - - while(getline(ss, tok, ' ')) { - ret.push_back(hidl_string(tok)); - } - - return ret; -} - -::android::hardware::radio::V1_4::PdpProtocolType convertToPdpProtocolType(hidl_string str) { - if (strncmp("IP", str.c_str(), 2) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::IP; - } else if (strncmp("IPV6", str.c_str(), 4) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::IPV6; - } else if (strncmp("IPV4V6", str.c_str(), 6) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::IPV4V6; - } else if (strncmp("PPP", str.c_str(), 3) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::PPP; - } else if (strncmp("NON_IP", str.c_str(), 6) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::NON_IP; - } else if (strncmp("UNSTRUCTURED", str.c_str(), 12) == 0) { - return ::android::hardware::radio::V1_4::PdpProtocolType::UNSTRUCTURED; - } else { - return ::android::hardware::radio::V1_4::PdpProtocolType::UNKNOWN; - } -} - -void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, - ::android::hardware::radio::V1_4::SetupDataCallResult& dcResult) { - dcResult.cause = (::android::hardware::radio::V1_4::DataCallFailCause) dcResponse->status; - dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; - dcResult.cid = dcResponse->cid; - dcResult.active = (::android::hardware::radio::V1_4::DataConnActiveStatus)dcResponse->active; - dcResult.type = convertToPdpProtocolType(convertCharPtrToHidlString(dcResponse->type)); - dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); - dcResult.addresses = split(convertCharPtrToHidlString(dcResponse->addresses)); - dcResult.dnses = split(convertCharPtrToHidlString(dcResponse->dnses)); - dcResult.gateways = split(convertCharPtrToHidlString(dcResponse->gateways)); - dcResult.pcscf = split(convertCharPtrToHidlString(dcResponse->pcscf)); - dcResult.mtu = dcResponse->mtu; -} - - -void convertRilDataCallListToHal(void *response, size_t responseLen, - hidl_vec<SetupDataCallResult>& dcResultList) { - int num = responseLen / sizeof(RIL_Data_Call_Response_v11); - - RIL_Data_Call_Response_v11 *dcResponse = (RIL_Data_Call_Response_v11 *) response; - dcResultList.resize(num); - for (int i = 0; i < num; i++) { - convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); - } -} - -int radio_1_5::dataCallListChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) { - RLOGE("dataCallListChangedInd: invalid response"); - return 0; - } - hidl_vec<SetupDataCallResult> dcList; - convertRilDataCallListToHal(response, responseLen, dcList); -#if VDBG - RLOGD("dataCallListChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->dataCallListChanged( - convertIntToRadioIndicationType(indicationType), dcList); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("dataCallListChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::suppSvcNotifyInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_SuppSvcNotification)) { - RLOGE("suppSvcNotifyInd: invalid response"); - return 0; - } - - SuppSvcNotification suppSvc = {}; - RIL_SuppSvcNotification *ssn = (RIL_SuppSvcNotification *) response; - suppSvc.isMT = ssn->notificationType; - suppSvc.code = ssn->code; - suppSvc.index = ssn->index; - suppSvc.type = ssn->type; - suppSvc.number = convertCharPtrToHidlString(ssn->number); - -#if VDBG - RLOGD("suppSvcNotifyInd: isMT %d code %d index %d type %d", - suppSvc.isMT, suppSvc.code, suppSvc.index, suppSvc.type); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->suppSvcNotify( - convertIntToRadioIndicationType(indicationType), suppSvc); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("suppSvcNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stkSessionEndInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("stkSessionEndInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->stkSessionEnd( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stkSessionEndInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stkProactiveCommandInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("stkProactiveCommandInd: invalid response"); - return 0; - } -#if VDBG - RLOGD("stkProactiveCommandInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->stkProactiveCommand( - convertIntToRadioIndicationType(indicationType), - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stkProactiveCommandInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stkEventNotifyInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("stkEventNotifyInd: invalid response"); - return 0; - } -#if VDBG - RLOGD("stkEventNotifyInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->stkEventNotify( - convertIntToRadioIndicationType(indicationType), - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stkEventNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stkCallSetupInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("stkCallSetupInd: invalid response"); - return 0; - } - int32_t timeout = ((int32_t *) response)[0]; -#if VDBG - RLOGD("stkCallSetupInd: timeout %d", timeout); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallSetup( - convertIntToRadioIndicationType(indicationType), timeout); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stkCallSetupInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::simSmsStorageFullInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("simSmsStorageFullInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->simSmsStorageFull( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("simSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::simRefreshInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_SimRefreshResponse_v7)) { - RLOGE("simRefreshInd: invalid response"); - return 0; - } - - SimRefreshResult refreshResult = {}; - RIL_SimRefreshResponse_v7 *simRefreshResponse = ((RIL_SimRefreshResponse_v7 *) response); - refreshResult.type = - (V1_0::SimRefreshType) simRefreshResponse->result; - refreshResult.efId = simRefreshResponse->ef_id; - refreshResult.aid = convertCharPtrToHidlString(simRefreshResponse->aid); - -#if VDBG - RLOGD("simRefreshInd: type %d efId %d", refreshResult.type, refreshResult.efId); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->simRefresh( - convertIntToRadioIndicationType(indicationType), refreshResult); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("simRefreshInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -void convertRilCdmaSignalInfoRecordToHal(RIL_CDMA_SignalInfoRecord *signalInfoRecord, - CdmaSignalInfoRecord& record) { - record.isPresent = signalInfoRecord->isPresent; - record.signalType = signalInfoRecord->signalType; - record.alertPitch = signalInfoRecord->alertPitch; - record.signal = signalInfoRecord->signal; -} - -int radio_1_5::callRingInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - bool isGsm; - CdmaSignalInfoRecord record = {}; - if (response == NULL || responseLen == 0) { - isGsm = true; - } else { - isGsm = false; - if (responseLen != sizeof (RIL_CDMA_SignalInfoRecord)) { - RLOGE("callRingInd: invalid response"); - return 0; - } - convertRilCdmaSignalInfoRecordToHal((RIL_CDMA_SignalInfoRecord *) response, record); - } - -#if VDBG - RLOGD("callRingInd: isGsm %d", isGsm); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->callRing( - convertIntToRadioIndicationType(indicationType), isGsm, record); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("callRingInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::simStatusChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("simStatusChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->simStatusChanged( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("simStatusChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::cdmaNewSmsInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_CDMA_SMS_Message)) { - RLOGE("cdmaNewSmsInd: invalid response"); - return 0; - } - - CdmaSmsMessage msg = {}; - RIL_CDMA_SMS_Message *rilMsg = (RIL_CDMA_SMS_Message *) response; - msg.teleserviceId = rilMsg->uTeleserviceID; - msg.isServicePresent = rilMsg->bIsServicePresent; - msg.serviceCategory = rilMsg->uServicecategory; - msg.address.digitMode = - (V1_0::CdmaSmsDigitMode) rilMsg->sAddress.digit_mode; - msg.address.numberMode = - (V1_0::CdmaSmsNumberMode) rilMsg->sAddress.number_mode; - msg.address.numberType = - (V1_0::CdmaSmsNumberType) rilMsg->sAddress.number_type; - msg.address.numberPlan = - (V1_0::CdmaSmsNumberPlan) rilMsg->sAddress.number_plan; - - int digitLimit = MIN((rilMsg->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); - msg.address.digits.setToExternal(rilMsg->sAddress.digits, digitLimit); - - msg.subAddress.subaddressType = (V1_0::CdmaSmsSubaddressType) - rilMsg->sSubAddress.subaddressType; - msg.subAddress.odd = rilMsg->sSubAddress.odd; - - digitLimit= MIN((rilMsg->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); - msg.subAddress.digits.setToExternal(rilMsg->sSubAddress.digits, digitLimit); - - digitLimit = MIN((rilMsg->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); - msg.bearerData.setToExternal(rilMsg->aBearerData, digitLimit); - -#if VDBG - RLOGD("cdmaNewSmsInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaNewSms( - convertIntToRadioIndicationType(indicationType), msg); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaNewSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::newBroadcastSmsInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("newBroadcastSmsInd: invalid response"); - return 0; - } - - hidl_vec<uint8_t> data; - data.setToExternal((uint8_t *) response, responseLen); -#if VDBG - RLOGD("newBroadcastSmsInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->newBroadcastSms( - convertIntToRadioIndicationType(indicationType), data); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("newBroadcastSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::cdmaRuimSmsStorageFullInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("cdmaRuimSmsStorageFullInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaRuimSmsStorageFull( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaRuimSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::restrictedStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("restrictedStateChangedInd: invalid response"); - return 0; - } - int32_t state = ((int32_t *) response)[0]; -#if VDBG - RLOGD("restrictedStateChangedInd: state %d", state); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->restrictedStateChanged( - convertIntToRadioIndicationType(indicationType), (PhoneRestrictedState) state); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("restrictedStateChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::enterEmergencyCallbackModeInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("enterEmergencyCallbackModeInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->enterEmergencyCallbackMode( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("enterEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::cdmaCallWaitingInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_CDMA_CallWaiting_v6)) { - RLOGE("cdmaCallWaitingInd: invalid response"); - return 0; - } - - CdmaCallWaiting callWaitingRecord = {}; - RIL_CDMA_CallWaiting_v6 *callWaitingRil = ((RIL_CDMA_CallWaiting_v6 *) response); - callWaitingRecord.number = convertCharPtrToHidlString(callWaitingRil->number); - callWaitingRecord.numberPresentation = - (CdmaCallWaitingNumberPresentation) callWaitingRil->numberPresentation; - callWaitingRecord.name = convertCharPtrToHidlString(callWaitingRil->name); - convertRilCdmaSignalInfoRecordToHal(&callWaitingRil->signalInfoRecord, - callWaitingRecord.signalInfoRecord); - callWaitingRecord.numberType = (CdmaCallWaitingNumberType) callWaitingRil->number_type; - callWaitingRecord.numberPlan = (CdmaCallWaitingNumberPlan) callWaitingRil->number_plan; - -#if VDBG - RLOGD("cdmaCallWaitingInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaCallWaiting( - convertIntToRadioIndicationType(indicationType), callWaitingRecord); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaCallWaitingInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::cdmaOtaProvisionStatusInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("cdmaOtaProvisionStatusInd: invalid response"); - return 0; - } - int32_t status = ((int32_t *) response)[0]; -#if VDBG - RLOGD("cdmaOtaProvisionStatusInd: status %d", status); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaOtaProvisionStatus( - convertIntToRadioIndicationType(indicationType), (CdmaOtaProvisionStatus) status); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaOtaProvisionStatusInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::cdmaInfoRecInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_CDMA_InformationRecords)) { - RLOGE("cdmaInfoRecInd: invalid response"); - return 0; - } - - CdmaInformationRecords records = {}; - RIL_CDMA_InformationRecords *recordsRil = (RIL_CDMA_InformationRecords *) response; - - char* string8 = NULL; - int num = MIN(recordsRil->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); - if (recordsRil->numberOfInfoRecs > RIL_CDMA_MAX_NUMBER_OF_INFO_RECS) { - RLOGE("cdmaInfoRecInd: received %d recs which is more than %d, dropping " - "additional ones", recordsRil->numberOfInfoRecs, - RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); - } - records.infoRec.resize(num); - for (int i = 0 ; i < num ; i++) { - CdmaInformationRecord *record = &records.infoRec[i]; - RIL_CDMA_InformationRecord *infoRec = &recordsRil->infoRec[i]; - record->name = (CdmaInfoRecName) infoRec->name; - // All vectors should be size 0 except one which will be size 1. Set everything to - // size 0 initially. - record->display.resize(0); - record->number.resize(0); - record->signal.resize(0); - record->redir.resize(0); - record->lineCtrl.resize(0); - record->clir.resize(0); - record->audioCtrl.resize(0); - switch (infoRec->name) { - case RIL_CDMA_DISPLAY_INFO_REC: - case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: { - if (infoRec->rec.display.alpha_len > CDMA_ALPHA_INFO_BUFFER_LENGTH) { - RLOGE("cdmaInfoRecInd: invalid display info response length %d " - "expected not more than %d", (int) infoRec->rec.display.alpha_len, - CDMA_ALPHA_INFO_BUFFER_LENGTH); - return 0; - } - string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1) * sizeof(char)); - if (string8 == NULL) { - RLOGE("cdmaInfoRecInd: Memory allocation failed for " - "responseCdmaInformationRecords"); - return 0; - } - memcpy(string8, infoRec->rec.display.alpha_buf, infoRec->rec.display.alpha_len); - string8[(int)infoRec->rec.display.alpha_len] = '\0'; - - record->display.resize(1); - record->display[0].alphaBuf = string8; - free(string8); - string8 = NULL; - break; - } - - case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: - case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: { - if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) { - RLOGE("cdmaInfoRecInd: invalid display info response length %d " - "expected not more than %d", (int) infoRec->rec.number.len, - CDMA_NUMBER_INFO_BUFFER_LENGTH); - return 0; - } - string8 = (char*) malloc((infoRec->rec.number.len + 1) * sizeof(char)); - if (string8 == NULL) { - RLOGE("cdmaInfoRecInd: Memory allocation failed for " - "responseCdmaInformationRecords"); - return 0; - } - memcpy(string8, infoRec->rec.number.buf, infoRec->rec.number.len); - string8[(int)infoRec->rec.number.len] = '\0'; - - record->number.resize(1); - record->number[0].number = string8; - free(string8); - string8 = NULL; - record->number[0].numberType = infoRec->rec.number.number_type; - record->number[0].numberPlan = infoRec->rec.number.number_plan; - record->number[0].pi = infoRec->rec.number.pi; - record->number[0].si = infoRec->rec.number.si; - break; - } - - case RIL_CDMA_SIGNAL_INFO_REC: { - record->signal.resize(1); - record->signal[0].isPresent = infoRec->rec.signal.isPresent; - record->signal[0].signalType = infoRec->rec.signal.signalType; - record->signal[0].alertPitch = infoRec->rec.signal.alertPitch; - record->signal[0].signal = infoRec->rec.signal.signal; - break; - } - - case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: { - if (infoRec->rec.redir.redirectingNumber.len > - CDMA_NUMBER_INFO_BUFFER_LENGTH) { - RLOGE("cdmaInfoRecInd: invalid display info response length %d " - "expected not more than %d\n", - (int)infoRec->rec.redir.redirectingNumber.len, - CDMA_NUMBER_INFO_BUFFER_LENGTH); - return 0; - } - string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber.len + 1) * - sizeof(char)); - if (string8 == NULL) { - RLOGE("cdmaInfoRecInd: Memory allocation failed for " - "responseCdmaInformationRecords"); - return 0; - } - memcpy(string8, infoRec->rec.redir.redirectingNumber.buf, - infoRec->rec.redir.redirectingNumber.len); - string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0'; - - record->redir.resize(1); - record->redir[0].redirectingNumber.number = string8; - free(string8); - string8 = NULL; - record->redir[0].redirectingNumber.numberType = - infoRec->rec.redir.redirectingNumber.number_type; - record->redir[0].redirectingNumber.numberPlan = - infoRec->rec.redir.redirectingNumber.number_plan; - record->redir[0].redirectingNumber.pi = infoRec->rec.redir.redirectingNumber.pi; - record->redir[0].redirectingNumber.si = infoRec->rec.redir.redirectingNumber.si; - record->redir[0].redirectingReason = - (CdmaRedirectingReason) infoRec->rec.redir.redirectingReason; - break; - } - - case RIL_CDMA_LINE_CONTROL_INFO_REC: { - record->lineCtrl.resize(1); - record->lineCtrl[0].lineCtrlPolarityIncluded = - infoRec->rec.lineCtrl.lineCtrlPolarityIncluded; - record->lineCtrl[0].lineCtrlToggle = infoRec->rec.lineCtrl.lineCtrlToggle; - record->lineCtrl[0].lineCtrlReverse = infoRec->rec.lineCtrl.lineCtrlReverse; - record->lineCtrl[0].lineCtrlPowerDenial = - infoRec->rec.lineCtrl.lineCtrlPowerDenial; - break; - } - - case RIL_CDMA_T53_CLIR_INFO_REC: { - record->clir.resize(1); - record->clir[0].cause = infoRec->rec.clir.cause; - break; - } - - case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: { - record->audioCtrl.resize(1); - record->audioCtrl[0].upLink = infoRec->rec.audioCtrl.upLink; - record->audioCtrl[0].downLink = infoRec->rec.audioCtrl.downLink; - break; - } - - case RIL_CDMA_T53_RELEASE_INFO_REC: - RLOGE("cdmaInfoRecInd: RIL_CDMA_T53_RELEASE_INFO_REC: INVALID"); - return 0; - - default: - RLOGE("cdmaInfoRecInd: Incorrect name value"); - return 0; - } - } - -#if VDBG - RLOGD("cdmaInfoRecInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaInfoRec( - convertIntToRadioIndicationType(indicationType), records); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaInfoRecInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::indicateRingbackToneInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("indicateRingbackToneInd: invalid response"); - return 0; - } - bool start = ((int32_t *) response)[0]; -#if VDBG - RLOGD("indicateRingbackToneInd: start %d", start); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->indicateRingbackTone( - convertIntToRadioIndicationType(indicationType), start); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("indicateRingbackToneInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::resendIncallMuteInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("resendIncallMuteInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->resendIncallMute( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("resendIncallMuteInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::cdmaSubscriptionSourceChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("cdmaSubscriptionSourceChangedInd: invalid response"); - return 0; - } - int32_t cdmaSource = ((int32_t *) response)[0]; -#if VDBG - RLOGD("cdmaSubscriptionSourceChangedInd: cdmaSource %d", cdmaSource); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication-> - cdmaSubscriptionSourceChanged(convertIntToRadioIndicationType(indicationType), - (CdmaSubscriptionSource) cdmaSource); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaSubscriptionSourceChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::cdmaPrlChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("cdmaPrlChangedInd: invalid response"); - return 0; - } - int32_t version = ((int32_t *) response)[0]; -#if VDBG - RLOGD("cdmaPrlChangedInd: version %d", version); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaPrlChanged( - convertIntToRadioIndicationType(indicationType), version); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cdmaPrlChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::exitEmergencyCallbackModeInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("exitEmergencyCallbackModeInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->exitEmergencyCallbackMode( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("exitEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::rilConnectedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - RLOGD("rilConnectedInd"); - Return<void> retStatus = radioService[slotId]->mRadioIndication->rilConnected( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("rilConnectedInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::voiceRadioTechChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("voiceRadioTechChangedInd: invalid response"); - return 0; - } - int32_t rat = ((int32_t *) response)[0]; -#if VDBG - RLOGD("voiceRadioTechChangedInd: rat %d", rat); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->voiceRadioTechChanged( - convertIntToRadioIndicationType(indicationType), (RadioTechnology) rat); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("voiceRadioTechChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records) { - int num = responseLen / sizeof(RIL_CellInfo_v12); - records.resize(num); - - RIL_CellInfo_v12 *rillCellInfo = (RIL_CellInfo_v12 *) response; - for (int i = 0; i < num; i++) { - records[i].cellInfoType = (CellInfoType) rillCellInfo->cellInfoType; - records[i].registered = rillCellInfo->registered; - records[i].timeStampType = (TimeStampType) rillCellInfo->timeStampType; - records[i].timeStamp = rillCellInfo->timeStamp; - // All vectors should be size 0 except one which will be size 1. Set everything to - // size 0 initially. - records[i].gsm.resize(0); - records[i].wcdma.resize(0); - records[i].cdma.resize(0); - records[i].lte.resize(0); - records[i].tdscdma.resize(0); - switch(rillCellInfo->cellInfoType) { - case RIL_CELL_INFO_TYPE_GSM: { - records[i].gsm.resize(1); - CellInfoGsm *cellInfoGsm = &records[i].gsm[0]; - cellInfoGsm->cellIdentityGsm.mcc = - std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc); - cellInfoGsm->cellIdentityGsm.mnc = - ril::util::mnc::decode(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc); - cellInfoGsm->cellIdentityGsm.lac = - rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac; - cellInfoGsm->cellIdentityGsm.cid = - rillCellInfo->CellInfo.gsm.cellIdentityGsm.cid; - cellInfoGsm->cellIdentityGsm.arfcn = - rillCellInfo->CellInfo.gsm.cellIdentityGsm.arfcn; - cellInfoGsm->cellIdentityGsm.bsic = - rillCellInfo->CellInfo.gsm.cellIdentityGsm.bsic; - cellInfoGsm->signalStrengthGsm.signalStrength = - rillCellInfo->CellInfo.gsm.signalStrengthGsm.signalStrength; - cellInfoGsm->signalStrengthGsm.bitErrorRate = - rillCellInfo->CellInfo.gsm.signalStrengthGsm.bitErrorRate; - cellInfoGsm->signalStrengthGsm.timingAdvance = - rillCellInfo->CellInfo.gsm.signalStrengthGsm.timingAdvance; - break; - } - - case RIL_CELL_INFO_TYPE_WCDMA: { - records[i].wcdma.resize(1); - CellInfoWcdma *cellInfoWcdma = &records[i].wcdma[0]; - cellInfoWcdma->cellIdentityWcdma.mcc = - std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc); - cellInfoWcdma->cellIdentityWcdma.mnc = - ril::util::mnc::decode(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc); - cellInfoWcdma->cellIdentityWcdma.lac = - rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac; - cellInfoWcdma->cellIdentityWcdma.cid = - rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.cid; - cellInfoWcdma->cellIdentityWcdma.psc = - rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.psc; - cellInfoWcdma->cellIdentityWcdma.uarfcn = - rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.uarfcn; - cellInfoWcdma->signalStrengthWcdma.signalStrength = - rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.signalStrength; - cellInfoWcdma->signalStrengthWcdma.bitErrorRate = - rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate; - break; - } - - case RIL_CELL_INFO_TYPE_CDMA: { - records[i].cdma.resize(1); - CellInfoCdma *cellInfoCdma = &records[i].cdma[0]; - cellInfoCdma->cellIdentityCdma.networkId = - rillCellInfo->CellInfo.cdma.cellIdentityCdma.networkId; - cellInfoCdma->cellIdentityCdma.systemId = - rillCellInfo->CellInfo.cdma.cellIdentityCdma.systemId; - cellInfoCdma->cellIdentityCdma.baseStationId = - rillCellInfo->CellInfo.cdma.cellIdentityCdma.basestationId; - cellInfoCdma->cellIdentityCdma.longitude = - rillCellInfo->CellInfo.cdma.cellIdentityCdma.longitude; - cellInfoCdma->cellIdentityCdma.latitude = - rillCellInfo->CellInfo.cdma.cellIdentityCdma.latitude; - cellInfoCdma->signalStrengthCdma.dbm = - rillCellInfo->CellInfo.cdma.signalStrengthCdma.dbm; - cellInfoCdma->signalStrengthCdma.ecio = - rillCellInfo->CellInfo.cdma.signalStrengthCdma.ecio; - cellInfoCdma->signalStrengthEvdo.dbm = - rillCellInfo->CellInfo.cdma.signalStrengthEvdo.dbm; - cellInfoCdma->signalStrengthEvdo.ecio = - rillCellInfo->CellInfo.cdma.signalStrengthEvdo.ecio; - cellInfoCdma->signalStrengthEvdo.signalNoiseRatio = - rillCellInfo->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio; - break; - } - - case RIL_CELL_INFO_TYPE_LTE: { - records[i].lte.resize(1); - CellInfoLte *cellInfoLte = &records[i].lte[0]; - cellInfoLte->cellIdentityLte.mcc = - std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc); - cellInfoLte->cellIdentityLte.mnc = - ril::util::mnc::decode(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc); - cellInfoLte->cellIdentityLte.ci = - rillCellInfo->CellInfo.lte.cellIdentityLte.ci; - cellInfoLte->cellIdentityLte.pci = - rillCellInfo->CellInfo.lte.cellIdentityLte.pci; - cellInfoLte->cellIdentityLte.tac = - rillCellInfo->CellInfo.lte.cellIdentityLte.tac; - cellInfoLte->cellIdentityLte.earfcn = - rillCellInfo->CellInfo.lte.cellIdentityLte.earfcn; - cellInfoLte->signalStrengthLte.signalStrength = - rillCellInfo->CellInfo.lte.signalStrengthLte.signalStrength; - cellInfoLte->signalStrengthLte.rsrp = - rillCellInfo->CellInfo.lte.signalStrengthLte.rsrp; - cellInfoLte->signalStrengthLte.rsrq = - rillCellInfo->CellInfo.lte.signalStrengthLte.rsrq; - cellInfoLte->signalStrengthLte.rssnr = - rillCellInfo->CellInfo.lte.signalStrengthLte.rssnr; - cellInfoLte->signalStrengthLte.cqi = - rillCellInfo->CellInfo.lte.signalStrengthLte.cqi; - cellInfoLte->signalStrengthLte.timingAdvance = - rillCellInfo->CellInfo.lte.signalStrengthLte.timingAdvance; - break; - } - - case RIL_CELL_INFO_TYPE_TD_SCDMA: { - records[i].tdscdma.resize(1); - CellInfoTdscdma *cellInfoTdscdma = &records[i].tdscdma[0]; - cellInfoTdscdma->cellIdentityTdscdma.mcc = - std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc); - cellInfoTdscdma->cellIdentityTdscdma.mnc = - ril::util::mnc::decode( - rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc); - cellInfoTdscdma->cellIdentityTdscdma.lac = - rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac; - cellInfoTdscdma->cellIdentityTdscdma.cid = - rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cid; - cellInfoTdscdma->cellIdentityTdscdma.cpid = - rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cpid; - cellInfoTdscdma->signalStrengthTdscdma.rscp = - rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp; - break; - } - default: { - break; - } - } - rillCellInfo += 1; - } -} - -int radio_1_5::cellInfoListInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) { - RLOGE("cellInfoListInd: invalid response"); - return 0; - } - - hidl_vec<CellInfo> records; - convertRilCellInfoListToHal(response, responseLen, records); - -#if VDBG - RLOGD("cellInfoListInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->cellInfoList( - convertIntToRadioIndicationType(indicationType), records); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("cellInfoListInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::imsNetworkStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { -#if VDBG - RLOGD("imsNetworkStateChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->imsNetworkStateChanged( - convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("imsNetworkStateChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::subscriptionStatusChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("subscriptionStatusChangedInd: invalid response"); - return 0; - } - bool activate = ((int32_t *) response)[0]; -#if VDBG - RLOGD("subscriptionStatusChangedInd: activate %d", activate); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->subscriptionStatusChanged( - convertIntToRadioIndicationType(indicationType), activate); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("subscriptionStatusChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::srvccStateNotifyInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(int)) { - RLOGE("srvccStateNotifyInd: invalid response"); - return 0; - } - int32_t state = ((int32_t *) response)[0]; -#if VDBG - RLOGD("srvccStateNotifyInd: rat %d", state); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->srvccStateNotify( - convertIntToRadioIndicationType(indicationType), (SrvccState) state); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("srvccStateNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -void convertRilHardwareConfigListToHal(void *response, size_t responseLen, - hidl_vec<HardwareConfig>& records) { - int num = responseLen / sizeof(RIL_HardwareConfig); - records.resize(num); - - RIL_HardwareConfig *rilHardwareConfig = (RIL_HardwareConfig *) response; - for (int i = 0; i < num; i++) { - records[i].type = (HardwareConfigType) rilHardwareConfig[i].type; - records[i].uuid = convertCharPtrToHidlString(rilHardwareConfig[i].uuid); - records[i].state = (HardwareConfigState) rilHardwareConfig[i].state; - switch (rilHardwareConfig[i].type) { - case RIL_HARDWARE_CONFIG_MODEM: { - records[i].modem.resize(1); - records[i].sim.resize(0); - HardwareConfigModem *hwConfigModem = &records[i].modem[0]; - hwConfigModem->rat = rilHardwareConfig[i].cfg.modem.rat; - hwConfigModem->maxVoice = rilHardwareConfig[i].cfg.modem.maxVoice; - hwConfigModem->maxData = rilHardwareConfig[i].cfg.modem.maxData; - hwConfigModem->maxStandby = rilHardwareConfig[i].cfg.modem.maxStandby; - break; - } - - case RIL_HARDWARE_CONFIG_SIM: { - records[i].sim.resize(1); - records[i].modem.resize(0); - records[i].sim[0].modemUuid = - convertCharPtrToHidlString(rilHardwareConfig[i].cfg.sim.modemUuid); - break; - } - } - } -} - -int radio_1_5::hardwareConfigChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if ((response == NULL && responseLen != 0) - || responseLen % sizeof(RIL_HardwareConfig) != 0) { - RLOGE("hardwareConfigChangedInd: invalid response"); - return 0; - } - - hidl_vec<HardwareConfig> configs; - convertRilHardwareConfigListToHal(response, responseLen, configs); - -#if VDBG - RLOGD("hardwareConfigChangedInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->hardwareConfigChanged( - convertIntToRadioIndicationType(indicationType), configs); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("hardwareConfigChangedInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc) { - RIL_RadioCapability *rilRadioCapability = (RIL_RadioCapability *) response; - rc.session = rilRadioCapability->session; - rc.phase = (V1_0::RadioCapabilityPhase) rilRadioCapability->phase; - rc.raf = rilRadioCapability->rat; - rc.logicalModemUuid = convertCharPtrToHidlString(rilRadioCapability->logicalModemUuid); - rc.status = (V1_0::RadioCapabilityStatus) rilRadioCapability->status; -} - -int radio_1_5::radioCapabilityIndicationInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { - RLOGE("radioCapabilityIndicationInd: invalid response"); - return 0; - } - - RadioCapability rc = {}; - convertRilRadioCapabilityToHal(response, responseLen, rc); - -#if VDBG - RLOGD("radioCapabilityIndicationInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->radioCapabilityIndication( - convertIntToRadioIndicationType(indicationType), rc); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("radioCapabilityIndicationInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) { - if ((reqType == SS_INTERROGATION) && - (serType == SS_CFU || - serType == SS_CF_BUSY || - serType == SS_CF_NO_REPLY || - serType == SS_CF_NOT_REACHABLE || - serType == SS_CF_ALL || - serType == SS_CF_ALL_CONDITIONAL)) { - return true; - } - return false; -} - -int radio_1_5::onSupplementaryServiceIndicationInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_StkCcUnsolSsResponse)) { - RLOGE("onSupplementaryServiceIndicationInd: invalid response"); - return 0; - } - - RIL_StkCcUnsolSsResponse *rilSsResponse = (RIL_StkCcUnsolSsResponse *) response; - StkCcUnsolSsResult ss = {}; - ss.serviceType = (SsServiceType) rilSsResponse->serviceType; - ss.requestType = (SsRequestType) rilSsResponse->requestType; - ss.teleserviceType = (SsTeleserviceType) rilSsResponse->teleserviceType; - ss.serviceClass = rilSsResponse->serviceClass; - ss.result = (RadioError) rilSsResponse->result; - - if (isServiceTypeCfQuery(rilSsResponse->serviceType, rilSsResponse->requestType)) { -#if VDBG - RLOGD("onSupplementaryServiceIndicationInd CF type, num of Cf elements %d", - rilSsResponse->cfData.numValidIndexes); -#endif - if (rilSsResponse->cfData.numValidIndexes > NUM_SERVICE_CLASSES) { - RLOGE("onSupplementaryServiceIndicationInd numValidIndexes is greater than " - "max value %d, truncating it to max value", NUM_SERVICE_CLASSES); - rilSsResponse->cfData.numValidIndexes = NUM_SERVICE_CLASSES; - } - - ss.cfData.resize(1); - ss.ssInfo.resize(0); - - /* number of call info's */ - ss.cfData[0].cfInfo.resize(rilSsResponse->cfData.numValidIndexes); - - for (int i = 0; i < rilSsResponse->cfData.numValidIndexes; i++) { - RIL_CallForwardInfo cf = rilSsResponse->cfData.cfInfo[i]; - CallForwardInfo *cfInfo = &ss.cfData[0].cfInfo[i]; - - cfInfo->status = (CallForwardInfoStatus) cf.status; - cfInfo->reason = cf.reason; - cfInfo->serviceClass = cf.serviceClass; - cfInfo->toa = cf.toa; - cfInfo->number = convertCharPtrToHidlString(cf.number); - cfInfo->timeSeconds = cf.timeSeconds; -#if VDBG - RLOGD("onSupplementaryServiceIndicationInd: " - "Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status, - cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds); -#endif - } - } else { - ss.ssInfo.resize(1); - ss.cfData.resize(0); - - /* each int */ - ss.ssInfo[0].ssInfo.resize(SS_INFO_MAX); - for (int i = 0; i < SS_INFO_MAX; i++) { -#if VDBG - RLOGD("onSupplementaryServiceIndicationInd: Data: %d", - rilSsResponse->ssInfo[i]); -#endif - ss.ssInfo[0].ssInfo[i] = rilSsResponse->ssInfo[i]; - } - } - -#if VDBG - RLOGD("onSupplementaryServiceIndicationInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication-> - onSupplementaryServiceIndication(convertIntToRadioIndicationType(indicationType), - ss); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("onSupplementaryServiceIndicationInd: " - "radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::stkCallControlAlphaNotifyInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("stkCallControlAlphaNotifyInd: invalid response"); - return 0; - } -#if VDBG - RLOGD("stkCallControlAlphaNotifyInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallControlAlphaNotify( - convertIntToRadioIndicationType(indicationType), - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("stkCallControlAlphaNotifyInd: radioService[%d]->mRadioIndication == NULL", - slotId); - } - - return 0; -} - -void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce) { - RIL_LceDataInfo *rilLceDataInfo = (RIL_LceDataInfo *)response; - lce.lastHopCapacityKbps = rilLceDataInfo->last_hop_capacity_kbps; - lce.confidenceLevel = rilLceDataInfo->confidence_level; - lce.lceSuspended = rilLceDataInfo->lce_suspended; -} - -int radio_1_5::lceDataInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { - RLOGE("lceDataInd: invalid response"); - return 0; - } - - LceDataInfo lce = {}; - convertRilLceDataInfoToHal(response, responseLen, lce); -#if VDBG - RLOGD("lceDataInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->lceData( - convertIntToRadioIndicationType(indicationType), lce); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("lceDataInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::pcoDataInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen != sizeof(RIL_PCO_Data)) { - RLOGE("pcoDataInd: invalid response"); - return 0; - } - - PcoDataInfo pco = {}; - RIL_PCO_Data *rilPcoData = (RIL_PCO_Data *)response; - pco.cid = rilPcoData->cid; - pco.bearerProto = convertCharPtrToHidlString(rilPcoData->bearer_proto); - pco.pcoId = rilPcoData->pco_id; - pco.contents.setToExternal((uint8_t *) rilPcoData->contents, rilPcoData->contents_length); - -#if VDBG - RLOGD("pcoDataInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->pcoData( - convertIntToRadioIndicationType(indicationType), pco); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("pcoDataInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::modemResetInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("modemResetInd: invalid response"); - return 0; - } -#if VDBG - RLOGD("modemResetInd"); -#endif - Return<void> retStatus = radioService[slotId]->mRadioIndication->modemReset( - convertIntToRadioIndicationType(indicationType), - convertCharPtrToHidlString((char *) response)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("modemResetInd: radioService[%d]->mRadioIndication == NULL", slotId); - } - - return 0; -} - -int radio_1_5::networkScanResultInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("networkScanResultInd"); -#endif - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_4 != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("networkScanResultInd: invalid response"); - return 0; - } - RLOGD("networkScanResultInd"); - -#if VDBG - RLOGD("networkScanResultInd"); -#endif - - RIL_NetworkScanResult *networkScanResult = (RIL_NetworkScanResult *) response; - - V1_1::NetworkScanResult result; - result.status = (V1_1::ScanStatus) networkScanResult->status; - result.error = (RadioError) networkScanResult->error; - convertRilCellInfoListToHal( - networkScanResult->network_infos, - networkScanResult->network_infos_length * sizeof(RIL_CellInfo_v12), - result.networkInfos); - - Return<void> retStatus = radioService[slotId]->mRadioIndicationV1_4->networkScanResult( - convertIntToRadioIndicationType(indicationType), result); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("networkScanResultInd: radioService[%d]->mRadioIndicationV1_4 == NULL", slotId); - } - return 0; -} - -int radio_1_5::carrierInfoForImsiEncryption(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_4 != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("carrierInfoForImsiEncryption: invalid response"); - return 0; - } - RLOGD("carrierInfoForImsiEncryption"); - Return<void> retStatus = radioService[slotId]->mRadioIndicationV1_4-> - carrierInfoForImsiEncryption(convertIntToRadioIndicationType(indicationType)); - radioService[slotId]->checkReturnStatus(retStatus); - } else { - RLOGE("carrierInfoForImsiEncryption: radioService[%d]->mRadioIndicationV1_4 == NULL", - slotId); - } - - return 0; -} - -int radio_1_5::keepaliveStatusInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { -#if VDBG - RLOGD("%s(): token=%d", __FUNCTION__, token); -#endif - if (radioService[slotId] == NULL || radioService[slotId]->mRadioIndication == NULL) { - RLOGE("%s: radioService[%d]->mRadioIndication == NULL", __FUNCTION__, slotId); - return 0; - } - - auto ret = V1_1::IRadioIndication::castFrom( - radioService[slotId]->mRadioIndication); - if (!ret.isOk()) { - RLOGE("%s: ret.isOk() == false for radioService[%d]", __FUNCTION__, slotId); - return 0; - } - sp<V1_1::IRadioIndication> radioIndicationV1_1 = ret; - - if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) { - RLOGE("%s: invalid response", __FUNCTION__); - return 0; - } - - V1_1::KeepaliveStatus ks; - convertRilKeepaliveStatusToHal(static_cast<RIL_KeepaliveStatus*>(response), ks); - - Return<void> retStatus = radioIndicationV1_1->keepaliveStatus( - convertIntToRadioIndicationType(indicationType), ks); - radioService[slotId]->checkReturnStatus(retStatus); - return 0; -} - -int radio_1_5::oemHookRawInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen) { - if (!kOemHookEnabled) return 0; - - if (oemHookService[slotId] != NULL && oemHookService[slotId]->mOemHookIndication != NULL) { - if (response == NULL || responseLen == 0) { - RLOGE("oemHookRawInd: invalid response"); - return 0; - } - - hidl_vec<uint8_t> data; - data.setToExternal((uint8_t *) response, responseLen); -#if VDBG - RLOGD("oemHookRawInd"); -#endif - Return<void> retStatus = oemHookService[slotId]->mOemHookIndication->oemHookRaw( - convertIntToRadioIndicationType(indicationType), data); - checkReturnStatus(slotId, retStatus, false); - } else { - RLOGE("oemHookRawInd: oemHookService[%d]->mOemHookIndication == NULL", slotId); - } - - return 0; -} - -void radio_1_5::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) { - using namespace android::hardware; - int simCount = 1; - const char *serviceNames[] = { - android::RIL_getServiceName() - #if (SIM_COUNT >= 2) - , RIL2_SERVICE_NAME - #if (SIM_COUNT >= 3) - , RIL3_SERVICE_NAME - #if (SIM_COUNT >= 4) - , RIL4_SERVICE_NAME - #endif - #endif - #endif - }; - - #if (SIM_COUNT >= 2) - simCount = SIM_COUNT; - #endif - - s_vendorFunctions = callbacks; - s_commands = commands; - - configureRpcThreadpool(1, true /* callerWillJoin */); - for (int i = 0; i < simCount; i++) { - pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i); - int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); - assert(ret == 0); - - RLOGD("sim i = %d registering ...", i); - - radioService[i] = new RadioImpl_1_5; - radioService[i]->mSlotId = i; - RLOGD("registerService: starting android::hardware::radio::V1_5::IRadio %s for slot %d", - serviceNames[i], i); - android::status_t status = radioService[i]->registerAsService(serviceNames[i]); - assert(status == android::OK); - - RLOGD("registerService: OemHook is enabled = %s", kOemHookEnabled ? "true" : "false"); - if (kOemHookEnabled) { - oemHookService[i] = new OemHookImpl; - oemHookService[i]->mSlotId = i; - // status = oemHookService[i]->registerAsService(serviceNames[i]); - } - - ret = pthread_rwlock_unlock(radioServiceRwlockPtr); - assert(ret == 0); - } -} - -void rilc_thread_pool() { - joinRpcThreadpool(); -} - -pthread_rwlock_t * radio_1_5::getRadioServiceRwlock(int slotId) { - pthread_rwlock_t *radioServiceRwlockPtr = &radioServiceRwlock; - - #if (SIM_COUNT >= 2) - if (slotId == 2) radioServiceRwlockPtr = &radioServiceRwlock2; - #if (SIM_COUNT >= 3) - if (slotId == 3) radioServiceRwlockPtr = &radioServiceRwlock3; - #if (SIM_COUNT >= 4) - if (slotId == 4) radioServiceRwlockPtr = &radioServiceRwlock4; - #endif - #endif - #endif - - return radioServiceRwlockPtr; -} - -// should acquire write lock for the corresponding service before calling this -void radio_1_5::setNitzTimeReceived(int slotId, long timeReceived) { - nitzTimeReceived[slotId] = timeReceived; -} diff --git a/guest/hals/ril/libril/ril_service.h b/guest/hals/ril/libril/ril_service.h deleted file mode 100644 index 814768ca..00000000 --- a/guest/hals/ril/libril/ril_service.h +++ /dev/null @@ -1,811 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#ifndef RIL_SERVICE_H -#define RIL_SERVICE_H - -#include <guest/hals/ril/libril/ril.h> -#include <ril_internal.h> - -namespace radio_1_5 { -void registerService(RIL_RadioFunctions *callbacks, android::CommandInfo *commands); - -int getIccCardStatusResponse(int slotId, int responseType, - int token, RIL_Errno e, void *response, size_t responselen); - -int supplyIccPinForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int supplyIccPukForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int supplyIccPin2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int supplyIccPuk2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int changeIccPinForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int changeIccPin2ForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int supplyNetworkDepersonalizationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getCurrentCallsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int dialResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, size_t responselen); - -int getIMSIForAppResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responselen); - -int hangupConnectionResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responselen); - -int hangupWaitingOrBackgroundResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int hangupForegroundResumeBackgroundResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int switchWaitingOrHoldingAndActiveResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int conferenceResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responselen); - -int rejectCallResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responselen); - -int getLastCallFailCauseResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getSignalStrengthResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int getVoiceRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getDataRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getOperatorResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setRadioPowerResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendSMSExpectMoreResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setupDataCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responseLen); - -int iccIOForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendUssdResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int cancelPendingUssdResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getClirResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, size_t responselen); - -int setClirResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, size_t responselen); - -int getCallForwardStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCallForwardResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getCallWaitingResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCallWaitingResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int acknowledgeLastIncomingGsmSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int acceptCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int deactivateDataCallResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getFacilityLockForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setFacilityLockForAppResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setBarringPasswordResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getNetworkSelectionModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setNetworkSelectionModeAutomaticResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setNetworkSelectionModeManualResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getAvailableNetworksResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int startNetworkScanResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int startNetworkScanResponse4(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int startNetworkScanResponse_1_5(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int stopNetworkScanResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int startDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int stopDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getBasebandVersionResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int separateConnectionResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setMuteResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getMuteResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getClipResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getDataCallListResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setSuppServiceNotificationsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int writeSmsToSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int deleteSmsOnSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setBandModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getAvailableBandModesResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendEnvelopeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendTerminalResponseToSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int handleStkCallSetupRequestFromSimResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int explicitCallTransferResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setPreferredNetworkTypeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getPreferredNetworkTypeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setPreferredNetworkTypeBitmapResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getPreferredNetworkTypeBitmapResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getNeighboringCidsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setLocationUpdatesResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCdmaSubscriptionSourceResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCdmaRoamingPreferenceResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getCdmaRoamingPreferenceResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setTTYModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getTTYModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setPreferredVoicePrivacyResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getPreferredVoicePrivacyResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendCDMAFeatureCodeResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int sendBurstDtmfResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int sendCdmaSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int acknowledgeLastIncomingCdmaSmsResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getGsmBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setGsmBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setGsmBroadcastActivationResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getCdmaBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCdmaBroadcastConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCdmaBroadcastActivationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getCDMASubscriptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int writeSmsToRuimResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int deleteSmsOnRuimResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getDeviceIdentityResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int exitEmergencyCallbackModeResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getSmscAddressResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int setCdmaBroadcastActivationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setSmscAddressResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int reportSmsMemoryStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int reportStkServiceIsRunningResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int getCdmaSubscriptionSourceResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int requestIsimAuthenticationResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int acknowledgeIncomingGsmSmsWithPduResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int sendEnvelopeWithStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - -int getVoiceRadioTechnologyResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getCellInfoListResponse(int slotId, - int responseType, - int serial, RIL_Errno e, void *response, - size_t responseLen); - -int setCellInfoListRateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setInitialAttachApnResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getImsRegistrationStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int sendImsSmsResponse(int slotId, int responseType, - int serial, RIL_Errno e, void *response, size_t responselen); - -int iccTransmitApduBasicChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int iccOpenLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, void *response, - size_t responselen); - - -int iccCloseLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int iccTransmitApduLogicalChannelResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int nvReadItemResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - - -int nvWriteItemResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int nvWriteCdmaPrlResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int nvResetConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setUiccSubscriptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setDataAllowedResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getHardwareConfigResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int requestIccSimAuthenticationResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setDataProfileResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int requestShutdownResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getRadioCapabilityResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setRadioCapabilityResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int startLceServiceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int stopLceServiceResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int pullLceDataResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int getModemActivityInfoResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getModemStackStatusResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int enableModemResponse(int slotId, int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setAllowedCarriersResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int getAllowedCarriersResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int sendDeviceStateResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setIndicationFilterResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int setSimCardPowerResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int startKeepaliveResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int stopKeepaliveResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -void acknowledgeRequest(int slotId, int serial); - -int radioStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responseLen); - -int callStateChangedInd(int slotId, int indType, int token, - RIL_Errno e, void *response, size_t responselen); - -int networkStateChangedInd(int slotId, int indType, - int token, RIL_Errno e, void *response, size_t responselen); - -int newSmsInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int newSmsStatusReportInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int newSmsOnSimInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int onUssdInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int nitzTimeReceivedInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int currentSignalStrengthInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responselen); - -int dataCallListChangedInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int suppSvcNotifyInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int stkSessionEndInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int stkProactiveCommandInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int stkEventNotifyInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int stkCallSetupInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int simSmsStorageFullInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int simRefreshInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int callRingInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int simStatusChangedInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int cdmaNewSmsInd(int slotId, int indicationType, - int token, RIL_Errno e, void *response, size_t responselen); - -int newBroadcastSmsInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cdmaRuimSmsStorageFullInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int restrictedStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int enterEmergencyCallbackModeInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cdmaCallWaitingInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cdmaOtaProvisionStatusInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cdmaInfoRecInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int oemHookRawInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int indicateRingbackToneInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int resendIncallMuteInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cdmaSubscriptionSourceChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responselen); - -int cdmaPrlChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int exitEmergencyCallbackModeInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int rilConnectedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int voiceRadioTechChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int cellInfoListInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int imsNetworkStateChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int subscriptionStatusChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int srvccStateNotifyInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int hardwareConfigChangedInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int radioCapabilityIndicationInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int onSupplementaryServiceIndicationInd(int slotId, - int indicationType, int token, RIL_Errno e, - void *response, size_t responselen); - -int stkCallControlAlphaNotifyInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int lceDataInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int pcoDataInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int modemResetInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int networkScanResultInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int keepaliveStatusInd(int slotId, - int indicationType, int token, RIL_Errno e, void *response, - size_t responselen); - -int sendRequestRawResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int sendRequestStringsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setCarrierInfoForImsiEncryptionResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int emergencyDialResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int carrierInfoForImsiEncryption(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setSystemSelectionChannelsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setSystemSelectionChannelsResponse_1_5(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responseLen); - -int setAllowedCarriersResponse4(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, - size_t responselen); - -int getAllowedCarriersResponse4(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, - size_t responselen); - -int setSignalStrengthReportingCriteriaResponse_1_5(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int enableUiccApplicationsResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int areUiccApplicationsEnabledResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -int canToggleUiccApplicationsEnablementResponse(int slotId, - int responseType, int serial, RIL_Errno e, - void *response, size_t responselen); - -pthread_rwlock_t * getRadioServiceRwlock(int slotId); - -void setNitzTimeReceived(int slotId, long timeReceived); - -} // namespace radio - -#endif // RIL_SERVICE_H diff --git a/guest/hals/ril/libril/ril_unsol_commands.h b/guest/hals/ril/libril/ril_unsol_commands.h deleted file mode 100644 index 89c1f558..00000000 --- a/guest/hals/ril/libril/ril_unsol_commands.h +++ /dev/null @@ -1,66 +0,0 @@ -/* ///guest/hals/ril/libril/ril_unsol_commands.h -** -** Copyright 2006, 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. -*/ - {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, radio_1_5::radioStateChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, radio_1_5::callStateChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, radio_1_5::networkStateChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS, radio_1_5::newSmsInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, radio_1_5::newSmsStatusReportInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, radio_1_5::newSmsOnSimInd, WAKE_PARTIAL}, - {RIL_UNSOL_ON_USSD, radio_1_5::onUssdInd, WAKE_PARTIAL}, - {RIL_UNSOL_ON_USSD_REQUEST, radio_1_5::onUssdInd, DONT_WAKE}, - {RIL_UNSOL_NITZ_TIME_RECEIVED, radio_1_5::nitzTimeReceivedInd, WAKE_PARTIAL}, - {RIL_UNSOL_SIGNAL_STRENGTH, radio_1_5::currentSignalStrengthInd, DONT_WAKE}, - {RIL_UNSOL_DATA_CALL_LIST_CHANGED, radio_1_5::dataCallListChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_SUPP_SVC_NOTIFICATION, radio_1_5::suppSvcNotifyInd, WAKE_PARTIAL}, - {RIL_UNSOL_STK_SESSION_END, radio_1_5::stkSessionEndInd, WAKE_PARTIAL}, - {RIL_UNSOL_STK_PROACTIVE_COMMAND, radio_1_5::stkProactiveCommandInd, WAKE_PARTIAL}, - {RIL_UNSOL_STK_EVENT_NOTIFY, radio_1_5::stkEventNotifyInd, WAKE_PARTIAL}, - {RIL_UNSOL_STK_CALL_SETUP, radio_1_5::stkCallSetupInd, WAKE_PARTIAL}, - {RIL_UNSOL_SIM_SMS_STORAGE_FULL, radio_1_5::simSmsStorageFullInd, WAKE_PARTIAL}, - {RIL_UNSOL_SIM_REFRESH, radio_1_5::simRefreshInd, WAKE_PARTIAL}, - {RIL_UNSOL_CALL_RING, radio_1_5::callRingInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, radio_1_5::simStatusChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, radio_1_5::cdmaNewSmsInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, radio_1_5::newBroadcastSmsInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, radio_1_5::cdmaRuimSmsStorageFullInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESTRICTED_STATE_CHANGED, radio_1_5::restrictedStateChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, radio_1_5::enterEmergencyCallbackModeInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_CALL_WAITING, radio_1_5::cdmaCallWaitingInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, radio_1_5::cdmaOtaProvisionStatusInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_INFO_REC, radio_1_5::cdmaInfoRecInd, WAKE_PARTIAL}, - {RIL_UNSOL_OEM_HOOK_RAW, radio_1_5::oemHookRawInd, WAKE_PARTIAL}, - {RIL_UNSOL_RINGBACK_TONE, radio_1_5::indicateRingbackToneInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESEND_INCALL_MUTE, radio_1_5::resendIncallMuteInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, radio_1_5::cdmaSubscriptionSourceChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_CDMA_PRL_CHANGED, radio_1_5::cdmaPrlChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, radio_1_5::exitEmergencyCallbackModeInd, WAKE_PARTIAL}, - {RIL_UNSOL_RIL_CONNECTED, radio_1_5::rilConnectedInd, WAKE_PARTIAL}, - {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, radio_1_5::voiceRadioTechChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_CELL_INFO_LIST, radio_1_5::cellInfoListInd, WAKE_PARTIAL}, - {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, radio_1_5::imsNetworkStateChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, radio_1_5::subscriptionStatusChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_SRVCC_STATE_NOTIFY, radio_1_5::srvccStateNotifyInd, WAKE_PARTIAL}, - {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, radio_1_5::hardwareConfigChangedInd, WAKE_PARTIAL}, - {RIL_UNSOL_DC_RT_INFO_CHANGED, NULL, WAKE_PARTIAL}, - {RIL_UNSOL_RADIO_CAPABILITY, radio_1_5::radioCapabilityIndicationInd, WAKE_PARTIAL}, - {RIL_UNSOL_ON_SS, radio_1_5::onSupplementaryServiceIndicationInd, WAKE_PARTIAL}, - {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, radio_1_5::stkCallControlAlphaNotifyInd, WAKE_PARTIAL}, - {RIL_UNSOL_LCEDATA_RECV, radio_1_5::lceDataInd, WAKE_PARTIAL}, - {RIL_UNSOL_PCO_DATA, radio_1_5::pcoDataInd, WAKE_PARTIAL}, - {RIL_UNSOL_MODEM_RESTART, radio_1_5::modemResetInd, WAKE_PARTIAL}, - {RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, radio_1_5::carrierInfoForImsiEncryption, WAKE_PARTIAL}, - {RIL_UNSOL_NETWORK_SCAN_RESULT, radio_1_5::networkScanResultInd, WAKE_PARTIAL}, diff --git a/guest/hals/ril/libril/sap_service.cpp b/guest/hals/ril/libril/sap_service.cpp deleted file mode 100644 index cd5b1378..00000000 --- a/guest/hals/ril/libril/sap_service.cpp +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright (c) 2016 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. - */ - -#define LOG_TAG "RIL_SAP" - -#include <android/hardware/radio/1.1/ISap.h> - -#include <hwbinder/IPCThreadState.h> -#include <hwbinder/ProcessState.h> -#include <sap_service.h> -#include "pb_decode.h" -#include "pb_encode.h" - -using namespace android::hardware::radio::V1_0; -using ::android::hardware::Return; -using ::android::hardware::hidl_vec; -using ::android::hardware::hidl_array; -using ::android::hardware::Void; -using android::CommandInfo; -using android::RequestInfo; -using android::requestToString; -using android::sp; - -struct SapImpl; - -#if (SIM_COUNT >= 2) -sp<SapImpl> sapService[SIM_COUNT]; -#else -sp<SapImpl> sapService[1]; -#endif - -struct SapImpl : public android::hardware::radio::V1_1::ISap { - int32_t slotId; - sp<ISapCallback> sapCallback; - RIL_SOCKET_ID rilSocketId; - - Return<void> setCallback(const ::android::sp<ISapCallback>& sapCallbackParam); - - Return<void> connectReq(int32_t token, int32_t maxMsgSize); - - Return<void> disconnectReq(int32_t token); - - Return<void> apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& command); - - Return<void> transferAtrReq(int32_t token); - - Return<void> powerReq(int32_t token, bool state); - - Return<void> resetSimReq(int32_t token); - - Return<void> transferCardReaderStatusReq(int32_t token); - - Return<void> setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol); - - MsgHeader* createMsgHeader(MsgId msgId, int32_t token); - - Return<void> addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, uint8_t *reqPtr); - - void sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...); - - void checkReturnStatus(Return<void>& ret); -}; - -void SapImpl::checkReturnStatus(Return<void>& ret) { - if (ret.isOk() == false) { - RLOGE("checkReturnStatus: unable to call response/indication callback: %s", - ret.description().c_str()); - // Remote process (SapRilReceiver.java) hosting the callback must be dead. Reset the - // callback object; there's no other recovery to be done here. When the client process is - // back up, it will call setCallback() - sapCallback = NULL; - } -} - -Return<void> SapImpl::setCallback(const ::android::sp<ISapCallback>& sapCallbackParam) { - RLOGD("SapImpl::setCallback for slotId %d", slotId); - sapCallback = sapCallbackParam; - return Void(); -} - -MsgHeader* SapImpl::createMsgHeader(MsgId msgId, int32_t token) { - // Memory for msg will be freed by RilSapSocket::onRequestComplete() - MsgHeader *msg = (MsgHeader *)calloc(1, sizeof(MsgHeader)); - if (msg == NULL) { - return NULL; - } - msg->token = token; - msg->type = MsgType_REQUEST; - msg->id = msgId; - msg->error = Error_RIL_E_SUCCESS; - return msg; -} - -Return<void> SapImpl::addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, - uint8_t *reqPtr) { - pb_bytes_array_t *payload = (pb_bytes_array_t *) malloc(sizeof(pb_bytes_array_t) - 1 + reqLen); - if (payload == NULL) { - sendFailedResponse(msg->id, msg->token, 2, reqPtr, msg); - return Void(); - } - - msg->payload = payload; - msg->payload->size = reqLen; - memcpy(msg->payload->bytes, reqPtr, reqLen); - - RilSapSocket *sapSocket = RilSapSocket::getSocketById(rilSocketId); - if (sapSocket) { - RLOGD("SapImpl::addPayloadAndDispatchRequest: calling dispatchRequest"); - sapSocket->dispatchRequest(msg); - } else { - RLOGE("SapImpl::addPayloadAndDispatchRequest: sapSocket is null"); - sendFailedResponse(msg->id, msg->token, 3, payload, reqPtr, msg); - return Void(); - } - free(msg->payload); - free(reqPtr); - return Void(); -} - -void SapImpl::sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...) { - va_list ap; - va_start(ap, numPointers); - for (int i = 0; i < numPointers; i++) { - void *ptr = va_arg(ap, void *); - if (ptr) free(ptr); - } - va_end(ap); - Return<void> retStatus; - switch(msgId) { - case MsgId_RIL_SIM_SAP_CONNECT: - retStatus = sapCallback->connectResponse(token, SapConnectRsp::CONNECT_FAILURE, 0); - break; - - case MsgId_RIL_SIM_SAP_DISCONNECT: - retStatus = sapCallback->disconnectResponse(token); - break; - - case MsgId_RIL_SIM_SAP_APDU: { - hidl_vec<uint8_t> apduRsp; - retStatus = sapCallback->apduResponse(token, SapResultCode::GENERIC_FAILURE, apduRsp); - break; - } - - case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { - hidl_vec<uint8_t> atr; - retStatus = sapCallback->transferAtrResponse(token, SapResultCode::GENERIC_FAILURE, - atr); - break; - } - - case MsgId_RIL_SIM_SAP_POWER: - retStatus = sapCallback->powerResponse(token, SapResultCode::GENERIC_FAILURE); - break; - - case MsgId_RIL_SIM_SAP_RESET_SIM: - retStatus = sapCallback->resetSimResponse(token, SapResultCode::GENERIC_FAILURE); - break; - - case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: - retStatus = sapCallback->transferCardReaderStatusResponse(token, - SapResultCode::GENERIC_FAILURE, 0); - break; - - case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: - retStatus = sapCallback->transferProtocolResponse(token, SapResultCode::NOT_SUPPORTED); - break; - - default: - return; - } - sapService[slotId]->checkReturnStatus(retStatus); -} - -Return<void> SapImpl::connectReq(int32_t token, int32_t maxMsgSize) { - RLOGD("SapImpl::connectReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_CONNECT, token); - if (msg == NULL) { - RLOGE("SapImpl::connectReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_CONNECT_REQ *****/ - RIL_SIM_SAP_CONNECT_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_CONNECT_REQ)); - req.max_message_size = maxMsgSize; - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { - RLOGE("SapImpl::connectReq: Error getting encoded size for RIL_SIM_SAP_CONNECT_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::connectReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); - return Void(); - } - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::connectReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { - RLOGE("SapImpl::connectReq: Error encoding RIL_SIM_SAP_CONNECT_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_CONNECT_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::disconnectReq(int32_t token) { - RLOGD("SapImpl::disconnectReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_DISCONNECT, token); - if (msg == NULL) { - RLOGE("SapImpl::disconnectReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_DISCONNECT_REQ *****/ - RIL_SIM_SAP_DISCONNECT_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_DISCONNECT_REQ)); - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { - RLOGE("SapImpl::disconnectReq: Error getting encoded size for RIL_SIM_SAP_DISCONNECT_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::disconnectReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::disconnectReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { - RLOGE("SapImpl::disconnectReq: Error encoding RIL_SIM_SAP_DISCONNECT_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_DISCONNECT_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& command) { - RLOGD("SapImpl::apduReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_APDU, token); - if (msg == NULL) { - RLOGE("SapImpl::apduReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_APDU_REQ *****/ - RIL_SIM_SAP_APDU_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_APDU_REQ)); - req.type = (RIL_SIM_SAP_APDU_REQ_Type)type; - - if (command.size() > 0) { - req.command = (pb_bytes_array_t *)malloc(sizeof(pb_bytes_array_t) - 1 + command.size()); - if (req.command == NULL) { - RLOGE("SapImpl::apduReq: Error allocating memory for req.command"); - sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 1, msg); - return Void(); - } - req.command->size = command.size(); - memcpy(req.command->bytes, command.data(), command.size()); - } - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_APDU_REQ_fields, &req)) { - RLOGE("SapImpl::apduReq: Error getting encoded size for RIL_SIM_SAP_APDU_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::apduReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::apduReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_APDU_REQ_fields, &req)) { - RLOGE("SapImpl::apduReq: Error encoding RIL_SIM_SAP_APDU_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 3, req.command, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_APDU_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::transferAtrReq(int32_t token) { - RLOGD("SapImpl::transferAtrReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token); - if (msg == NULL) { - RLOGE("SapImpl::transferAtrReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ *****/ - RIL_SIM_SAP_TRANSFER_ATR_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_ATR_REQ)); - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { - RLOGE("SapImpl::transferAtrReq: Error getting encoded size for " - "RIL_SIM_SAP_TRANSFER_ATR_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::transferAtrReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::transferAtrReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { - RLOGE("SapImpl::transferAtrReq: Error encoding RIL_SIM_SAP_TRANSFER_ATR_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::powerReq(int32_t token, bool state) { - RLOGD("SapImpl::powerReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_POWER, token); - if (msg == NULL) { - RLOGE("SapImpl::powerReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_POWER_REQ *****/ - RIL_SIM_SAP_POWER_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_POWER_REQ)); - req.state = state; - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_POWER_REQ_fields, &req)) { - RLOGE("SapImpl::powerReq: Error getting encoded size for RIL_SIM_SAP_POWER_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::powerReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::powerReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_POWER_REQ_fields, &req)) { - RLOGE("SapImpl::powerReq: Error encoding RIL_SIM_SAP_POWER_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_POWER_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::resetSimReq(int32_t token) { - RLOGD("SapImpl::resetSimReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_RESET_SIM, token); - if (msg == NULL) { - RLOGE("SapImpl::resetSimReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_RESET_SIM_REQ *****/ - RIL_SIM_SAP_RESET_SIM_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_RESET_SIM_REQ)); - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { - RLOGE("SapImpl::resetSimReq: Error getting encoded size for RIL_SIM_SAP_RESET_SIM_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::resetSimReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::resetSimReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { - RLOGE("SapImpl::resetSimReq: Error encoding RIL_SIM_SAP_RESET_SIM_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_RESET_SIM_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::transferCardReaderStatusReq(int32_t token) { - RLOGD("SapImpl::transferCardReaderStatusReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token); - if (msg == NULL) { - RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ *****/ - RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ)); - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, - &req)) { - RLOGE("SapImpl::transferCardReaderStatusReq: Error getting encoded size for " - "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::transferCardReaderStatusReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, &req)) { - RLOGE("SapImpl::transferCardReaderStatusReq: Error encoding " - "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -Return<void> SapImpl::setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol) { - RLOGD("SapImpl::setTransferProtocolReq"); - MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token); - if (msg == NULL) { - RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for msg"); - sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 0); - return Void(); - } - - /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ *****/ - RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ req; - memset(&req, 0, sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ)); - req.protocol = (RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_Protocol)transferProtocol; - - size_t encodedSize = 0; - if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { - RLOGE("SapImpl::setTransferProtocolReq: Error getting encoded size for " - "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); - return Void(); - } - - uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); - if (buffer == NULL) { - RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for buffer"); - sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); - return Void(); - } - - pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); - - RLOGD("SapImpl::setTransferProtocolReq calling pb_encode"); - if (!pb_encode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { - RLOGE("SapImpl::setTransferProtocolReq: Error encoding " - "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); - sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 2, buffer, msg); - return Void(); - } - /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ done *****/ - - /* encoded req is payload */ - return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); -} - -void *sapDecodeMessage(MsgId msgId, MsgType msgType, uint8_t *payloadPtr, size_t payloadLen) { - void *responsePtr = NULL; - pb_istream_t stream; - - /* Create the stream */ - stream = pb_istream_from_buffer((uint8_t *)payloadPtr, payloadLen); - - /* Decode based on the message id */ - switch (msgId) - { - case MsgId_RIL_SIM_SAP_CONNECT: - responsePtr = malloc(sizeof(RIL_SIM_SAP_CONNECT_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_CONNECT_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_CONNECT_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_DISCONNECT: - if (msgType == MsgType_RESPONSE) { - responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_RSP"); - return NULL; - } - } - } else { - responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_IND)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_IND_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_IND"); - return NULL; - } - } - } - break; - - case MsgId_RIL_SIM_SAP_APDU: - responsePtr = malloc(sizeof(RIL_SIM_SAP_APDU_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_APDU_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_APDU_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_TRANSFER_ATR: - responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_ATR_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_ATR_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_ATR_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_POWER: - responsePtr = malloc(sizeof(RIL_SIM_SAP_POWER_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_POWER_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_POWER_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_RESET_SIM: - responsePtr = malloc(sizeof(RIL_SIM_SAP_RESET_SIM_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_RESET_SIM_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_RESET_SIM_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_STATUS: - responsePtr = malloc(sizeof(RIL_SIM_SAP_STATUS_IND)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_STATUS_IND_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_STATUS_IND"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: - responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_fields, - responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_ERROR_RESP: - responsePtr = malloc(sizeof(RIL_SIM_SAP_ERROR_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_ERROR_RSP_fields, responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_ERROR_RSP"); - return NULL; - } - } - break; - - case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: - responsePtr = malloc(sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP)); - if (responsePtr) { - if (!pb_decode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_fields, - responsePtr)) { - RLOGE("Error decoding RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP"); - return NULL; - } - } - break; - - default: - break; - } - return responsePtr; -} /* sapDecodeMessage */ - -sp<SapImpl> getSapImpl(RilSapSocket *sapSocket) { - switch (sapSocket->getSocketId()) { - case RIL_SOCKET_1: - RLOGD("getSapImpl: returning sapService[0]"); - return sapService[0]; - #if (SIM_COUNT >= 2) - case RIL_SOCKET_2: - return sapService[1]; - #if (SIM_COUNT >= 3) - case RIL_SOCKET_3: - return sapService[2]; - #if (SIM_COUNT >= 4) - case RIL_SOCKET_4: - return sapService[3]; - #endif - #endif - #endif - default: - return NULL; - } -} - -SapResultCode convertApduResponseProtoToHal(RIL_SIM_SAP_APDU_RSP_Response responseProto) { - switch(responseProto) { - case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SUCCESS: - return SapResultCode::SUCCESS; - case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_GENERIC_FAILURE: - return SapResultCode::GENERIC_FAILURE; - case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_NOT_READY: - return SapResultCode::CARD_NOT_ACCESSSIBLE; - case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: - return SapResultCode::CARD_ALREADY_POWERED_OFF; - case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ABSENT: - return SapResultCode::CARD_REMOVED; - default: - return SapResultCode::GENERIC_FAILURE; - } -} - -SapResultCode convertTransferAtrResponseProtoToHal( - RIL_SIM_SAP_TRANSFER_ATR_RSP_Response responseProto) { - switch(responseProto) { - case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SUCCESS: - return SapResultCode::SUCCESS; - case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_GENERIC_FAILURE: - return SapResultCode::GENERIC_FAILURE; - case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: - return SapResultCode::CARD_ALREADY_POWERED_OFF; - case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ABSENT: - return SapResultCode::CARD_REMOVED; - case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: - return SapResultCode::DATA_NOT_AVAILABLE; - default: - return SapResultCode::GENERIC_FAILURE; - } -} - -SapResultCode convertPowerResponseProtoToHal(RIL_SIM_SAP_POWER_RSP_Response responseProto) { - switch(responseProto) { - case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SUCCESS: - return SapResultCode::SUCCESS; - case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_GENERIC_FAILURE: - return SapResultCode::GENERIC_FAILURE; - case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ABSENT: - return SapResultCode::CARD_REMOVED; - case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: - return SapResultCode::CARD_ALREADY_POWERED_OFF; - case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_ON: - return SapResultCode::CARD_ALREADY_POWERED_ON; - default: - return SapResultCode::GENERIC_FAILURE; - } -} - -SapResultCode convertResetSimResponseProtoToHal(RIL_SIM_SAP_RESET_SIM_RSP_Response responseProto) { - switch(responseProto) { - case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SUCCESS: - return SapResultCode::SUCCESS; - case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_GENERIC_FAILURE: - return SapResultCode::GENERIC_FAILURE; - case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ABSENT: - return SapResultCode::CARD_REMOVED; - case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_NOT_READY: - return SapResultCode::CARD_NOT_ACCESSSIBLE; - case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: - return SapResultCode::CARD_ALREADY_POWERED_OFF; - } - return SapResultCode::GENERIC_FAILURE; -} - -SapResultCode convertTransferCardReaderStatusResponseProtoToHal( - RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response responseProto) { - switch(responseProto) { - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SUCCESS: - return SapResultCode::SUCCESS; - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_GENERIC_FAILURE: - return SapResultCode::GENERIC_FAILURE; - case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: - return SapResultCode::DATA_NOT_AVAILABLE; - } - return SapResultCode::GENERIC_FAILURE; -} - -void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket, MsgType msgType) { - MsgId msgId = rsp->id; - uint8_t *data = rsp->payload->bytes; - size_t dataLen = rsp->payload->size; - - void *messagePtr = sapDecodeMessage(msgId, msgType, data, dataLen); - - sp<SapImpl> sapImpl = getSapImpl(sapSocket); - if (sapImpl->sapCallback == NULL) { - RLOGE("processResponse: sapCallback == NULL; msgId = %d; msgType = %d", - msgId, msgType); - return; - } - - if (messagePtr == NULL) { - RLOGE("processResponse: *messagePtr == NULL; msgId = %d; msgType = %d", - msgId, msgType); - sapImpl->sendFailedResponse(msgId, rsp->token, 0); - return; - } - - RLOGD("processResponse: sapCallback != NULL; msgId = %d; msgType = %d", - msgId, msgType); - - Return<void> retStatus; - switch (msgId) { - case MsgId_RIL_SIM_SAP_CONNECT: { - RIL_SIM_SAP_CONNECT_RSP *connectRsp = (RIL_SIM_SAP_CONNECT_RSP *)messagePtr; - RLOGD("processResponse: calling sapCallback->connectResponse %d %d %d", - rsp->token, - connectRsp->response, - connectRsp->max_message_size); - retStatus = sapImpl->sapCallback->connectResponse(rsp->token, - (SapConnectRsp)connectRsp->response, - connectRsp->max_message_size); - break; - } - - case MsgId_RIL_SIM_SAP_DISCONNECT: - if (msgType == MsgType_RESPONSE) { - RLOGD("processResponse: calling sapCallback->disconnectResponse %d", rsp->token); - retStatus = sapImpl->sapCallback->disconnectResponse(rsp->token); - } else { - RIL_SIM_SAP_DISCONNECT_IND *disconnectInd = - (RIL_SIM_SAP_DISCONNECT_IND *)messagePtr; - RLOGD("processResponse: calling sapCallback->disconnectIndication %d %d", - rsp->token, disconnectInd->disconnectType); - retStatus = sapImpl->sapCallback->disconnectIndication(rsp->token, - (SapDisconnectType)disconnectInd->disconnectType); - } - break; - - case MsgId_RIL_SIM_SAP_APDU: { - RIL_SIM_SAP_APDU_RSP *apduRsp = (RIL_SIM_SAP_APDU_RSP *)messagePtr; - SapResultCode apduResponse = convertApduResponseProtoToHal(apduRsp->response); - RLOGD("processResponse: calling sapCallback->apduResponse %d %d", - rsp->token, apduResponse); - hidl_vec<uint8_t> apduRspVec; - if (apduRsp->apduResponse != NULL && apduRsp->apduResponse->size > 0) { - apduRspVec.setToExternal(apduRsp->apduResponse->bytes, apduRsp->apduResponse->size); - } - retStatus = sapImpl->sapCallback->apduResponse(rsp->token, apduResponse, apduRspVec); - break; - } - - case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { - RIL_SIM_SAP_TRANSFER_ATR_RSP *transferAtrRsp = - (RIL_SIM_SAP_TRANSFER_ATR_RSP *)messagePtr; - SapResultCode transferAtrResponse = - convertTransferAtrResponseProtoToHal(transferAtrRsp->response); - RLOGD("processResponse: calling sapCallback->transferAtrResponse %d %d", - rsp->token, transferAtrResponse); - hidl_vec<uint8_t> transferAtrRspVec; - if (transferAtrRsp->atr != NULL && transferAtrRsp->atr->size > 0) { - transferAtrRspVec.setToExternal(transferAtrRsp->atr->bytes, - transferAtrRsp->atr->size); - } - retStatus = sapImpl->sapCallback->transferAtrResponse(rsp->token, transferAtrResponse, - transferAtrRspVec); - break; - } - - case MsgId_RIL_SIM_SAP_POWER: { - SapResultCode powerResponse = convertPowerResponseProtoToHal( - ((RIL_SIM_SAP_POWER_RSP *)messagePtr)->response); - RLOGD("processResponse: calling sapCallback->powerResponse %d %d", - rsp->token, powerResponse); - retStatus = sapImpl->sapCallback->powerResponse(rsp->token, powerResponse); - break; - } - - case MsgId_RIL_SIM_SAP_RESET_SIM: { - SapResultCode resetSimResponse = convertResetSimResponseProtoToHal( - ((RIL_SIM_SAP_RESET_SIM_RSP *)messagePtr)->response); - RLOGD("processResponse: calling sapCallback->resetSimResponse %d %d", - rsp->token, resetSimResponse); - retStatus = sapImpl->sapCallback->resetSimResponse(rsp->token, resetSimResponse); - break; - } - - case MsgId_RIL_SIM_SAP_STATUS: { - RIL_SIM_SAP_STATUS_IND *statusInd = (RIL_SIM_SAP_STATUS_IND *)messagePtr; - RLOGD("processResponse: calling sapCallback->statusIndication %d %d", - rsp->token, statusInd->statusChange); - retStatus = sapImpl->sapCallback->statusIndication(rsp->token, - (SapStatus)statusInd->statusChange); - break; - } - - case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: { - RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *transferStatusRsp = - (RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *)messagePtr; - SapResultCode transferCardReaderStatusResponse = - convertTransferCardReaderStatusResponseProtoToHal( - transferStatusRsp->response); - RLOGD("processResponse: calling sapCallback->transferCardReaderStatusResponse %d %d %d", - rsp->token, - transferCardReaderStatusResponse, - transferStatusRsp->CardReaderStatus); - retStatus = sapImpl->sapCallback->transferCardReaderStatusResponse(rsp->token, - transferCardReaderStatusResponse, - transferStatusRsp->CardReaderStatus); - break; - } - - case MsgId_RIL_SIM_SAP_ERROR_RESP: { - RLOGD("processResponse: calling sapCallback->errorResponse %d", rsp->token); - retStatus = sapImpl->sapCallback->errorResponse(rsp->token); - break; - } - - case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: { - SapResultCode setTransferProtocolResponse; - if (((RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP *)messagePtr)->response == - RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_Response_RIL_E_SUCCESS) { - setTransferProtocolResponse = SapResultCode::SUCCESS; - } else { - setTransferProtocolResponse = SapResultCode::NOT_SUPPORTED; - } - RLOGD("processResponse: calling sapCallback->transferProtocolResponse %d %d", - rsp->token, setTransferProtocolResponse); - retStatus = sapImpl->sapCallback->transferProtocolResponse(rsp->token, - setTransferProtocolResponse); - break; - } - - default: - return; - } - sapImpl->checkReturnStatus(retStatus); -} - -void sap::processResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { - processResponse(rsp, sapSocket, MsgType_RESPONSE); -} - -void sap::processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { - processResponse(rsp, sapSocket, MsgType_UNSOL_RESPONSE); -} - -void sap::registerService(const RIL_RadioFunctions *callbacks) { - using namespace android::hardware; - int simCount = 1; - const char *serviceNames[] = { - android::RIL_getServiceName() - #if (SIM_COUNT >= 2) - , RIL2_SERVICE_NAME - #if (SIM_COUNT >= 3) - , RIL3_SERVICE_NAME - #if (SIM_COUNT >= 4) - , RIL4_SERVICE_NAME - #endif - #endif - #endif - }; - - RIL_SOCKET_ID socketIds[] = { - RIL_SOCKET_1 - #if (SIM_COUNT >= 2) - , RIL_SOCKET_2 - #if (SIM_COUNT >= 3) - , RIL_SOCKET_3 - #if (SIM_COUNT >= 4) - , RIL_SOCKET_4 - #endif - #endif - #endif - }; - #if (SIM_COUNT >= 2) - simCount = SIM_COUNT; - #endif - - for (int i = 0; i < simCount; i++) { - sapService[i] = new SapImpl; - sapService[i]->slotId = i; - sapService[i]->rilSocketId = socketIds[i]; - RLOGD("registerService: starting ISap %s for slotId %d", serviceNames[i], i); - android::status_t status = sapService[i]->registerAsService(serviceNames[i]); - RLOGD("registerService: started ISap %s status %d", serviceNames[i], status); - } -} diff --git a/guest/hals/rild/Android.mk b/guest/hals/rild/Android.mk deleted file mode 100644 index 01c709bf..00000000 --- a/guest/hals/rild/Android.mk +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (C) 2006 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. - -# only for PLATFORM_VERSION greater or equal to Q -ifeq (true,$(ENABLE_CUTTLEFISH_RILD)) -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - rild_cuttlefish.c - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libdl \ - liblog \ - libril-cuttlefish-fork - -LOCAL_C_INCLUDES += \ - device/google/cuttlefish_common - -# Temporary hack for broken vendor RILs. -LOCAL_WHOLE_STATIC_LIBRARIES := \ - librilutils - -LOCAL_CFLAGS := -DRIL_SHLIB -LOCAL_CFLAGS += -Wall -Wextra -Werror - -LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_PROPRIETARY_MODULE := true -LOCAL_MODULE:= libcuttlefish-rild -LOCAL_OVERRIDES_PACKAGES := rild -PACKAGES.$(LOCAL_MODULE).OVERRIDES := rild -LOCAL_INIT_RC := rild_cuttlefish.rc - -include $(BUILD_EXECUTABLE) -endif diff --git a/guest/hals/rild/rild_cuttlefish.c b/guest/hals/rild/rild_cuttlefish.c deleted file mode 100644 index cfd74fa3..00000000 --- a/guest/hals/rild/rild_cuttlefish.c +++ /dev/null @@ -1,238 +0,0 @@ -/* //device/system/rild/rild.c -** -** Copyright 2006 The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <dlfcn.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include <guest/hals/ril/libril/ril.h> - -#define LOG_TAG "RILD" -#include <log/log.h> -#include <cutils/properties.h> -#include <cutils/sockets.h> -#include <sys/capability.h> -#include <sys/prctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <guest/hals/ril/libril/ril_ex.h> - -#define LIB_PATH_PROPERTY "vendor.rild.libpath" -#define LIB_ARGS_PROPERTY "vendor.rild.libargs" -#define MAX_LIB_ARGS 16 - -static void usage(const char *argv0) { - fprintf(stderr, "Usage: %s -l <ril impl library> [-- <args for impl library>]\n", argv0); - exit(EXIT_FAILURE); -} - -extern char ril_service_name_base[MAX_SERVICE_NAME_LENGTH]; -extern char ril_service_name[MAX_SERVICE_NAME_LENGTH]; - -extern void RIL_register (const RIL_RadioFunctions *callbacks); -extern void rilc_thread_pool (); - -extern void RIL_register_socket (const RIL_RadioFunctions *(*rilUimInit) - (const struct RIL_Env *, int, char **), RIL_SOCKET_TYPE socketType, int argc, char **argv); - -extern void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, - void *response, size_t responselen); - -extern void RIL_onRequestAck(RIL_Token t); - -#if defined(ANDROID_MULTI_SIM) -extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen, RIL_SOCKET_ID socket_id); -#else -extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, - size_t datalen); -#endif - -extern void RIL_requestTimedCallback (RIL_TimedCallback callback, - void *param, const struct timeval *relativeTime); - - -static struct RIL_Env s_rilEnv = { - RIL_onRequestComplete, - RIL_onUnsolicitedResponse, - RIL_requestTimedCallback, - RIL_onRequestAck -}; - -extern void RIL_startEventLoop(); - -static int make_argv(char * args, char ** argv) { - // Note: reserve argv[0] - int count = 1; - char * tok; - char * s = args; - - while ((tok = strtok(s, " \0"))) { - argv[count] = tok; - s = NULL; - count++; - } - return count; -} - -int main(int argc, char **argv) { - // vendor ril lib path either passed in as -l parameter, or read from rild.libpath property - const char *rilLibPath = NULL; - // ril arguments either passed in as -- parameter, or read from rild.libargs property - char **rilArgv; - // handle for vendor ril lib - void *dlHandle; - // Pointer to ril init function in vendor ril - const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **); - // Pointer to sap init function in vendor ril - const RIL_RadioFunctions *(*rilUimInit)(const struct RIL_Env *, int, char **); - const char *err_str = NULL; - - // functions returned by ril init function in vendor ril - const RIL_RadioFunctions *funcs; - // lib path from rild.libpath property (if it's read) - char libPath[PROPERTY_VALUE_MAX]; - // flat to indicate if -- parameters are present - unsigned char hasLibArgs = 0; - - int i; - // ril/socket id received as -c parameter, otherwise set to 0 - const char *clientId = NULL; - - RLOGD("**RIL Daemon Started - Version 1.4**"); - RLOGD("**RILd param count=%d**", argc); - - umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH); - for (i = 1; i < argc ;) { - if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) { - rilLibPath = argv[i + 1]; - i += 2; - } else if (0 == strcmp(argv[i], "--")) { - i++; - hasLibArgs = 1; - break; - } else if (0 == strcmp(argv[i], "-c") && (argc - i > 1)) { - clientId = argv[i+1]; - i += 2; - } else { - usage(argv[0]); - } - } - - if (clientId == NULL) { - clientId = "0"; - } else if (atoi(clientId) >= MAX_RILDS) { - RLOGE("Max Number of rild's supported is: %d", MAX_RILDS); - exit(0); - } - if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) { - snprintf(ril_service_name, sizeof(ril_service_name), "%s%s", ril_service_name_base, - clientId); - } - - if (rilLibPath == NULL) { - if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) { - // No lib sepcified on the command line, and nothing set in props. - // Assume "no-ril" case. - goto done; - } else { - rilLibPath = libPath; - } - } - - dlHandle = dlopen(rilLibPath, RTLD_NOW); - - if (dlHandle == NULL) { - RLOGE("dlopen failed: %s", dlerror()); - exit(EXIT_FAILURE); - } - - RIL_startEventLoop(); - - rilInit = - (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **)) - dlsym(dlHandle, "RIL_Init"); - - if (rilInit == NULL) { - RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath); - exit(EXIT_FAILURE); - } - - dlerror(); // Clear any previous dlerror - rilUimInit = - (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **)) - dlsym(dlHandle, "RIL_SAP_Init"); - err_str = dlerror(); - if (err_str) { - RLOGW("RIL_SAP_Init not defined or exported in %s: %s\n", rilLibPath, err_str); - } else if (!rilUimInit) { - RLOGW("RIL_SAP_Init defined as null in %s. SAP Not usable\n", rilLibPath); - } - - if (hasLibArgs) { - rilArgv = argv + i - 1; - argc = argc -i + 1; - } else { - static char * newArgv[MAX_LIB_ARGS]; - static char args[PROPERTY_VALUE_MAX]; - rilArgv = newArgv; - property_get(LIB_ARGS_PROPERTY, args, ""); - argc = make_argv(args, rilArgv); - } - - rilArgv[argc++] = "-c"; - rilArgv[argc++] = (char*)clientId; - RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]); - - // Make sure there's a reasonable argv[0] - rilArgv[0] = argv[0]; - - funcs = rilInit(&s_rilEnv, argc, rilArgv); - if (funcs == NULL) { - RLOGE("RIL_Init rilInit failed.\n"); - exit(EXIT_FAILURE); - } - - RLOGD("RIL_Init rilInit completed"); - - RLOGD("RIL_Init callback versions = %d", funcs->version); - - RIL_register(funcs); - - RLOGD("RIL_Init RIL_register completed"); - - if (rilUimInit) { - RLOGD("RIL_register_socket started"); - RIL_register_socket(rilUimInit, RIL_SAP_SOCKET, argc, rilArgv); - } - - RLOGD("RIL_register_socket completed"); - -done: - - rilc_thread_pool(); - - RLOGD("RIL_Init starting sleep loop"); - while (true) { - sleep(UINT32_MAX); - } -} diff --git a/guest/hals/rild/rild_cuttlefish.legacy.rc b/guest/hals/rild/rild_cuttlefish.legacy.rc deleted file mode 100644 index e9c2d071..00000000 --- a/guest/hals/rild/rild_cuttlefish.legacy.rc +++ /dev/null @@ -1,5 +0,0 @@ -service ril-daemon /vendor/bin/hw/libcuttlefish-rild - class main - user radio - group radio cache inet misc audio log readproc wakelock - capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW diff --git a/guest/hals/rild/rild_cuttlefish.rc b/guest/hals/rild/rild_cuttlefish.rc deleted file mode 100644 index 9990a7a8..00000000 --- a/guest/hals/rild/rild_cuttlefish.rc +++ /dev/null @@ -1,5 +0,0 @@ -service vendor.ril-daemon /vendor/bin/hw/libcuttlefish-rild - class main - user radio - group radio cache inet misc audio log readproc wakelock - capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW diff --git a/guest/monitoring/Android.bp b/guest/monitoring/Android.bp deleted file mode 100644 index a7f69c0a..00000000 --- a/guest/monitoring/Android.bp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "dumpstate_ext", - "tombstone_transmit", -] diff --git a/guest/monitoring/cuttlefish_service/Android.mk b/guest/monitoring/cuttlefish_service/Android.mk deleted file mode 100644 index 2540ef5d..00000000 --- a/guest/monitoring/cuttlefish_service/Android.mk +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2016 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_CERTIFICATE := platform -LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-java-files-under, java) -LOCAL_STATIC_JAVA_LIBRARIES := guava -LOCAL_PACKAGE_NAME := CuttlefishService -LOCAL_SDK_VERSION := 28 -LOCAL_PROGUARD_FLAGS := -include build/core/proguard.flags -LOCAL_PROGUARD_FLAG_FILES := proguard.flags -LOCAL_PROGUARD_ENABLED := obfuscation -LOCAL_VENDOR_MODULE := true - -include $(BUILD_PACKAGE) diff --git a/guest/monitoring/cuttlefish_service/AndroidManifest.xml b/guest/monitoring/cuttlefish_service/AndroidManifest.xml deleted file mode 100644 index 85abd096..00000000 --- a/guest/monitoring/cuttlefish_service/AndroidManifest.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.google.gce.gceservice" - android:sharedUserId="android.uid.system"> - - <uses-sdk android:minSdkVersion="5" /> - - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - <uses-permission android:name="android.permission.WRITE_SETTINGS" /> - <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> - <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" /> - <uses-permission android:name="android.permission.DUMP" /> - - <application - android:label="GceService" - android:allowBackup="false"> - - <receiver android:name=".GceBroadcastReceiver"> - <intent-filter android:priority="1000"> - <!-- - Do not register for other events here. - Use GceService.registerBroadcastReceivers() instead. - --> - <action android:name="android.intent.action.BOOT_COMPLETED" /> - </intent-filter> - </receiver> - - <service android:name=".GceService"> - <intent-filter> - <action android:name="com.android.google.gce.gceservice.CONFIGURE" /> - <action android:name="com.android.google.gce.gceservice.CONNECTIVITY_CHANGE" /> - <action android:name="com.android.google.gce.gceservice.BLUETOOTH_CHANGED" /> - </intent-filter> - </service> - </application> -</manifest> diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java deleted file mode 100644 index 23d4fec4..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.bluetooth.BluetoothAdapter; -import android.util.Log; - -/* - * A job that checks for Bluetooth being enabled before reporting VIRTUAL_DEVICE_BOOT_COMPLETED. Our - * devices should always boot with bt enabled, it can be configured in - * gce_x86/overlay_<device>/frameworks/base/packages/SettingsProvider/res/values/defaults.xml - */ -public class BluetoothChecker extends JobBase { - private static final String LOG_TAG = "GceBluetoothChecker"; - private final GceFuture<Boolean> mEnabled = new GceFuture<Boolean>("Bluetooth"); - - - public BluetoothChecker() { - super(LOG_TAG); - } - - - @Override - public int execute() { - if (mEnabled.isDone()) { - return 0; - } - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - if (bluetoothAdapter == null) { - Log.e(LOG_TAG, "No bluetooth adapter found"); - mEnabled.set(new Exception("No bluetooth adapter found")); - } else { - if (bluetoothAdapter.isEnabled()) { - Log.i(LOG_TAG, "Bluetooth enabled with name: " + bluetoothAdapter.getName()); - mEnabled.set(true); - } else { - Log.i(LOG_TAG, "Bluetooth disabled with name: " + bluetoothAdapter.getName()); - } - } - return 0; - } - - - @Override - public void onDependencyFailed(Exception e) { - mEnabled.set(e); - } - - - public GceFuture<Boolean> getEnabled() { - return mEnabled; - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java deleted file mode 100644 index b866b356..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.os.Handler; -import android.util.Log; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -/** - * Report boot status to console. - * - * This class sends messages to kernel log (and serial console) directly by - * writing to /dev/kmsg. - */ -public class BootReporter extends JobBase { - private static final String LOG_TAG = "GceBootReporter"; - private static final int KLOG_NOTICE = 5; - private static final String KLOG_OUTPUT = "/dev/kmsg"; - private static final String KLOG_FORMAT = "<%d>%s: %s\n"; - private static final String VIRTUAL_DEVICE_BOOT_STARTED = "VIRTUAL_DEVICE_BOOT_STARTED"; - private static final String VIRTUAL_DEVICE_BOOT_PENDING = "VIRTUAL_DEVICE_BOOT_PENDING"; - private static final String VIRTUAL_DEVICE_BOOT_COMPLETED = "VIRTUAL_DEVICE_BOOT_COMPLETED"; - private static final String VIRTUAL_DEVICE_BOOT_FAILED = "VIRTUAL_DEVICE_BOOT_FAILED"; - private FileOutputStream mKmsgStream = null; - private PrintWriter mKmsgWriter = null; - private List<String> mMessageList = new ArrayList<String>(); - - - /** Constructor. */ - public BootReporter() { - super(LOG_TAG); - - try { - mKmsgStream = new FileOutputStream(KLOG_OUTPUT); - mKmsgWriter = new PrintWriter(mKmsgStream); - } catch (IOException e) { - Log.e(LOG_TAG, "Could not open output stream.", e); - } - } - - - /** Report boot failure. - * - * Send message to kernel log and serial console explaining boot failure. - */ - @Override - public void onDependencyFailed(Exception e) { - reportMessage(String.format("%s: %s", VIRTUAL_DEVICE_BOOT_FAILED, e.getMessage())); - } - - - /** Report straggling jobs. - * - * Reports boot pending, if any of the parent jobs is still awaiting completion - * and reschedules itself for re-execution. - * - * If all jobs have completed, reports boot completed and stops. - */ - @Override - public void onDependencyStraggling(ArrayList<GceFuture<?>> deps) { - reportMessage(String.format("%s: %s", VIRTUAL_DEVICE_BOOT_PENDING, - GceFuture.toString(deps))); - } - - - /** Report successful boot completion. - * - * Issue message to serial port confirming successful boot completion and - * custom boot completion message, if specified by the user prior to reboot. - */ - @Override - public int execute() { - // We suspect that something is throttling our messages and preventing - // the following message from being logged to bugreport. - // The log is present in logcat log (that we collect independently), yet - // occasionally most of the GCEService logs never make it to show up on - // bug report. - // This may or may not prove to be effective. We need to monitor bugreports - // for VIRTUAL_DEVICE_BOOT_COMPLETED messages are being dropped. - // - // Number chosen at random - yet guaranteed to be prime. - try { - Thread.sleep(937); - } catch (InterruptedException e) {} - - reportMessage(VIRTUAL_DEVICE_BOOT_COMPLETED); - return 0; - } - - - public void reportMessage(String message) { - Log.i(LOG_TAG, message); - mKmsgWriter.printf(KLOG_FORMAT, KLOG_NOTICE, LOG_TAG, message); - mKmsgWriter.flush(); - DateFormat df = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); - String date = df.format(Calendar.getInstance().getTime()); - mMessageList.add("[" + date + "] " + message); - } - - - public void reportBootStarted() { - reportMessage(VIRTUAL_DEVICE_BOOT_STARTED); - } - - /** Get the list of reported messages so far. - */ - public List<String> getMessageList() { - return mMessageList; - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java deleted file mode 100644 index 1354021b..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.util.Log; - -import java.util.ArrayList; - -public class ConnectivityChecker extends JobBase { - private static final String LOG_TAG = "GceConnChecker"; - private static final String MOBILE_NETWORK_CONNECTED_MESSAGE = - "VIRTUAL_DEVICE_NETWORK_MOBILE_CONNECTED"; - - private final Context mContext; - private final BootReporter mBootReporter; - private final GceFuture<Boolean> mConnected = new GceFuture<Boolean>("Connectivity"); - // TODO(schuffelen): Figure out why this has to be static in order to not report 3 times. - private static boolean reportedMobileConnectivity = false; - - public ConnectivityChecker(Context context, BootReporter bootReporter) { - super(LOG_TAG); - mContext = context; - mBootReporter = bootReporter; - } - - - @Override - public int execute() { - ConnectivityManager connManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - if (mConnected.isDone()) { - return 0; - } - - Network[] networks = connManager.getAllNetworks(); - for (Network network : networks) { - NetworkInfo info = connManager.getNetworkInfo(network); - if (info.isConnected()) { - NetworkCapabilities capabilities = connManager.getNetworkCapabilities(network); - if (capabilities != null - && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) - && !reportedMobileConnectivity) { - mBootReporter.reportMessage(MOBILE_NETWORK_CONNECTED_MESSAGE); - reportedMobileConnectivity = true; - } - } - } - - return 0; - } - - - @Override - public void onDependencyFailed(Exception e) { - mConnected.set(e); - } - - - public GceFuture<Boolean> getConnected() { - return mConnected; - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java deleted file mode 100644 index 754eb8f3..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.bluetooth.BluetoothAdapter; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.util.Log; - -import com.android.google.gce.gceservice.GceService; - -public class GceBroadcastReceiver extends BroadcastReceiver { - private static final String LOG_TAG = "GceBroadcastReceiver"; - - - private void reportIntent(Context context, String intentType) { - Intent intent = new Intent(context, GceService.class); - intent.setAction(intentType); - context.startService(intent); - } - - - @Override - public void onReceive(Context context, Intent intent) { - if (intent != null) { - final String action = intent.getAction(); - Log.i(LOG_TAG, "Received broadcast: " + action); - - if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { - reportIntent(context, GceService.INTENT_ACTION_CONFIGURE); - } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - reportIntent(context, GceService.INTENT_ACTION_NETWORK_CHANGED); - } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - reportIntent(context, GceService.INTENT_ACTION_BLUETOOTH_CHANGED); - } - } - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java deleted file mode 100644 index 055377de..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.util.Log; -import java.util.ArrayList; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.TimeUnit; -import com.google.common.util.concurrent.AbstractFuture; - -public class GceFuture<T> extends AbstractFuture<T> { - private static final String LOG_TAG = "GceFuture"; - private final String mName; - - - public GceFuture(String name) { - mName = name; - } - - - public String getName() { - return mName; - } - - - @Override - public boolean set(T value) { - if (super.set(value)) { - return true; - } else { - Exception e = new Exception(); - Log.e(LOG_TAG, mName + ": Multiple return values from a future object.", e); - return false; - } - } - - - public void set(Exception e) { - if (!super.setException(e)) { - Log.w(LOG_TAG, mName + ": Discarding execution exception -- job done.", e); - return; - } - Log.w(LOG_TAG, mName + ": Could not complete job: " + e.getMessage(), e); - } - - - @Override - public boolean cancel(boolean canInterrupt) { - // TODO(schuffelen): See if this can be deleted, since GceFuture.cancel is never invoked - // directly. - // We do not support interrupting jobs on purpose: - // this offers us little benefit (stripping maybe a second or two), at the expense - // of killing something that may cascade, like BroadcastReceiver. - return super.setException(new CancellationException("cancelled")); - } - - - @Override - public boolean isCancelled() { - if (isDone()) { - try { - get(); - } catch (ExecutionException ex) { - return ex.getCause() instanceof CancellationException; - } catch (InterruptedException ex) { - return false; - } catch (CancellationException ex) { - return true; - } - } - return false; - } - - - /** Convert list of GceFuture objects to string representation. - */ - public static String toString(ArrayList<GceFuture<?>> futures) { - StringBuilder b = new StringBuilder(); - for (GceFuture<?> dep : futures) { - if (b.length() > 0) b.append(", "); - b.append(dep.getName()); - } - - return b.toString(); - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java deleted file mode 100644 index b070377e..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.util.Log; -import android.os.Binder; -import android.os.IBinder; -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.List; - -/** - * Service is started by the BootCompletedReceiver at the end of Android Boot process. - * Responsible for final configuration changes and emitting final BOOT_COMPLETED message. - */ -public class GceService extends Service { - private static final String LOG_TAG = "GceService"; - /* Intent sent by the BootCompletedReceiver upon receiving ACTION_BOOT_COMPLETED broadcast. */ - public static final String INTENT_ACTION_CONFIGURE = "com.android.google.gce.gceservice.CONFIGURE"; - public static final String INTENT_ACTION_NETWORK_CHANGED = "com.android.google.gce.gceservice.NETWORK_CHANGED"; - public static final String INTENT_ACTION_BLUETOOTH_CHANGED = "com.android.google.gce.gceservice.BLUETOOTH_CHANGED"; - private static final int NETWORK_OR_BOOT_TIMEOUT = 30; - - private final JobExecutor mExecutor = new JobExecutor(); - private final LocationServicesManager mLocationServices = new LocationServicesManager(this); - private final PackageVerifierManager mPackageVerifier = new PackageVerifierManager(this); - private final PackageVerificationConsentEnforcer mConsentEnforcer = new PackageVerificationConsentEnforcer(this); - private final BootReporter mBootReporter = new BootReporter(); - private final GceBroadcastReceiver mBroadcastReceiver = new GceBroadcastReceiver(); - private final BluetoothChecker mBluetoothChecker = new BluetoothChecker(); - private final TombstoneChecker mTombstoneChecker = new TombstoneChecker(); - - private ConnectivityChecker mConnChecker; - private GceWifiManager mWifiManager = null; - private String mMostRecentAction = null; - - public GceService() {} - - - @Override - public void onCreate() { - try { - super.onCreate(); - mBootReporter.reportBootStarted(); - registerBroadcastReceivers(); - - mConnChecker = new ConnectivityChecker(this, mBootReporter); - mWifiManager = new GceWifiManager(this, mBootReporter, mExecutor); - - mExecutor.schedule(mLocationServices); - mExecutor.schedule(mPackageVerifier); - mExecutor.schedule(mConsentEnforcer); - mExecutor.schedule(mWifiManager); - mExecutor.schedule(mBluetoothChecker); - mExecutor.schedule(mConnChecker); - // TODO(ender): TombstoneChecker is disabled, because we no longer have the code that - // produces /ts_snap.txt file. We need to rethink how TombstoneChecker should work. - // mExecutor.schedule(mTombstoneChecker); - - mExecutor.schedule(mBootReporter, - mLocationServices.getLocationServicesReady(), - mPackageVerifier.getPackageVerifierReady(), - mBluetoothChecker.getEnabled() - // mTombstoneChecker.getTombstoneResult() - ); - } catch (Exception e) { - Log.e(LOG_TAG, "Exception caught", e); - } - } - - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - - /** Register broadcast listeners. - * - * Certain intents can no longer be used to start a service or activity, but - * can still be registered for, such as CONNECTIVITY_ACTION (Android N). - */ - private void registerBroadcastReceivers() { - IntentFilter filter = new IntentFilter(); - filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); - filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - this.registerReceiver(mBroadcastReceiver, filter); - } - - - /** StartService entry point. - */ - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent != null) { - mMostRecentAction = intent.getAction(); - } else { - Log.w(LOG_TAG, "Previous execution failed. Retrying."); - } - - if (mMostRecentAction == null) { - Log.e(LOG_TAG, "Missing intent action."); - } - - if (INTENT_ACTION_CONFIGURE.equals(mMostRecentAction)) { - mExecutor.schedule(mConnChecker); - } else if (INTENT_ACTION_NETWORK_CHANGED.equals(mMostRecentAction)) { - mExecutor.schedule(mConnChecker); - } else if (INTENT_ACTION_BLUETOOTH_CHANGED.equals(mMostRecentAction)) { - mExecutor.schedule(mBluetoothChecker); - } - - /* If anything goes wrong, make sure we receive intent again. */ - return Service.START_STICKY; - } - - /** Dump the virtual device state - */ - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("Boot reporter:"); - List<String> messageList = mBootReporter.getMessageList(); - for (int i = 0; i < messageList.size(); i++) { - pw.println(" " + messageList.get(i)); - } - pw.println(""); - pw.println("Current system service state:"); - pw.println(" Location service ready: " - + mLocationServices.getLocationServicesReady().isDone()); - pw.println(" Package verifier ready: " - + mPackageVerifier.getPackageVerifierReady().isDone()); - pw.println(" Network connected: " + mConnChecker.getConnected().isDone()); - pw.println(" WiFi configured: " + mWifiManager.getWifiReady().isDone()); - pw.println(" Bluetooth enabled: " + mBluetoothChecker.getEnabled().isDone()); - pw.println(" Tombstone dropped (on boot): " - + !mTombstoneChecker.getTombstoneResult().isDone()); - pw.println(""); - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java deleted file mode 100644 index 27471101..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.os.Handler; -import android.util.Log; -import java.util.ArrayList; -import java.util.List; - -/** - * Manage WIFI state. - */ -public class GceWifiManager extends JobBase { - private static final String LOG_TAG = "GceWifiManager"; - /* Timeout after which the service will check if wifi has come up. */ - private static final int WIFI_RECONNECTION_TIMEOUT_S = 5; - private static final String WIFI_CONNECTED_MESSAGE = - "VIRTUAL_DEVICE_NETWORK_WIFI_CONNECTED"; - - private final JobExecutor mJobExecutor; - private final Context mContext; - private final WifiManager mWifiManager; - private final ConnectivityManager mConnManager; - private final BootReporter mBootReporter; - - private final MonitorWifiJob mMonitorWifiJob; - - - public GceWifiManager(Context context, BootReporter bootReporter, JobExecutor executor) { - super(LOG_TAG); - - mContext = context; - mWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); - mConnManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); - mBootReporter = bootReporter; - mJobExecutor = executor; - mMonitorWifiJob = new MonitorWifiJob(); - } - - - /** Executed during initial configuration. */ - @Override - public synchronized int execute() { - mJobExecutor.schedule(mMonitorWifiJob); - return 0; - } - - - @Override - public void onDependencyFailed(Exception e) { - Log.e(LOG_TAG, "Initial WIFI configuration failed due to dependency.", e); - getWifiReady().set(e); - } - - - public GceFuture<Boolean> getWifiReady() { - return mMonitorWifiJob.getWifiReady(); - } - - - /* Modifies Wifi state: - * - if wifi disable requested (state == false), simply turns off wifi. - * - if wifi enable requested (state == true), turns on wifi and arms the - * connection timeout (see startWifiReconnectionTimeout). - */ - private class MonitorWifiJob extends JobBase { - private final GceFuture<Boolean> mWifiReady = - new GceFuture<Boolean>("WIFI Ready"); - private boolean mReportedWifiNotConnected = false; - - - public MonitorWifiJob() { - super(LOG_TAG); - } - - - public synchronized void cancel() { - if (!mWifiReady.isDone()) { - mWifiReady.cancel(false); - } - } - - - @Override - public synchronized int execute() { - // Could be cancelled or exception. - if (mWifiReady.isDone()) return 0; - - WifiInfo info = mWifiManager.getConnectionInfo(); - if (info.getSupplicantState() != SupplicantState.COMPLETED) { - if (!mReportedWifiNotConnected) { - Log.w(LOG_TAG, "Wifi not yet connected."); - mReportedWifiNotConnected = true; - } - return WIFI_RECONNECTION_TIMEOUT_S; - } else { - mBootReporter.reportMessage(WIFI_CONNECTED_MESSAGE); - Log.i(LOG_TAG, "Wifi connected."); - mWifiReady.set(true); - return 0; - } - } - - - @Override - public void onDependencyFailed(Exception e) { - Log.e(LOG_TAG, "Wifi state change failed due to failing dependency.", e); - mWifiReady.set(e); - } - - - public GceFuture<Boolean> getWifiReady() { - return mWifiReady; - } - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java deleted file mode 100644 index aceb70f5..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.util.Log; -import java.util.ArrayList; - -public abstract class JobBase { - private final String mTag; - - JobBase(String tag) { - mTag = tag; - } - - - /** Invoked, when job could not be started due to dependency failure. - * - * Supplied exception describes reason of failure. - */ - public abstract void onDependencyFailed(Exception exception); - - - /** Invoked, when one or more tasks have taken substantial time to complete. - * - * This is not a direct indication of an error, but merely an information - * about what stops current job from being executed. - * - * @param stragglingDependencies list of dependencies that have not completed - * in last 10 seconds. - */ - public void onDependencyStraggling(ArrayList<GceFuture<?>> stragglingDependencies) { - Log.i(mTag, "Waiting for: " + GceFuture.toString(stragglingDependencies)); - } - - - /** Invoked, when all dependencies are ready and job is clear to commence. - * - * Returns number of second before re-execution, or 0, if job is done. - */ - public abstract int execute(); -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java deleted file mode 100644 index 1eed0065..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.util.Log; -import com.android.google.gce.gceservice.JobBase; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.TimeUnit; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Set; -import java.util.HashSet; - -public class JobExecutor { - private static final int THREAD_POOL_SIZE = 8; - private static final String LOG_TAG = "GceExecutor"; - private static final int ITERATION_PERIOD_MS = 10 * 1000; - private final ScheduledExecutorService mExecutor; - private final Set<String> mStartedJobs; - - public JobExecutor() { - mExecutor = Executors.newScheduledThreadPool(THREAD_POOL_SIZE); - mStartedJobs = new HashSet<String>(); - } - - /** Schedule job for (periodic) execution. - * - * First execution is performed at the earliest possibility. - * Execution stops when a call to execute() returns a nonpositive number. - * - * Note: iteration time is |delaySeconds| + total time needed to execute job. - */ - public void schedule(final JobBase job, final GceFuture<?>... futures) { - mExecutor.schedule(new Runnable() { - private boolean mDependenciesReady = false; - private ArrayList<GceFuture<?>> mFutures = new ArrayList<GceFuture<?>>(); - - { - for (GceFuture<?> future: futures) { - mFutures.add(future); - } - } - - public void run() { - if (!mDependenciesReady) { - while (!mFutures.isEmpty()) { - ArrayList<GceFuture<?>> stragglers = new ArrayList<GceFuture<?>>(); - long endTime = System.currentTimeMillis() + ITERATION_PERIOD_MS; - for (GceFuture<?> future : mFutures) { - try { - // Wait for at most ITERATION_PERIOD_MS. Check all futures, - // collect only those that still failed to complete. - future.get( - Math.max(0, endTime - System.currentTimeMillis()), - TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - stragglers.add(future); - } catch (InterruptedException e) { - // In theory we should re-try this one. - // In practice this hardly ever happens, so let's just - // give it another go in the second loop. - stragglers.add(future); - } catch (Exception e) { - Log.e(LOG_TAG, String.format( - "Could not start job %s.", job.getClass().getName()), - e); - job.onDependencyFailed(e); - return; - } - } - - mFutures = stragglers; - if (!mFutures.isEmpty()) { - job.onDependencyStraggling(mFutures); - } - } - mDependenciesReady = true; - } - - try { - String jobName = job.getClass().getName(); - if (!mStartedJobs.contains(jobName)) { - mStartedJobs.add(jobName); - } - int delaySeconds = job.execute(); - if (delaySeconds > 0) { - mExecutor.schedule(this, delaySeconds, TimeUnit.SECONDS); - } else { - mStartedJobs.remove(jobName); - } - } catch (Exception e) { - Log.e(LOG_TAG, String.format("Job %s threw an exception and will not be re-scheduled.", - job.getClass().getName()), e); - } - } - }, 0, TimeUnit.SECONDS); - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java deleted file mode 100644 index f9ad3883..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.util.Log; -import com.android.google.gce.gceservice.GceFuture; -import com.android.google.gce.gceservice.JobBase; - -/** - * Configure Location Services on Android Jellybean. - * No action on more recent versions of Android. - */ -class LocationServicesManager extends JobBase { - private static final String LOG_TAG = "GceLocationServicesManager"; - private static final String ACTION_LOCATION_SERVICES_CONSENT_INTENT = - "com.google.android.gsf.action.SET_USE_LOCATION_FOR_SERVICES"; - private static final String EXTRA_LOCATION_SERVICES_CONSENT_DISABLE = - "disable"; - private final Context mContext; - private final GceFuture<Boolean> mResult = new GceFuture<Boolean>("Location Services"); - - - LocationServicesManager(Context context) { - super(LOG_TAG); - mContext = context; - } - - - public int execute() { - /* Check if we're running Jellybean. - * Sadly, we can't use version name Build.VERSION_CODES.JELLY_BEAN_MR2 - * because MR1 and MR0 don't know this number. - */ - if (Build.VERSION.SDK_INT <= 18) { - Intent intent = new Intent(); - intent.setAction(ACTION_LOCATION_SERVICES_CONSENT_INTENT); - intent.setFlags(intent.getFlags() | - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.putExtra(EXTRA_LOCATION_SERVICES_CONSENT_DISABLE, false); - mContext.startActivity(intent); - } - - mResult.set(true); - return 0; - } - - - public void onDependencyFailed(Exception e) { - Log.e(LOG_TAG, "Could not configure LocationServices.", e); - mResult.set(e); - } - - - public GceFuture<Boolean> getLocationServicesReady() { - return mResult; - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java deleted file mode 100644 index e45d656b..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.content.ContentResolver; -import android.content.Context; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.util.Log; - -/** - * Forces pacakge verification to be off on N and N-MR1 by adjusting package_verifier_user_consent. - * - * This is needed because CVDs don't have a touch screen, and the consent - * dialog will block apk installs. - * - * Possible values for consent seem to be: - * -1 The user refused - * 0 Ask the user - * 1 The user accepted - * - * This code polls because Android may overwrite a non-zero value with a 0 - * at some point after boot completes. However, this happens only on some - * boots, so it can't be a blocker for boot complete. - */ -class PackageVerificationConsentEnforcer extends JobBase { - private static final String LOG_TAG = "GcePVCR"; - private static final String PACKAGE_VERIFIER_USER_CONSENT = "package_verifier_user_consent"; - private final Context mContext; - - // Chosen to avoid the possible values (see top comment). - private int mLastObservedValue = -2; - - - public PackageVerificationConsentEnforcer(Context context) { - super(LOG_TAG); - mContext = context; - } - - - public int execute() { - if (android.os.Build.VERSION.SDK_INT < 24) { - // Skip older android versions. - return 0; - } - - try { - ContentResolver contentResolver = mContext.getContentResolver(); - int value = Settings.Secure.getInt(contentResolver, PACKAGE_VERIFIER_USER_CONSENT); - if (value != mLastObservedValue) { - mLastObservedValue = value; - } - - if (value == 0) { - Settings.Secure.putInt(mContext.getContentResolver(), PACKAGE_VERIFIER_USER_CONSENT, -1); - } - } catch (SettingNotFoundException e) { - } - - return 1; - } - - - public void onDependencyFailed(Exception e) { - Log.e(LOG_TAG, "Could not start Consent Enforcer.", e); - } -} - - diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java deleted file mode 100644 index e10845a9..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.content.ContentResolver; -import android.content.Context; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.util.Log; - -/** - * Disable package verifier. - */ -public class PackageVerifierManager extends JobBase { - private static final String LOG_TAG = "GcePackageVerifierManager"; - private static final String SETTING_PACKAGE_VERIFIER_ENABLE = "verifier_verify_adb_installs"; - private final Context mContext; - private final GceFuture<Boolean> mResult = - new GceFuture<Boolean>("Package Verifier"); - - - PackageVerifierManager(Context context) { - super(LOG_TAG); - mContext = context; - } - - - private boolean getAndLogPackageVerifierState() { - int package_verifier_state = 1; - try { - ContentResolver contentResolver = mContext.getContentResolver(); - package_verifier_state = Settings.Secure.getInt(contentResolver, SETTING_PACKAGE_VERIFIER_ENABLE); - } catch (SettingNotFoundException e) { - Log.w(LOG_TAG, "Could not read package verifier state. Assuming it's enabled."); - } - - return package_verifier_state != 0; - } - - - public int execute() { - if (getAndLogPackageVerifierState()) { - Settings.Secure.putInt(mContext.getContentResolver(), SETTING_PACKAGE_VERIFIER_ENABLE, 0); - // One more call, just to log the state. - getAndLogPackageVerifierState(); - } - - mResult.set(true); - return 0; - } - - - public void onDependencyFailed(Exception e) { - Log.e(LOG_TAG, "Could not disable Package Verifier.", e); - mResult.set(e); - } - - - public GceFuture<Boolean> getPackageVerifierReady() { - return mResult; - } -} diff --git a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java deleted file mode 100644 index dec08370..00000000 --- a/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.google.gce.gceservice; - -import android.util.Log; -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Scanner; - -/** A job that checks for any new tombstones before reporting VIRTUAL_DEVICE_BOOT_COMPLETED. - * - */ -public class TombstoneChecker extends JobBase { - private static final String LOG_TAG = "GceTombstoneChecker"; - private static final String sSnapshotDir = "/data/tombstones"; - private static final String sSnapshotFile = "/ts_snap.txt"; - private static final String sTsExceptionMessage = "GceTombstoneChecker internal error. "; - private static final String sTsFilePrefix = "tombstone"; - private final GceFuture<Boolean> mPassed = new GceFuture<Boolean>("GceTombstoneChecker"); - private ArrayList<Record> mPreBootRecords = new ArrayList<Record>(); - private ArrayList<Record> mPostBootRecords = new ArrayList<Record>(); - - public TombstoneChecker() { - super(LOG_TAG); - } - - - @Override - public int execute() { - if (mPassed.isDone()) { - return 0; - } - - try { - readPreBootSnapshot(); - capturePostBootSnapshot(); - if (seenNewTombstones()) { - Log.e(LOG_TAG, "Tombstones created during boot. "); - for (int i = 0; i < mPostBootRecords.size(); i++) { - Log.i(LOG_TAG, mPostBootRecords.get(i).getFileName()); - } - mPassed.set(new Exception("Tombstones created. ")); - } else { - mPassed.set(true); - } - } catch(Exception e) { - Log.e(LOG_TAG, sTsExceptionMessage + e); - mPassed.set(new Exception(sTsExceptionMessage, e)); - } - - return 0; - } - - @Override - public void onDependencyFailed(Exception e) { - mPassed.set(e); - } - - public GceFuture<Boolean> getTombstoneResult() { - return mPassed; - } - - private void capturePostBootSnapshot() throws Exception { - File dir = new File(sSnapshotDir); - File[] files = dir.listFiles(); - - // In K & L, /data/tombstones directory is not created during boot. So - // dir.listFiles() can return null. - if (files == null) { - return; - } - - for (int i = 0; i < files.length; i++) { - if (files[i].isFile() && files[i].getName().startsWith(sTsFilePrefix)) { - long ctime = files[i].lastModified() / 1000; - mPostBootRecords.add(new Record(files[i].getName(), ctime)); - } - } - Collections.sort(mPostBootRecords); - - return; - } - - private void readPreBootSnapshot() throws Exception { - File file = new File(sSnapshotFile); - if (!file.isFile()) { - throw new FileNotFoundException(sSnapshotFile); - } - - Scanner scanner = new Scanner(file); - while (scanner.hasNext()) { - String[] fields = scanner.nextLine().split(" "); - mPreBootRecords.add(new Record(fields[0], Long.parseLong(fields[1]))); - } - Collections.sort(mPreBootRecords); - - return; - } - - private boolean seenNewTombstones() { - return !isEqual(mPreBootRecords, mPostBootRecords); - } - - private boolean isEqual(ArrayList<Record> preBoot, ArrayList<Record> postBoot) { - postBoot.removeAll(preBoot); - if (postBoot.size() != 0) { - return false; - } - - return true; - } - - private class Record implements Comparable<Record> { - private String mFilename; - private long mCtime; - - public Record(String filename, long ctime) { - this.mFilename = filename; - this.mCtime = ctime; - } - - public String getFileName() { - return mFilename; - } - - public int compareTo(Record r) { - if (this == r) { - return 0; - } - - return (mFilename.compareTo(r.mFilename)); - } - - public boolean equals(Object o) { - if (o == null) { - return false; - } - - if (this == o) { - return true; - } - - Record r = (Record) o; - return (mFilename.equals(r.mFilename) && (mCtime == r.mCtime)); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(mFilename).append(" ").append(String.valueOf(mCtime)); - return sb.toString(); - } - } -} diff --git a/guest/monitoring/cuttlefish_service/proguard.flags b/guest/monitoring/cuttlefish_service/proguard.flags deleted file mode 100644 index 4578c0d1..00000000 --- a/guest/monitoring/cuttlefish_service/proguard.flags +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2016 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. - -# Keep enough data for stack traces --renamesourcefileattribute SourceFile --keepattributes SourceFile,LineNumberTable,RuntimeVisible*Annotations,AnnotationDefault - -# Keep classes and methods that have the guava @VisibleForTesting annotation --keep @com.google.common.annotations.VisibleForTesting class * --keepclassmembers class * { - @com.google.common.annotations.VisibleForTesting *; -} - --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver - -# -dontobfuscate --keep,allowshrinking class * { *; } diff --git a/guest/monitoring/dumpstate_ext/Android.bp b/guest/monitoring/dumpstate_ext/Android.bp deleted file mode 100644 index ba3320c3..00000000 --- a/guest/monitoring/dumpstate_ext/Android.bp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary { - name: "android.hardware.dumpstate@1.0-service.cuttlefish", - srcs: [ - "dumpstate_device.cpp", - "service.cpp", - ], - shared_libs: [ - "android.hardware.dumpstate@1.0", - "libbase", - "libcutils", - "libdumpstateutil", - "libhidlbase", - "liblog", - "libutils", - ], - cflags: [ - "-DLOG_TAG=\"VSoC-dumpstate\"", - ], - relative_install_path: "hw", - init_rc: [ - "android.hardware.dumpstate@1.0-service.cuttlefish.rc", - ], - defaults: ["cuttlefish_guest_only"] -} diff --git a/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc b/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc deleted file mode 100644 index ad68f35c..00000000 --- a/guest/monitoring/dumpstate_ext/android.hardware.dumpstate@1.0-service.cuttlefish.rc +++ /dev/null @@ -1,4 +0,0 @@ -service dumpstate-1-0 /vendor/bin/hw/android.hardware.dumpstate@1.0-service.cuttlefish - class hal - user system - group system diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp b/guest/monitoring/dumpstate_ext/dumpstate_device.cpp deleted file mode 100644 index d8481c71..00000000 --- a/guest/monitoring/dumpstate_ext/dumpstate_device.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "guest/monitoring/dumpstate_ext/dumpstate_device.h" - -#include <log/log.h> -#include <DumpstateUtil.h> - -using android::os::dumpstate::DumpFileToFd; - -namespace android { -namespace hardware { -namespace dumpstate { -namespace V1_0 { -namespace implementation { - -// Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow. -Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) { - if (handle == nullptr || handle->numFds < 1) { - ALOGE("no FDs\n"); - return Void(); - } - - int fd = handle->data[0]; - if (fd < 0) { - ALOGE("invalid FD: %d\n", handle->data[0]); - return Void(); - } - - DumpFileToFd(fd, "GCE INITIAL METADATA", "/initial.metadata"); - - return Void(); -} - -} // namespace implementation -} // namespace V1_0 -} // namespace dumpstate -} // namespace hardware -} // namespace android diff --git a/guest/monitoring/dumpstate_ext/dumpstate_device.h b/guest/monitoring/dumpstate_ext/dumpstate_device.h deleted file mode 100644 index 581a96b0..00000000 --- a/guest/monitoring/dumpstate_ext/dumpstate_device.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h> -#include <hidl/MQDescriptor.h> -#include <hidl/Status.h> - -namespace android { -namespace hardware { -namespace dumpstate { -namespace V1_0 { -namespace implementation { - -using ::android::hardware::Return; -using ::android::hardware::Void; -using ::android::hardware::dumpstate::V1_0::IDumpstateDevice; -using ::android::hardware::hidl_array; -using ::android::hardware::hidl_handle; -using ::android::hardware::hidl_string; -using ::android::hardware::hidl_vec; -using ::android::sp; - -struct DumpstateDevice : public IDumpstateDevice { - // Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow. - Return<void> dumpstateBoard(const hidl_handle& h) override; -}; - -} // namespace implementation -} // namespace V1_0 -} // namespace dumpstate -} // namespace hardware -} // namespace android diff --git a/guest/monitoring/dumpstate_ext/service.cpp b/guest/monitoring/dumpstate_ext/service.cpp deleted file mode 100644 index 67eebe56..00000000 --- a/guest/monitoring/dumpstate_ext/service.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <hidl/HidlSupport.h> -#include <hidl/HidlTransportSupport.h> - -#include "guest/monitoring/dumpstate_ext/dumpstate_device.h" - -using ::android::OK; -using ::android::hardware::configureRpcThreadpool; -using ::android::hardware::dumpstate::V1_0::IDumpstateDevice; -using ::android::hardware::dumpstate::V1_0::implementation::DumpstateDevice; -using ::android::hardware::joinRpcThreadpool; -using ::android::sp; - -int main() { - sp<IDumpstateDevice> dumpstate = new DumpstateDevice; - // This method MUST be called before interacting with any HIDL interfaces. - configureRpcThreadpool(1, true); - if (dumpstate->registerAsService() != OK) { - ALOGE("Could not register service."); - return 1; - } - joinRpcThreadpool(); -} diff --git a/guest/monitoring/tombstone_transmit/Android.bp b/guest/monitoring/tombstone_transmit/Android.bp deleted file mode 100644 index 2e0af82a..00000000 --- a/guest/monitoring/tombstone_transmit/Android.bp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary { - name: "tombstone_transmit", - srcs: [ - "tombstone_transmit.cpp", - ], - static_libs: [ - "libcuttlefish_fs_product", - "libgflags", - "libbase", - "libcutils", - ], - shared_libs: [ - "liblog", - ], - stl: "libc++_static", - header_libs: [ - "cuttlefish_glog_product", - ], - defaults: ["cuttlefish_guest_product_only"], -} - -cc_binary { - name: "tombstone_producer", - srcs: [ - "tombstone_producer.cpp", - ], - defaults: ["cuttlefish_guest_product_only"], -} diff --git a/guest/monitoring/tombstone_transmit/tombstone_producer.cpp b/guest/monitoring/tombstone_transmit/tombstone_producer.cpp deleted file mode 100644 index 95d447d4..00000000 --- a/guest/monitoring/tombstone_transmit/tombstone_producer.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <stdlib.h> - -int __attribute__((noreturn)) main() { - abort(); -} diff --git a/guest/monitoring/tombstone_transmit/tombstone_transmit.cpp b/guest/monitoring/tombstone_transmit/tombstone_transmit.cpp deleted file mode 100644 index 8fc3586c..00000000 --- a/guest/monitoring/tombstone_transmit/tombstone_transmit.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android-base/logging.h> -#include <errno.h> -#include <log/log.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/inotify.h> -#include <unistd.h> -#include <fstream> - -#include <cutils/properties.h> -#include <gflags/gflags.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/subprocess.h" - -static const char TOMBSTONE_DIR[] = "/data/tombstones/"; - -// returns a fd which when read from, provides inotify events when tombstones -// are created -static int new_tombstone_create_notifier(void) { - int file_create_notification_handle = inotify_init(); - if (file_create_notification_handle == -1) { - ALOGE("%s: inotify_init failure error: '%s' (%d)", __FUNCTION__, - strerror(errno), errno); - return -1; - } - - int watch_descriptor = inotify_add_watch(file_create_notification_handle, - TOMBSTONE_DIR, IN_CREATE); - if (watch_descriptor == -1) { - ALOGE("%s: Could not add watch for '%s', error: '%s' (%d)", __FUNCTION__, - TOMBSTONE_DIR, strerror(errno), errno); - close(file_create_notification_handle); - return -1; - } - - return file_create_notification_handle; -} - -#define INOTIFY_MAX_EVENT_SIZE (sizeof(struct inotify_event) + NAME_MAX + 1) -static std::string get_next_tombstone_path_blocking(int fd) { - char event_readout[INOTIFY_MAX_EVENT_SIZE]; - struct inotify_event *i = (inotify_event*)(event_readout); - - int event_read_out_length = read(fd, event_readout, INOTIFY_MAX_EVENT_SIZE); - - if(event_read_out_length == -1) { - ALOGE("%s: Couldn't read out inotify event due to error: '%s' (%d)", - __FUNCTION__, strerror(errno), errno); - return std::string(); - } - - // Create event didn't show up for some reason or no file name was present - if(event_read_out_length == sizeof(struct inotify_event)) { - ALOGE("%s: inotify event didn't contain filename",__FUNCTION__); - return std::string(); - } - - if(!(i->mask & IN_CREATE)) { - ALOGE("%s: inotify event didn't pertain to file creation",__FUNCTION__); - return std::string(); - } - - std::string ret_value(TOMBSTONE_DIR); - return ret_value + i->name; -} - -DEFINE_uint32(port, property_get_int32("ro.boot.vsock_tombstone_port", 0), - "VSOCK port to send tombstones to"); -DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to"); -#define TOMBSTONE_BUFFER_SIZE (1024) - -int main(int argc, char** argv) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - - if(FLAGS_port == 0) { - LOG(FATAL_WITHOUT_ABORT) << "Port flag is required"; - while(1) {sleep(1);}; - } - - int file_create_notification_handle = new_tombstone_create_notifier(); - if (file_create_notification_handle == -1) {return -1;} - - LOG(INFO) << "tombstone watcher successfully initialized"; - - while (true) { - std::string ts_path = get_next_tombstone_path_blocking( - file_create_notification_handle); - - if(ts_path.empty()) {continue;} - - auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port, - SOCK_STREAM); - - std::ifstream ifs(ts_path); - char buffer[TOMBSTONE_BUFFER_SIZE]; - uint num_transfers = 0; - int num_bytes_read = 0; - while (log_fd->IsOpen() && ifs.is_open() && !ifs.eof()) { - ifs.read(buffer, sizeof(buffer)); - num_bytes_read += ifs.gcount(); - log_fd->Write(buffer, ifs.gcount()); - num_transfers++; - } - - if (!log_fd->IsOpen()) { - ALOGE("Unable to connect to vsock:%u:%u: %s", FLAGS_cid, FLAGS_port, - log_fd->StrError()); - } else if (!ifs.is_open()) { - ALOGE("%s closed in the middle of readout.", ts_path.c_str()); - } else { - LOG(INFO) << num_bytes_read << " chars transferred from " << - ts_path.c_str() << " over " << num_transfers << " " - << TOMBSTONE_BUFFER_SIZE << " byte sized transfers"; - } - } - - return 0; -} diff --git a/guest/services/suspend_blocker/Android.bp b/guest/services/suspend_blocker/Android.bp deleted file mode 100644 index c87c4da9..00000000 --- a/guest/services/suspend_blocker/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2019 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. - -cc_binary { - name: "suspend_blocker", - srcs: ["suspend_blocker.cpp"], - shared_libs: ["libpower"], - defaults: ["cuttlefish_guest_product_only"], -} diff --git a/guest/services/suspend_blocker/suspend_blocker.cpp b/guest/services/suspend_blocker/suspend_blocker.cpp deleted file mode 100644 index 120a01b8..00000000 --- a/guest/services/suspend_blocker/suspend_blocker.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <signal.h> -#include <wakelock/wakelock.h> - -int main() { - android::wakelock::WakeLock wl{"suspend_blocker"}; // RAII object - - sigset_t mask; - sigemptyset(&mask); - return sigsuspend(&mask); // Infinite sleep -} diff --git a/host/Android.bp b/host/Android.bp deleted file mode 100644 index 2280c23e..00000000 --- a/host/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "commands", - "frontend", - "libs", -] diff --git a/host/commands/Android.bp b/host/commands/Android.bp deleted file mode 100644 index c200611e..00000000 --- a/host/commands/Android.bp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "adbshell", - "fetch_cvd", - "launch", - "stop_cvd", - "ivserver", - "virtual_usb_manager", - "kernel_log_monitor", - "config_server", - "console_forwarder", - "run_cvd", - "assemble_cvd", -] diff --git a/host/commands/adbshell/Android.bp b/host/commands/adbshell/Android.bp deleted file mode 100644 index ea84dd40..00000000 --- a/host/commands/adbshell/Android.bp +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_binary_host { - name: "adbshell", - srcs: [ - "main.cpp", - ], - cflags: [ - "-D_XOPEN_SOURCE", - ], - shared_libs: [ - "libbase", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/adbshell/main.cpp b/host/commands/adbshell/main.cpp deleted file mode 100644 index d8932478..00000000 --- a/host/commands/adbshell/main.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -/* Utility that uses an adb connection as the login shell. */ - -#include "host/libs/config/cuttlefish_config.h" - -#include <array> -#include <cassert> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <string> -#include <vector> - -#include <errno.h> -#include <unistd.h> - -// Many of our users interact with CVDs via ssh. They expect to be able to -// get an Android shell (as opposed to the host shell) with a single command. -// -// Our goals are to: -// -// * Allow the user to select which CVD to connect to -// -// * Avoid modifications to the host-side sshd and the protocol -// -// We accomplish this by using specialized accounts: vsoc-## and cvd-## and -// specific Android serial numbers: -// -// The vsoc-01 account provides a host-side shell that controls the first CVD -// The cvd-01 account is connected to the Andorid shell of the first CVD -// The first CVD has a serial number of CUTTLEFISHCVD01 -// -// The code in the commands/launch directory also follows these conventions by -// default. -// - -namespace { -std::string VsocUser() { - const char* user_cstring = std::getenv("USER"); - assert(user_cstring != nullptr); - std::string user(user_cstring); - - std::string cvd_prefix = "cvd-"; - if (user.find(cvd_prefix) == 0) { - user.replace(0, cvd_prefix.size(), vsoc::kVsocUserPrefix); - } - return user; -} - -std::string CuttlefishConfigLocation() { - return std::string("/home/") + VsocUser() + - "/cuttlefish_runtime/cuttlefish_config.json"; -} - -std::string CuttlefishFindAdb() { - std::string rval = std::string("/home/") + VsocUser() + "/bin/adb"; - if (TEMP_FAILURE_RETRY(access(rval.c_str(), X_OK)) == -1) { - return "/usr/bin/adb"; - } - return rval; -} - -void SetCuttlefishConfigEnv() { - setenv(vsoc::kCuttlefishConfigEnvVarName, CuttlefishConfigLocation().c_str(), - true); -} -} // namespace - -int main(int argc, char* argv[]) { - SetCuttlefishConfigEnv(); - auto instance = vsoc::CuttlefishConfig::Get()->adb_device_name(); - std::string adb_path = CuttlefishFindAdb(); - - std::vector<char*> new_argv = { - const_cast<char*>(adb_path.c_str()), const_cast<char*>("-s"), - const_cast<char*>(instance.c_str()), const_cast<char*>("shell"), - const_cast<char*>("/system/bin/sh")}; - - // Some important data is lost before this point, and there are - // no great recovery options: - // * ssh with no arguments comes in with 1 arg of -adbshell. The command - // given above does the right thing if we don't invoke the shell. - if (argc == 1) { - new_argv.back() = nullptr; - } - // * simple shell commands come in with a -c and a single string. The - // problem here is that adb doesn't preserve spaces, so we need - // to do additional escaping. The best compromise seems to be to - // throw double quotes around each string. - for (int i = 1; i < argc; ++i) { - size_t buf_size = std::strlen(argv[i]) + 4; - new_argv.push_back(new char[buf_size]); - std::snprintf(new_argv.back(), buf_size, "\"%s\"", argv[i]); - } - // - // * scp seems to be pathologically broken when paths contain spaces. - // spaces aren't properly escaped by gcloud, so scp will fail with - // "scp: with ambiguous target." We might be able to fix this with - // some creative parsing of the arguments, but that seems like - // overkill. - new_argv.push_back(nullptr); - execv(new_argv[0], new_argv.data()); - // This never should happen - return 2; -} diff --git a/host/commands/assemble_cvd/Android.bp b/host/commands/assemble_cvd/Android.bp deleted file mode 100644 index 18b846f3..00000000 --- a/host/commands/assemble_cvd/Android.bp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_library_host_shared { - name: "cdisk_spec", - srcs: [ - "cdisk_spec.proto", - ], - proto: { - type: "full", - export_proto_headers: true, - include_dirs: [ - "external/protobuf/src", - ], - }, - defaults: ["cuttlefish_host_only"], -} - -cc_binary_host { - name: "assemble_cvd", - srcs: [ - "assemble_cvd.cc", - "boot_image_unpacker.cc", - "data_image.cc", - "flags.cc", - "image_aggregator.cc", - "super_image_mixer.cc", - ], - header_libs: [ - "bootimg_headers", - "cuttlefish_glog", - ], - shared_libs: [ - "cdisk_spec", - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - "libnl", - "libprotobuf-cpp-full", - "libziparchive", - "libz", - ], - static_libs: [ - "libcuttlefish_host_config", - "libcuttlefish_vm_manager", - "libgflags", - "libxml2", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"], -} - -sh_binary_host { - name: "cf_bpttool", - src: "cf_bpttool", -} diff --git a/host/commands/assemble_cvd/assemble_cvd.cc b/host/commands/assemble_cvd/assemble_cvd.cc deleted file mode 100644 index c8293956..00000000 --- a/host/commands/assemble_cvd/assemble_cvd.cc +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <iostream> - -#include <android-base/strings.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" -#include "host/commands/assemble_cvd/assembler_defs.h" -#include "host/commands/assemble_cvd/flags.h" -#include "host/libs/config/fetcher_config.h" - -namespace { - -std::string kFetcherConfigFile = "fetcher_config.json"; - -cvd::FetcherConfig FindFetcherConfig(const std::vector<std::string>& files) { - cvd::FetcherConfig fetcher_config; - for (const auto& file : files) { - auto expected_pos = file.size() - kFetcherConfigFile.size(); - if (file.rfind(kFetcherConfigFile) == expected_pos) { - if (fetcher_config.LoadFromFile(file)) { - return fetcher_config; - } - LOG(ERROR) << "Could not load fetcher config file."; - } - } - return fetcher_config; -} - -} // namespace - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - - if (isatty(0)) { - LOG(FATAL) << "stdin was a tty, expected to be passed the output of a previous stage. " - << "Did you mean to run launch_cvd?"; - return cvd::AssemblerExitCodes::kInvalidHostConfiguration; - } else { - int error_num = errno; - if (error_num == EBADF) { - LOG(FATAL) << "stdin was not a valid file descriptor, expected to be passed the output " - << "of assemble_cvd. Did you mean to run launch_cvd?"; - return cvd::AssemblerExitCodes::kInvalidHostConfiguration; - } - } - - std::string input_files_str; - { - auto input_fd = cvd::SharedFD::Dup(0); - auto bytes_read = cvd::ReadAll(input_fd, &input_files_str); - if (bytes_read < 0) { - LOG(FATAL) << "Failed to read input files. Error was \"" << input_fd->StrError() << "\""; - } - } - std::vector<std::string> input_files = android::base::Split(input_files_str, "\n"); - - auto config = InitFilesystemAndCreateConfig(&argc, &argv, FindFetcherConfig(input_files)); - - std::cout << GetConfigFilePath(*config) << "\n"; - std::cout << std::flush; - - return cvd::AssemblerExitCodes::kSuccess; -} diff --git a/host/commands/assemble_cvd/assembler_defs.h b/host/commands/assemble_cvd/assembler_defs.h deleted file mode 100644 index 61f7f9d0..00000000 --- a/host/commands/assemble_cvd/assembler_defs.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -namespace cvd { - -constexpr char kLogcatSerialMode[] = "serial"; -constexpr char kLogcatVsockMode[] = "vsock"; - -enum AssemblerExitCodes : int { - kSuccess = 0, - kArgumentParsingError = 1, - kInvalidHostConfiguration = 2, - kCuttlefishConfigurationInitError = 3, - kInstanceDirCreationError = 4, - kPrioFilesCleanupError = 5, - kBootImageUnpackError = 6, - kCuttlefishConfigurationSaveError = 7, - kDaemonizationError = 8, - kVMCreationError = 9, - kPipeIOError = 10, - kVirtualDeviceBootFailed = 11, - kProcessGroupError = 12, - kMonitorCreationFailed = 13, - kServerError = 14, - kUsbV1SocketError = 15, - kE2eTestFailed = 16, - kKernelDecompressError = 17, - kLogcatServerError = 18, - kConfigServerError = 19, - kTombstoneServerError = 20, - kTombstoneDirCreationError = 21, - kInitRamFsConcatError = 22, -}; - -} // namespace cvd diff --git a/host/commands/assemble_cvd/boot_image_unpacker.cc b/host/commands/assemble_cvd/boot_image_unpacker.cc deleted file mode 100644 index f1ead301..00000000 --- a/host/commands/assemble_cvd/boot_image_unpacker.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/assemble_cvd/boot_image_unpacker.h" - -#include <string.h> -#include <unistd.h> - -#include <sstream> - -#include <bootimg.h> -#include <glog/logging.h> - -#include "common/libs/utils/subprocess.h" - -namespace cvd { - -namespace { - -// Extracts size bytes from file, starting at offset bytes from the beginning to -// path. -bool ExtractFile(SharedFD source, off_t offset, size_t size, - const std::string& path) { - auto dest = SharedFD::Open(path.c_str(), O_CREAT | O_RDWR, 0755); - if (!dest->IsOpen()) { - LOG(ERROR) << "Unable to open " << path; - return false; - } - auto off = source->LSeek(offset, SEEK_SET); - if (off != offset) { - LOG(ERROR) << "Failed to lseek: " << source->StrError(); - return false; - } - return dest->CopyFrom(*source, size); -} -} // namespace - -std::unique_ptr<BootImageUnpacker> BootImageUnpacker::FromImages( - const std::string& boot_image_path, - const std::string& vendor_boot_image_path) { - auto boot_img = SharedFD::Open(boot_image_path.c_str(), O_RDONLY); - if (!boot_img->IsOpen()) { - LOG(ERROR) << "Unable to open boot image (" << boot_image_path - << "): " << boot_img->StrError(); - return nullptr; - } - boot_img_hdr_v3 header; - auto bytes_read = boot_img->Read(&header, sizeof(header)); - if (bytes_read != sizeof(header)) { - LOG(ERROR) << "Error reading boot image header"; - return nullptr; - } - - auto vendor_boot_img = SharedFD::Open(vendor_boot_image_path.c_str(), - O_RDONLY); - if (!vendor_boot_img->IsOpen()) { - LOG(ERROR) << "Unable to open vendor boot image (" << vendor_boot_image_path - << "): " << vendor_boot_img->StrError(); - return nullptr; - } - vendor_boot_img_hdr_v3 vboot_header; - bytes_read = vendor_boot_img->Read(&vboot_header, sizeof(vboot_header)); - if (bytes_read != sizeof(vboot_header)) { - LOG(ERROR) << "Error reading vendor boot image header"; - return nullptr; - } - - std::ostringstream cmdline; - cmdline << reinterpret_cast<char*>(&header.cmdline[0]); - if (vboot_header.cmdline[0] != '\0') { - cmdline << " "; - cmdline << reinterpret_cast<char*>(&vboot_header.cmdline[0]); - } - - uint32_t page_size = 4096; - // See system/tools/mkbootimg/include/bootimg/bootimg.h for the origin of - // these offset calculations - uint32_t kernel_offset = page_size; - uint32_t ramdisk_offset = - kernel_offset + - ((header.kernel_size + page_size - 1) / page_size) * page_size; - uint32_t vendor_ramdisk_offset = - ((vboot_header.header_size + vboot_header.page_size - 1) / vboot_header.page_size) * - vboot_header.page_size; - - std::unique_ptr<BootImageUnpacker> ret(new BootImageUnpacker( - boot_img, cmdline.str(), header.kernel_size, kernel_offset, - header.ramdisk_size, ramdisk_offset, vendor_boot_img, - vboot_header.vendor_ramdisk_size, vendor_ramdisk_offset)); - - return ret; -} - -std::string BootImageUnpacker::kernel_cmdline() const { - return kernel_cmdline_; -} - -bool BootImageUnpacker::ExtractKernelImage(const std::string& path) const { - if (kernel_image_size_ == 0) return false; - return ExtractFile(boot_image_, kernel_image_offset_, kernel_image_size_, - path); -} -bool BootImageUnpacker::ExtractRamdiskImage(const std::string& path) const { - if (ramdisk_image_size_ == 0) return false; - return ExtractFile(boot_image_, ramdisk_image_offset_, ramdisk_image_size_, - path); -} -bool BootImageUnpacker::ExtractVendorRamdiskImage(const std::string& path) const { - if (vendor_ramdisk_image_size_ == 0) return false; - return ExtractFile(vendor_boot_image_, vendor_ramdisk_image_offset_, - vendor_ramdisk_image_size_, path); -} - -bool BootImageUnpacker::Unpack(const std::string& ramdisk_image_path, - const std::string& vendor_ramdisk_image_path, - const std::string& kernel_image_path) { - if (HasRamdiskImage()) { - if (!ExtractRamdiskImage(ramdisk_image_path)) { - LOG(ERROR) << "Error extracting ramdisk from boot image"; - return false; - } - } - if (HasVendorRamdiskImage()) { - if (!ExtractVendorRamdiskImage(vendor_ramdisk_image_path)) { - LOG(ERROR) << "Error extracting vendor ramdisk from venodr boot image"; - return false; - } - } - if (!kernel_image_path.empty()) { - if (HasKernelImage()) { - if (!ExtractKernelImage(kernel_image_path)) { - LOG(ERROR) << "Error extracting kernel from boot image"; - return false; - } - } else { - LOG(ERROR) << "No kernel found on boot image"; - return false; - } - } - return true; -} - -} // namespace cvd diff --git a/host/commands/assemble_cvd/boot_image_unpacker.h b/host/commands/assemble_cvd/boot_image_unpacker.h deleted file mode 100644 index a331f0ca..00000000 --- a/host/commands/assemble_cvd/boot_image_unpacker.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "common/libs/fs/shared_fd.h" - -namespace cvd { - -// Unpacks the boot image and extracts kernel, ramdisk and kernel arguments -class BootImageUnpacker { - public: - // Reads header section of boot image at path and returns a BootImageUnpacker - // preloaded with all the metadata. - static std::unique_ptr<BootImageUnpacker> FromImages( - const std::string& boot_image_path, - const std::string& vendor_boot_image_path); - - ~BootImageUnpacker() = default; - - std::string kernel_cmdline() const; - - bool HasKernelImage() const { return kernel_image_size_ > 0; } - bool HasRamdiskImage() const { return ramdisk_image_size_ > 0; } - bool HasVendorRamdiskImage() const { return vendor_ramdisk_image_size_ > 0; } - - bool Unpack(const std::string& ramdisk_image_path, - const std::string& vendor_ramdisk_image_path, - const std::string& kernel_image_path); - - private: - BootImageUnpacker(SharedFD boot_image, const std::string& cmdline, - uint32_t kernel_image_size, uint32_t kernel_image_offset, - uint32_t ramdisk_image_size, uint32_t ramdisk_image_offset, - SharedFD vendor_boot_image, - uint32_t vendor_ramdisk_image_size, - uint32_t vendor_ramdisk_image_offset) - : boot_image_(boot_image), - vendor_boot_image_(vendor_boot_image), - kernel_cmdline_(cmdline), - kernel_image_size_(kernel_image_size), - kernel_image_offset_(kernel_image_offset), - ramdisk_image_size_(ramdisk_image_size), - ramdisk_image_offset_(ramdisk_image_offset), - vendor_ramdisk_image_size_(vendor_ramdisk_image_size), - vendor_ramdisk_image_offset_(vendor_ramdisk_image_offset) {} - - // Mutable because we only read from the fd, but do not modify its contents - mutable SharedFD boot_image_; - mutable SharedFD vendor_boot_image_; - std::string kernel_cmdline_; - // When buidling the boot image a particular page size is assumed, which may - // not match the actual page size of the system. - uint32_t kernel_image_size_; - uint32_t kernel_image_offset_; - uint32_t ramdisk_image_size_; - uint32_t ramdisk_image_offset_; - uint32_t vendor_ramdisk_image_size_; - uint32_t vendor_ramdisk_image_offset_; - - // Extracts the kernel image to the given path - bool ExtractKernelImage(const std::string& path) const; - // Extracts the ramdisk image to the given path. It may return false if the - // boot image does not contain a ramdisk, which is the case when having system - // as root. - bool ExtractRamdiskImage(const std::string& path) const; - // Extracts the vendor ramdisk image to the given path - bool ExtractVendorRamdiskImage(const std::string& path) const; -}; - -} // namespace cvd diff --git a/host/commands/assemble_cvd/cdisk_spec.proto b/host/commands/assemble_cvd/cdisk_spec.proto deleted file mode 100644 index 771c7cea..00000000 --- a/host/commands/assemble_cvd/cdisk_spec.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -enum ReadWriteCapability { - READ_ONLY = 0; - READ_WRITE = 1; -} - -message ComponentDisk { - string file_path = 1; - uint64 offset = 2; - ReadWriteCapability read_write_capability = 3; -} - -message CompositeDisk { - uint64 version = 1; - repeated ComponentDisk component_disks = 2; - uint64 length = 3; -}; diff --git a/host/commands/assemble_cvd/cf_bpttool b/host/commands/assemble_cvd/cf_bpttool deleted file mode 100755 index a29d737b..00000000 --- a/host/commands/assemble_cvd/cf_bpttool +++ /dev/null @@ -1,1649 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2016, 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. - - -"""Command-line tool for partitioning Brillo images.""" - - -import argparse -import bisect -import copy -import json -import math -import numbers -import os -import struct -import sys -import uuid -import zlib - -# Python 2.6 required for modern exception syntax -if sys.hexversion < 0x02060000: - print >> sys.stderr, "Python 2.6 or newer is required." - sys.exit(1) - -# Keywords used in JSON files. -JSON_KEYWORD_SETTINGS = 'settings' -JSON_KEYWORD_SETTINGS_AB_SUFFIXES = 'ab_suffixes' -JSON_KEYWORD_SETTINGS_DISK_SIZE = 'disk_size' -JSON_KEYWORD_SETTINGS_DISK_ALIGNMENT = 'disk_alignment' -JSON_KEYWORD_SETTINGS_DISK_GUID = 'disk_guid' -JSON_KEYWORD_SETTINGS_PARTITIONS_OFFSET_BEGIN = 'partitions_offset_begin' -JSON_KEYWORD_PARTITIONS = 'partitions' -JSON_KEYWORD_PARTITIONS_LABEL = 'label' -JSON_KEYWORD_PARTITIONS_OFFSET = 'offset' -JSON_KEYWORD_PARTITIONS_SIZE = 'size' -JSON_KEYWORD_PARTITIONS_GROW = 'grow' -JSON_KEYWORD_PARTITIONS_GUID = 'guid' -JSON_KEYWORD_PARTITIONS_TYPE_GUID = 'type_guid' -JSON_KEYWORD_PARTITIONS_FLAGS = 'flags' -JSON_KEYWORD_PARTITIONS_PERSIST = 'persist' -JSON_KEYWORD_PARTITIONS_IGNORE = 'ignore' -JSON_KEYWORD_PARTITIONS_AB = 'ab' -JSON_KEYWORD_PARTITIONS_AB_EXPANDED = 'ab_expanded' -JSON_KEYWORD_PARTITIONS_POSITION = 'position' -JSON_KEYWORD_AUTO = 'auto' - -# Possible values for the --type option of the query_partition -# sub-command. -QUERY_PARTITION_TYPES = ['size', - 'offset', - 'guid', - 'type_guid', - 'flags', - 'persist'] - -BPT_VERSION_MAJOR = 1 -BPT_VERSION_MINOR = 0 - -DISK_SECTOR_SIZE = 512 - -GPT_NUM_LBAS = 33 - -GPT_MIN_PART_NUM = 1 -GPT_MAX_PART_NUM = 128 - -KNOWN_TYPE_GUIDS = { - 'brillo_boot': 'bb499290-b57e-49f6-bf41-190386693794', - 'brillo_bootloader': '4892aeb3-a45f-4c5f-875f-da3303c0795c', - 'brillo_system': '0f2778c4-5cc1-4300-8670-6c88b7e57ed6', - 'brillo_odm': 'e99d84d7-2c1b-44cf-8c58-effae2dc2558', - 'brillo_oem': 'aa3434b2-ddc3-4065-8b1a-18e99ea15cb7', - 'brillo_userdata': '0bb7e6ed-4424-49c0-9372-7fbab465ab4c', - 'brillo_misc': '6b2378b0-0fbc-4aa9-a4f6-4d6e17281c47', - 'brillo_vbmeta': 'b598858a-5fe3-418e-b8c4-824b41f4adfc', - 'brillo_vendor_specific': '314f99d5-b2bf-4883-8d03-e2f2ce507d6a', - 'linux_fs': '0fc63daf-8483-4772-8e79-3d69d8477de4', - 'ms_basic_data': 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7', - 'efi_system': 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b' -} - - -def RoundToMultiple(number, size, round_down=False): - """Rounds a number up (or down) to nearest multiple of another number. - - Args: - number: The number to round up. - size: The multiple to round up to. - round_down: If True, the number will be rounded down. - - Returns: - If |number| is a multiple of |size|, returns |number|, otherwise - returns |number| + |size| - |remainder| (if |round_down| is False) or - |number| - |remainder| (if |round_down| is True). Always returns - an integer. - """ - remainder = number % size - if remainder == 0: - return int(number) - if round_down: - return int(number - remainder) - return int(number + size - remainder) - - -def ParseNumber(arg): - """Number parser. - - If |arg| is an integer, that value is returned. Otherwise int(arg, 0) - is returned. - - This function is suitable for use in the |type| parameter of - |ArgumentParser|'s add_argument() function. An improvement to just - using type=int is that this function supports numbers in other - bases, e.g. "0x1234". - - Arguments: - arg: Argument (int or string) to parse. - - Returns: - The parsed value, as an integer. - - Raises: - ValueError: If the argument could not be parsed. - """ - if isinstance(arg, numbers.Integral): - return arg - return int(arg, 0) - - -def ParseGuid(arg): - """Parser for RFC 4122 GUIDs. - - Arguments: - arg: The argument, as a string. - - Returns: - UUID in hyphenated format. - - Raises: - ValueError: If the given string cannot be parsed. - """ - return str(uuid.UUID(arg)) - - -def ParseSize(arg): - """Parser for size strings with decimal and binary unit support. - - This supports both integers and strings. - - Arguments: - arg: The string to parse. - - Returns: - The parsed size in bytes as an integer. - - Raises: - ValueError: If the given string cannot be parsed. - """ - if isinstance(arg, numbers.Integral): - return arg - - ws_index = arg.find(' ') - if ws_index != -1: - num = float(arg[0:ws_index]) - factor = 1 - if arg.endswith('KiB'): - factor = 1024 - elif arg.endswith('MiB'): - factor = 1024*1024 - elif arg.endswith('GiB'): - factor = 1024*1024*1024 - elif arg.endswith('TiB'): - factor = 1024*1024*1024*1024 - elif arg.endswith('PiB'): - factor = 1024*1024*1024*1024*1024 - elif arg.endswith('kB'): - factor = 1000 - elif arg.endswith('MB'): - factor = 1000*1000 - elif arg.endswith('GB'): - factor = 1000*1000*1000 - elif arg.endswith('TB'): - factor = 1000*1000*1000*1000 - elif arg.endswith('PB'): - factor = 1000*1000*1000*1000*1000 - else: - raise ValueError('Cannot parse string "{}"'.format(arg)) - value = num*factor - # If the resulting value isn't an integer, round up. - if not value.is_integer(): - value = int(math.ceil(value)) - else: - value = int(arg, 0) - return value - - -class ImageChunk(object): - """Data structure used for representing chunks in Android sparse files. - - Attributes: - chunk_type: One of TYPE_RAW, TYPE_FILL, or TYPE_DONT_CARE. - chunk_offset: Offset in the sparse file where this chunk begins. - output_offset: Offset in de-sparsified file where output begins. - output_size: Number of bytes in output. - input_offset: Offset in sparse file for data if TYPE_RAW otherwise None. - fill_data: Blob with data to fill if TYPE_FILL otherwise None. - """ - - FORMAT = '<2H2I' - TYPE_RAW = 0xcac1 - TYPE_FILL = 0xcac2 - TYPE_DONT_CARE = 0xcac3 - TYPE_CRC32 = 0xcac4 - - def __init__(self, chunk_type, chunk_offset, output_offset, output_size, - input_offset, fill_data): - """Initializes an ImageChunk object. - - Arguments: - chunk_type: One of TYPE_RAW, TYPE_FILL, or TYPE_DONT_CARE. - chunk_offset: Offset in the sparse file where this chunk begins. - output_offset: Offset in de-sparsified file. - output_size: Number of bytes in output. - input_offset: Offset in sparse file if TYPE_RAW otherwise None. - fill_data: Blob with data to fill if TYPE_FILL otherwise None. - - Raises: - ValueError: If data is not well-formed. - """ - self.chunk_type = chunk_type - self.chunk_offset = chunk_offset - self.output_offset = output_offset - self.output_size = output_size - self.input_offset = input_offset - self.fill_data = fill_data - # Check invariants. - if self.chunk_type == self.TYPE_RAW: - if self.fill_data is not None: - raise ValueError('RAW chunk cannot have fill_data set.') - if not self.input_offset: - raise ValueError('RAW chunk must have input_offset set.') - elif self.chunk_type == self.TYPE_FILL: - if self.fill_data is None: - raise ValueError('FILL chunk must have fill_data set.') - if self.input_offset: - raise ValueError('FILL chunk cannot have input_offset set.') - elif self.chunk_type == self.TYPE_DONT_CARE: - if self.fill_data is not None: - raise ValueError('DONT_CARE chunk cannot have fill_data set.') - if self.input_offset: - raise ValueError('DONT_CARE chunk cannot have input_offset set.') - else: - raise ValueError('Invalid chunk type') - - -class ImageHandler(object): - """Abstraction for image I/O with support for Android sparse images. - - This class provides an interface for working with image files that - may be using the Android Sparse Image format. When an instance is - constructed, we test whether it's an Android sparse file. If so, - operations will be on the sparse file by interpreting the sparse - format, otherwise they will be directly on the file. Either way the - operations do the same. - - For reading, this interface mimics a file object - it has seek(), - tell(), and read() methods. For writing, only truncation - (truncate()) and appending is supported (append_raw(), - append_fill(), and append_dont_care()). Additionally, data can only - be written in units of the block size. - - Attributes: - is_sparse: Whether the file being operated on is sparse. - block_size: The block size, typically 4096. - image_size: The size of the unsparsified file. - - """ - # See system/core/libsparse/sparse_format.h for details. - MAGIC = 0xed26ff3a - HEADER_FORMAT = '<I4H4I' - - # These are formats and offset of just the |total_chunks| and - # |total_blocks| fields. - NUM_CHUNKS_AND_BLOCKS_FORMAT = '<II' - NUM_CHUNKS_AND_BLOCKS_OFFSET = 16 - - def __init__(self, image_filename): - """Initializes an image handler. - - Arguments: - image_filename: The name of the file to operate on. - - Raises: - ValueError: If data in the file is invalid. - """ - self._image_filename = image_filename - self._read_header() - - def _read_header(self): - """Initializes internal data structures used for reading file. - - This may be called multiple times and is typically called after - modifying the file (e.g. appending, truncation). - - Raises: - ValueError: If data in the file is invalid. - """ - self.is_sparse = False - self.block_size = 4096 - self._file_pos = 0 - self._image = open(self._image_filename, 'r+b') - self._image.seek(0, os.SEEK_END) - self.image_size = self._image.tell() - - self._image.seek(0, os.SEEK_SET) - header_bin = self._image.read(struct.calcsize(self.HEADER_FORMAT)) - if len(header_bin) < struct.calcsize(self.HEADER_FORMAT): - # Not a sparse image, our job here is done. - return - (magic, major_version, minor_version, file_hdr_sz, chunk_hdr_sz, - block_size, self._num_total_blocks, self._num_total_chunks, - _) = struct.unpack(self.HEADER_FORMAT, header_bin) - if magic != self.MAGIC: - # Not a sparse image, our job here is done. - return - if not (major_version == 1 and minor_version == 0): - raise ValueError('Encountered sparse image format version {}.{} but ' - 'only 1.0 is supported'.format(major_version, - minor_version)) - if file_hdr_sz != struct.calcsize(self.HEADER_FORMAT): - raise ValueError('Unexpected file_hdr_sz value {}.'. - format(file_hdr_sz)) - if chunk_hdr_sz != struct.calcsize(ImageChunk.FORMAT): - raise ValueError('Unexpected chunk_hdr_sz value {}.'. - format(chunk_hdr_sz)) - - self.block_size = block_size - - # Build an list of chunks by parsing the file. - self._chunks = [] - - # Find the smallest offset where only "Don't care" chunks - # follow. This will be the size of the content in the sparse - # image. - offset = 0 - output_offset = 0 - for _ in xrange(1, self._num_total_chunks + 1): - chunk_offset = self._image.tell() - - header_bin = self._image.read(struct.calcsize(ImageChunk.FORMAT)) - (chunk_type, _, chunk_sz, total_sz) = struct.unpack(ImageChunk.FORMAT, - header_bin) - data_sz = total_sz - struct.calcsize(ImageChunk.FORMAT) - - if chunk_type == ImageChunk.TYPE_RAW: - if data_sz != (chunk_sz * self.block_size): - raise ValueError('Raw chunk input size ({}) does not match output ' - 'size ({})'. - format(data_sz, chunk_sz*self.block_size)) - self._chunks.append(ImageChunk(ImageChunk.TYPE_RAW, - chunk_offset, - output_offset, - chunk_sz*self.block_size, - self._image.tell(), - None)) - self._image.read(data_sz) - - elif chunk_type == ImageChunk.TYPE_FILL: - if data_sz != 4: - raise ValueError('Fill chunk should have 4 bytes of fill, but this ' - 'has {}'.format(data_sz)) - fill_data = self._image.read(4) - self._chunks.append(ImageChunk(ImageChunk.TYPE_FILL, - chunk_offset, - output_offset, - chunk_sz*self.block_size, - None, - fill_data)) - elif chunk_type == ImageChunk.TYPE_DONT_CARE: - if data_sz != 0: - raise ValueError('Don\'t care chunk input size is non-zero ({})'. - format(data_sz)) - self._chunks.append(ImageChunk(ImageChunk.TYPE_DONT_CARE, - chunk_offset, - output_offset, - chunk_sz*self.block_size, - None, - None)) - elif chunk_type == ImageChunk.TYPE_CRC32: - if data_sz != 4: - raise ValueError('CRC32 chunk should have 4 bytes of CRC, but ' - 'this has {}'.format(data_sz)) - self._image.read(4) - else: - raise ValueError('Unknown chunk type {}'.format(chunk_type)) - - offset += chunk_sz - output_offset += chunk_sz * self.block_size - - # Record where sparse data end. - self._sparse_end = self._image.tell() - - # Now that we've traversed all chunks, sanity check. - if self._num_total_blocks != offset: - raise ValueError('The header said we should have {} output blocks, ' - 'but we saw {}'.format(self._num_total_blocks, offset)) - junk_len = len(self._image.read()) - if junk_len > 0: - raise ValueError('There were {} bytes of extra data at the end of the ' - 'file.'.format(junk_len)) - - # Assign |image_size|. - self.image_size = output_offset - - # This is used when bisecting in read() to find the initial slice. - self._chunk_output_offsets = [i.output_offset for i in self._chunks] - - self.is_sparse = True - - def _update_chunks_and_blocks(self): - """Helper function to update the image header. - - The the |total_chunks| and |total_blocks| fields in the header - will be set to value of the |_num_total_blocks| and - |_num_total_chunks| attributes. - - """ - self._image.seek(self.NUM_CHUNKS_AND_BLOCKS_OFFSET, os.SEEK_SET) - self._image.write(struct.pack(self.NUM_CHUNKS_AND_BLOCKS_FORMAT, - self._num_total_blocks, - self._num_total_chunks)) - - def append_dont_care(self, num_bytes): - """Appends a DONT_CARE chunk to the sparse file. - - The given number of bytes must be a multiple of the block size. - - Arguments: - num_bytes: Size in number of bytes of the DONT_CARE chunk. - """ - assert num_bytes % self.block_size == 0 - - if not self.is_sparse: - self._image.seek(0, os.SEEK_END) - # This is more efficient that writing NUL bytes since it'll add - # a hole on file systems that support sparse files (native - # sparse, not Android sparse). - self._image.truncate(self._image.tell() + num_bytes) - self._read_header() - return - - self._num_total_chunks += 1 - self._num_total_blocks += num_bytes / self.block_size - self._update_chunks_and_blocks() - - self._image.seek(self._sparse_end, os.SEEK_SET) - self._image.write(struct.pack(ImageChunk.FORMAT, - ImageChunk.TYPE_DONT_CARE, - 0, # Reserved - num_bytes / self.block_size, - struct.calcsize(ImageChunk.FORMAT))) - self._read_header() - - def append_raw(self, data): - """Appends a RAW chunk to the sparse file. - - The length of the given data must be a multiple of the block size. - - Arguments: - data: Data to append. - """ - assert len(data) % self.block_size == 0 - - if not self.is_sparse: - self._image.seek(0, os.SEEK_END) - self._image.write(data) - self._read_header() - return - - self._num_total_chunks += 1 - self._num_total_blocks += len(data) / self.block_size - self._update_chunks_and_blocks() - - self._image.seek(self._sparse_end, os.SEEK_SET) - self._image.write(struct.pack(ImageChunk.FORMAT, - ImageChunk.TYPE_RAW, - 0, # Reserved - len(data) / self.block_size, - len(data) + - struct.calcsize(ImageChunk.FORMAT))) - self._image.write(data) - self._read_header() - - def append_fill(self, fill_data, size): - """Appends a fill chunk to the sparse file. - - The total length of the fill data must be a multiple of the block size. - - Arguments: - fill_data: Fill data to append - must be four bytes. - size: Number of chunk - must be a multiple of four and the block size. - """ - assert len(fill_data) == 4 - assert size % 4 == 0 - assert size % self.block_size == 0 - - if not self.is_sparse: - self._image.seek(0, os.SEEK_END) - self._image.write(fill_data * (size/4)) - self._read_header() - return - - self._num_total_chunks += 1 - self._num_total_blocks += size / self.block_size - self._update_chunks_and_blocks() - - self._image.seek(self._sparse_end, os.SEEK_SET) - self._image.write(struct.pack(ImageChunk.FORMAT, - ImageChunk.TYPE_FILL, - 0, # Reserved - size / self.block_size, - 4 + struct.calcsize(ImageChunk.FORMAT))) - self._image.write(fill_data) - self._read_header() - - def seek(self, offset): - """Sets the cursor position for reading from unsparsified file. - - Arguments: - offset: Offset to seek to from the beginning of the file. - """ - self._file_pos = offset - - def read(self, size): - """Reads data from the unsparsified file. - - This method may return fewer than |size| bytes of data if the end - of the file was encountered. - - The file cursor for reading is advanced by the number of bytes - read. - - Arguments: - size: Number of bytes to read. - - Returns: - The data. - - """ - if not self.is_sparse: - self._image.seek(self._file_pos) - data = self._image.read(size) - self._file_pos += len(data) - return data - - # Iterate over all chunks. - chunk_idx = bisect.bisect_right(self._chunk_output_offsets, - self._file_pos) - 1 - data = bytearray() - to_go = size - while to_go > 0: - chunk = self._chunks[chunk_idx] - chunk_pos_offset = self._file_pos - chunk.output_offset - chunk_pos_to_go = min(chunk.output_size - chunk_pos_offset, to_go) - - if chunk.chunk_type == ImageChunk.TYPE_RAW: - self._image.seek(chunk.input_offset + chunk_pos_offset) - data.extend(self._image.read(chunk_pos_to_go)) - elif chunk.chunk_type == ImageChunk.TYPE_FILL: - all_data = chunk.fill_data*(chunk_pos_to_go/len(chunk.fill_data) + 2) - offset_mod = chunk_pos_offset % len(chunk.fill_data) - data.extend(all_data[offset_mod:(offset_mod + chunk_pos_to_go)]) - else: - assert chunk.chunk_type == ImageChunk.TYPE_DONT_CARE - data.extend('\0' * chunk_pos_to_go) - - to_go -= chunk_pos_to_go - self._file_pos += chunk_pos_to_go - chunk_idx += 1 - # Generate partial read in case of EOF. - if chunk_idx >= len(self._chunks): - break - - return data - - def tell(self): - """Returns the file cursor position for reading from unsparsified file. - - Returns: - The file cursor position for reading. - """ - return self._file_pos - - def truncate(self, size): - """Truncates the unsparsified file. - - Arguments: - size: Desired size of unsparsified file. - - Raises: - ValueError: If desired size isn't a multiple of the block size. - """ - if not self.is_sparse: - self._image.truncate(size) - self._read_header() - return - - if size % self.block_size != 0: - raise ValueError('Cannot truncate to a size which is not a multiple ' - 'of the block size') - - if size == self.image_size: - # Trivial where there's nothing to do. - return - elif size < self.image_size: - chunk_idx = bisect.bisect_right(self._chunk_output_offsets, size) - 1 - chunk = self._chunks[chunk_idx] - if chunk.output_offset != size: - # Truncation in the middle of a trunk - need to keep the chunk - # and modify it. - chunk_idx_for_update = chunk_idx + 1 - num_to_keep = size - chunk.output_offset - assert num_to_keep % self.block_size == 0 - if chunk.chunk_type == ImageChunk.TYPE_RAW: - truncate_at = (chunk.chunk_offset + - struct.calcsize(ImageChunk.FORMAT) + num_to_keep) - data_sz = num_to_keep - elif chunk.chunk_type == ImageChunk.TYPE_FILL: - truncate_at = (chunk.chunk_offset + - struct.calcsize(ImageChunk.FORMAT) + 4) - data_sz = 4 - else: - assert chunk.chunk_type == ImageChunk.TYPE_DONT_CARE - truncate_at = chunk.chunk_offset + struct.calcsize(ImageChunk.FORMAT) - data_sz = 0 - chunk_sz = num_to_keep/self.block_size - total_sz = data_sz + struct.calcsize(ImageChunk.FORMAT) - self._image.seek(chunk.chunk_offset) - self._image.write(struct.pack(ImageChunk.FORMAT, - chunk.chunk_type, - 0, # Reserved - chunk_sz, - total_sz)) - chunk.output_size = num_to_keep - else: - # Truncation at trunk boundary. - truncate_at = chunk.chunk_offset - chunk_idx_for_update = chunk_idx - - self._num_total_chunks = chunk_idx_for_update - self._num_total_blocks = 0 - for i in range(0, chunk_idx_for_update): - self._num_total_blocks += self._chunks[i].output_size / self.block_size - self._update_chunks_and_blocks() - self._image.truncate(truncate_at) - - # We've modified the file so re-read all data. - self._read_header() - else: - # Truncating to grow - just add a DONT_CARE section. - self.append_dont_care(size - self.image_size) - - -class GuidGenerator(object): - """An interface for obtaining strings that are GUIDs. - - To facilitate unit testing, this abstraction is used instead of the - directly using the uuid module. - """ - - def dispense_guid(self, partition_number): - """Dispenses a GUID. - - Arguments: - partition_number: The partition number or 0 if requesting a GUID - for the whole disk. - - Returns: - A RFC 4122 compliant GUID, as a string. - """ - return str(uuid.uuid4()) - - -class Partition(object): - """Object representing a partition. - - Attributes: - label: The partition label. - offset: Offset of the partition on the disk, or None. - size: Size of the partition or None if not specified. - grow: True if partition has been requested to use all remaining space. - guid: Instance GUID (RFC 4122 compliant) as a string or None or 'auto' - if it should be automatically generated. - type_guid: Type GUID (RFC 4122 compliant) as a string or a known type - from the |KNOWN_TYPE_GUIDS| map. - flags: GUID flags. - persist: If true, sets bit 0 of flags indicating that this partition should - not be deleted by the bootloader. - ab: If True, the partition is an A/B partition. - ab_expanded: If True, the A/B partitions have been generated. - ignore: If True, the partition should not be included in the final output. - position: The requested position of the partition or 0 if it doesn't matter. - """ - - def __init__(self): - """Initializer method.""" - self.label = '' - self.offset = None - self.size = None - self.grow = False - self.guid = None - self.type_guid = None - self.flags = 0 - self.persist = False - self.ab = False - self.ab_expanded = False - self.ignore = False - self.position = 0 - - def add_info(self, pobj): - """Add information to partition. - - Arguments: - pobj: A JSON object with information about the partition. - """ - self.label = pobj[JSON_KEYWORD_PARTITIONS_LABEL] - value = pobj.get(JSON_KEYWORD_PARTITIONS_OFFSET) - if value is not None: - self.offset = ParseSize(value) - value = pobj.get(JSON_KEYWORD_PARTITIONS_SIZE) - if value is not None: - self.size = ParseSize(value) - value = pobj.get(JSON_KEYWORD_PARTITIONS_GROW) - if value is not None: - self.grow = value - value = pobj.get(JSON_KEYWORD_PARTITIONS_AB) - if value is not None: - self.ab = value - value = pobj.get(JSON_KEYWORD_PARTITIONS_AB_EXPANDED) - if value is not None: - self.ab_expanded = value - value = pobj.get(JSON_KEYWORD_PARTITIONS_GUID) - if value is not None: - self.guid = value - value = pobj.get(JSON_KEYWORD_PARTITIONS_IGNORE) - if value is not None: - self.ignore = value - value = pobj.get(JSON_KEYWORD_PARTITIONS_TYPE_GUID) - if value is not None: - self.type_guid = str.lower(str(value)) - if self.type_guid in KNOWN_TYPE_GUIDS: - self.type_guid = KNOWN_TYPE_GUIDS[self.type_guid] - value = pobj.get(JSON_KEYWORD_PARTITIONS_FLAGS) - if value is not None: - self.flags = ParseNumber(value) - value = pobj.get(JSON_KEYWORD_PARTITIONS_PERSIST) - if value is not None: - self.persist = value - if value: - self.flags = self.flags | 0x1 - value = pobj.get(JSON_KEYWORD_PARTITIONS_POSITION) - if value is not None: - self.position = ParseNumber(value) - - def expand_guid(self, guid_generator, partition_number): - """Assign instance GUID and type GUID if required. - - Arguments: - guid_generator: A GuidGenerator object. - partition_number: The partition number, starting from 1. - """ - if not self.guid or self.guid == JSON_KEYWORD_AUTO: - self.guid = guid_generator.dispense_guid(partition_number) - if not self.type_guid: - self.type_guid = KNOWN_TYPE_GUIDS['brillo_vendor_specific'] - - def validate(self): - """Sanity checks data in object.""" - - try: - _ = uuid.UUID(str(self.guid)) - except ValueError: - raise ValueError('The string "{}" is not a valid GPT instance GUID on ' - 'partition with label "{}".'.format( - str(self.guid), self.label)) - - try: - _ = uuid.UUID(str(self.type_guid)) - except ValueError: - raise ValueError('The string "{}" is not a valid GPT type GUID on ' - 'partition with label "{}".'.format( - str(self.type_guid), self.label)) - - if not self.size: - if not self.grow: - raise ValueError('Size can only be unset if "grow" is True.') - - def cmp(self, other): - """Comparison method.""" - self_position = self.position - if self_position == 0: - self_position = GPT_MAX_PART_NUM - other_position = other.position - if other_position == 0: - other_position = GPT_MAX_PART_NUM - return cmp(self_position, other_position) - - -class Settings(object): - """An object for holding settings. - - Attributes: - ab_suffixes: A list of A/B suffixes to use. - disk_size: An integer with the disk size in bytes. - partitions_offset_begin: An integer with the disk partitions - offset begin size in bytes. - disk_alignment: The alignment to use for partitions. - disk_guid: The GUID to use for the disk or None or 'auto' if - automatically generated. - """ - - def __init__(self): - """Initializer with defaults.""" - self.ab_suffixes = ['_a', '_b'] - self.disk_size = None - self.partitions_offset_begin = 0 - self.disk_alignment = 4096 - self.disk_guid = JSON_KEYWORD_AUTO - - -class BptError(Exception): - """Application-specific errors. - - These errors represent issues for which a stack-trace should not be - presented. - - Attributes: - message: Error message. - """ - - def __init__(self, message): - Exception.__init__(self, message) - - -class BptParsingError(BptError): - """Represents an error with an input file. - - Attributes: - message: Error message. - filename: Name of the file that caused an error. - """ - - def __init__(self, filename, message): - self.filename = filename - BptError.__init__(self, message) - - -class Bpt(object): - """Business logic for bpttool command-line tool.""" - - def _read_json(self, input_files, ab_collapse=True): - """Parses a stack of JSON files into suitable data structures. - - The order of files matters as later files can modify partitions - declared in earlier files. - - Arguments: - input_files: An ordered list of open files. - ab_collapse: If True, collapse A/B partitions. - - Returns: - A tuple where the first element is a list of Partition objects - and the second element is a Settings object. - - Raises: - BptParsingError: If an input file has an error. - """ - partitions = [] - settings = Settings() - - # Read all input file and merge partitions and settings. - for f in input_files: - try: - obj = json.loads(f.read()) - except ValueError as e: - # Unfortunately we can't easily get the line number where the - # error occurred. - raise BptParsingError(f.name, e.message) - - sobj = obj.get(JSON_KEYWORD_SETTINGS) - if sobj: - ab_suffixes = sobj.get(JSON_KEYWORD_SETTINGS_AB_SUFFIXES) - if ab_suffixes: - settings.ab_suffixes = ab_suffixes - disk_size = sobj.get(JSON_KEYWORD_SETTINGS_DISK_SIZE) - if disk_size: - settings.disk_size = ParseSize(disk_size) - partitions_offset_begin = sobj.get( - JSON_KEYWORD_SETTINGS_PARTITIONS_OFFSET_BEGIN) - if partitions_offset_begin: - settings.partitions_offset_begin = ParseSize(partitions_offset_begin) - disk_alignment = sobj.get(JSON_KEYWORD_SETTINGS_DISK_ALIGNMENT) - if disk_alignment: - settings.disk_alignment = ParseSize(disk_alignment) - disk_guid = sobj.get(JSON_KEYWORD_SETTINGS_DISK_GUID) - if disk_guid: - settings.disk_guid = disk_guid - - pobjs = obj.get(JSON_KEYWORD_PARTITIONS) - if pobjs: - for pobj in pobjs: - if ab_collapse and pobj.get(JSON_KEYWORD_PARTITIONS_AB_EXPANDED): - # If we encounter an expanded partition, unexpand it. This - # is to make it possible to use output-JSON (from this tool) - # and stack it with an input-JSON file that e.g. specifies - # size='256 GiB' for the 'system' partition. - label = pobj[JSON_KEYWORD_PARTITIONS_LABEL] - if label.endswith(settings.ab_suffixes[0]): - # Modify first A/B copy so it doesn't have the trailing suffix. - new_len = len(label) - len(settings.ab_suffixes[0]) - pobj[JSON_KEYWORD_PARTITIONS_LABEL] = label[0:new_len] - pobj[JSON_KEYWORD_PARTITIONS_AB_EXPANDED] = False - pobj[JSON_KEYWORD_PARTITIONS_GUID] = JSON_KEYWORD_AUTO - else: - # Skip other A/B copies. - continue - # Find or create a partition. - p = None - for candidate in partitions: - if candidate.label == pobj[JSON_KEYWORD_PARTITIONS_LABEL]: - p = candidate - break - if not p: - p = Partition() - partitions.append(p) - p.add_info(pobj) - - return partitions, settings - - def _generate_json(self, partitions, settings): - """Generate a string with JSON representing partitions and settings. - - Arguments: - partitions: A list of Partition objects. - settings: A Settings object. - - Returns: - A JSON string. - """ - suffixes_str = '[' - for n in range(0, len(settings.ab_suffixes)): - if n != 0: - suffixes_str += ', ' - suffixes_str += '"{}"'.format(settings.ab_suffixes[n]) - suffixes_str += ']' - - ret = ('{{\n' - ' "' + JSON_KEYWORD_SETTINGS + '": {{\n' - ' "' + JSON_KEYWORD_SETTINGS_AB_SUFFIXES + '": {},\n' - ' "' + JSON_KEYWORD_SETTINGS_PARTITIONS_OFFSET_BEGIN + '": {},\n' - ' "' + JSON_KEYWORD_SETTINGS_DISK_SIZE + '": {},\n' - ' "' + JSON_KEYWORD_SETTINGS_DISK_ALIGNMENT + '": {},\n' - ' "' + JSON_KEYWORD_SETTINGS_DISK_GUID + '": "{}"\n' - ' }},\n' - ' "' + JSON_KEYWORD_PARTITIONS + '": [\n').format( - suffixes_str, - settings.partitions_offset_begin, - settings.disk_size, - settings.disk_alignment, - settings.disk_guid) - - for n in range(0, len(partitions)): - p = partitions[n] - ret += (' {{\n' - ' "' + JSON_KEYWORD_PARTITIONS_LABEL + '": "{}",\n' - ' "' + JSON_KEYWORD_PARTITIONS_OFFSET + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_SIZE + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_GROW + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_GUID + '": "{}",\n' - ' "' + JSON_KEYWORD_PARTITIONS_TYPE_GUID + '": "{}",\n' - ' "' + JSON_KEYWORD_PARTITIONS_FLAGS + '": "{:#018x}",\n' - ' "' + JSON_KEYWORD_PARTITIONS_PERSIST + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_IGNORE + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_AB + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_AB_EXPANDED + '": {},\n' - ' "' + JSON_KEYWORD_PARTITIONS_POSITION + '": {}\n' - ' }}{}\n').format(p.label, - p.offset, - p.size, - 'true' if p.grow else 'false', - p.guid, - p.type_guid, - p.flags, - 'true' if p.persist else 'false', - 'true' if p.ignore else 'false', - 'true' if p.ab else 'false', - 'true' if p.ab_expanded else 'false', - p.position, - '' if n == len(partitions) - 1 else ',') - ret += (' ]\n' - '}\n') - return ret - - def _lba_to_chs(self, lba): - """Converts LBA to CHS. - - Arguments: - lba: The sector number to convert. - - Returns: - An array containing the CHS encoded the way it's expected in a - MBR partition table. - """ - # See https://en.wikipedia.org/wiki/Cylinder-head-sector - num_heads = 255 - num_sectors = 63 - # If LBA isn't going to fit in CHS, return maximum CHS values. - max_lba = 255*num_heads*num_sectors - if lba > max_lba: - return [255, 255, 255] - c = lba / (num_heads*num_sectors) - h = (lba / num_sectors) % num_heads - s = lba % num_sectors - return [h, (((c>>8) & 0x03)<<6) | (s & 0x3f), c & 0xff] - - def _generate_protective_mbr(self, settings): - """Generate Protective MBR. - - Arguments: - settings: A Settings object. - - Returns: - A string with the binary protective MBR (512 bytes). - """ - # See https://en.wikipedia.org/wiki/Master_boot_record for MBR layout. - # - # The first partition starts at offset 446 (0x1be). - lba_start = 1 - lba_end = settings.disk_size/DISK_SECTOR_SIZE - 1 - start_chs = self._lba_to_chs(lba_start) - end_chs = self._lba_to_chs(lba_end) - pmbr = struct.pack('<446s' # Bootloader code - 'B' # Status. - 'BBB' # CHS start. - 'B' # Partition type. - 'BBB' # CHS end. - 'I' # LBA of partition start. - 'I' # Number of sectors in partition. - '48x' # Padding to get to offset 510 (0x1fe). - 'BB', # Boot signature. - '\xfa\xeb\xfe', # cli ; jmp $ (x86) - 0x00, - start_chs[0], start_chs[1], start_chs[2], - 0xee, # MBR Partition Type: GPT protective MBR. - end_chs[0], end_chs[1], end_chs[2], - 1, # LBA start - lba_end, - 0x55, 0xaa) - return pmbr - - def _generate_gpt(self, partitions, settings, primary=True): - """Generate GUID Partition Table. - - Arguments: - partitions: A list of Partition objects. - settings: A Settings object. - primary: True to generate primary GPT, False to generate secondary. - - Returns: - A string with the binary GUID Partition Table (33*512 bytes). - """ - # See https://en.wikipedia.org/wiki/Master_boot_record for MBR layout. - # - # The first partition starts at offset 446 (0x1be). - - disk_num_lbas = settings.disk_size/DISK_SECTOR_SIZE - if primary: - current_lba = 1 - other_lba = disk_num_lbas - 1 - partitions_lba = 2 - else: - current_lba = disk_num_lbas - 1 - other_lba = 1 - partitions_lba = disk_num_lbas - GPT_NUM_LBAS - first_usable_lba = GPT_NUM_LBAS + 1 - last_usable_lba = disk_num_lbas - GPT_NUM_LBAS - 1 - - part_array = [] - for p in partitions: - part_array.append(struct.pack( - '<16s' # Partition type GUID. - '16s' # Partition instance GUID. - 'QQ' # First and last LBA. - 'Q' # Flags. - '72s', # Name (36 UTF-16LE code units). - uuid.UUID(p.type_guid).get_bytes_le(), - uuid.UUID(p.guid).get_bytes_le(), - p.offset/DISK_SECTOR_SIZE, - (p.offset + p.size)/DISK_SECTOR_SIZE - 1, - p.flags, - p.label.encode(encoding='utf-16le'))) - - part_array.append(((128 - len(partitions))*128) * '\0') - part_array_str = ''.join(part_array) - - partitions_crc32 = zlib.crc32(part_array_str) % (1<<32) - - header_crc32 = 0 - while True: - header = struct.pack( - '<8s' # Signature. - '4B' # Version. - 'I' # Header size. - 'I' # CRC32 (must be zero during calculation). - 'I' # Reserved (must be zero). - 'QQ' # Current and Other LBA. - 'QQ' # First and last usable LBA. - '16s' # Disk GUID. - 'Q' # Starting LBA of array of partitions. - 'I' # Number of partitions. - 'I' # Partition entry size, in bytes. - 'I' # CRC32 of partition array - '420x', # Padding to get to 512 bytes. - 'EFI PART', - 0x00, 0x00, 0x01, 0x00, - 92, - header_crc32, - 0x00000000, - current_lba, other_lba, - first_usable_lba, last_usable_lba, - uuid.UUID(settings.disk_guid).get_bytes_le(), - partitions_lba, - 128, - 128, - partitions_crc32) - if header_crc32 != 0: - break - header_crc32 = zlib.crc32(header[0:92]) % (1<<32) - - if primary: - return header + part_array_str - else: - return part_array_str + header - - def _generate_gpt_bin(self, partitions, settings): - """Generate a bytearray representing partitions and settings. - - The blob will have three partition tables, laid out one after - another: 1) Protective MBR (512 bytes); 2) Primary GPT (33*512 - bytes); and 3) Secondary GPT (33*512 bytes). - - The total size will be 34,304 bytes. - - Arguments: - partitions: A list of Partition objects. - settings: A Settings object. - - Returns: - A bytearray() object. - """ - protective_mbr = self._generate_protective_mbr(settings) - primary_gpt = self._generate_gpt(partitions, settings) - secondary_gpt = self._generate_gpt(partitions, settings, primary=False) - ret = protective_mbr + primary_gpt + secondary_gpt - return ret - - def _validate_disk_partitions(self, partitions, disk_size): - """Check that a list of partitions have assigned offsets and fits on a - disk of a given size. - - This function checks partition offsets and sizes to see if they may fit on - a disk image. - - Arguments: - partitions: A list of Partition objects. - settings: Integer size of disk image. - - Raises: - BptError: If checked condition is not satisfied. - """ - for p in partitions: - if not p.offset or p.offset < (GPT_NUM_LBAS + 1)*DISK_SECTOR_SIZE: - raise BptError('Partition with label "{}" has no offset.' - .format(p.label)) - if not p.size or p.size < 0: - raise BptError('Partition with label "{}" has no size.' - .format(p.label)) - if (p.offset + p.size) > (disk_size - GPT_NUM_LBAS*DISK_SECTOR_SIZE): - raise BptError('Partition with label "{}" exceeds the disk ' - 'image size.'.format(p.label)) - - def make_table(self, - inputs, - ab_suffixes=None, - partitions_offset_begin=None, - disk_size=None, - disk_alignment=None, - disk_guid=None, - guid_generator=None): - """Implementation of the 'make_table' command. - - This function takes a list of input partition definition files, - flattens them, expands A/B partitions, grows partitions, and lays - out partitions according to alignment constraints. - - Arguments: - inputs: List of JSON files to parse. - ab_suffixes: List of the A/B suffixes (as a comma-separated string) - to use or None to not override. - partitions_offset_begin: Size of disk partitions offset - begin or None to not override. - disk_size: Size of disk or None to not override. - disk_alignment: Disk alignment or None to not override. - disk_guid: Disk GUID as a string or None to not override. - guid_generator: A GuidGenerator or None to use the default. - - Returns: - A tuple where the first argument is a JSON string for the resulting - partitions and the second argument is the binary partition tables. - - Raises: - BptParsingError: If an input file has an error. - BptError: If another application-specific error occurs - """ - partitions, settings = self._read_json(inputs) - - # Command-line arguments override anything specified in input - # files. - if disk_size: - settings.disk_size = int(math.ceil(disk_size)) - if disk_alignment: - settings.disk_alignment = int(disk_alignment) - if partitions_offset_begin: - settings.partitions_offset_begin = int(partitions_offset_begin) - if ab_suffixes: - settings.ab_suffixes = ab_suffixes.split(',') - if disk_guid: - settings.disk_guid = disk_guid - - if not guid_generator: - guid_generator = GuidGenerator() - - # We need to know the disk size. Also round it down to ensure it's - # a multiple of the sector size. - if not settings.disk_size: - raise BptError('Disk size not specified. Use --disk_size option ' - 'or specify it in an input file.\n') - settings.disk_size = RoundToMultiple(settings.disk_size, - DISK_SECTOR_SIZE, - round_down=True) - - # Alignment must be divisible by disk sector size. - if settings.disk_alignment % DISK_SECTOR_SIZE != 0: - raise BptError( - 'Disk alignment size of {} is not divisible by {}.\n'.format( - settings.disk_alignment, DISK_SECTOR_SIZE)) - - if settings.partitions_offset_begin != 0: - # Disk partitions offset begin size must be - # divisible by disk sector size. - if settings.partitions_offset_begin % settings.disk_alignment != 0: - raise BptError( - 'Disk Partitions offset begin size of {} ' - 'is not divisible by {}.\n'.format( - settings.partitions_offset_begin, settings.disk_alignment)) - settings.partitions_offset_begin = max(settings.partitions_offset_begin, - DISK_SECTOR_SIZE*(1 + GPT_NUM_LBAS)) - settings.partitions_offset_begin = RoundToMultiple( - settings.partitions_offset_begin, settings.disk_alignment) - - # Expand A/B partitions and skip ignored partitions. - expanded_partitions = [] - for p in partitions: - if p.ignore: - continue - if p.ab and not p.ab_expanded: - p.ab_expanded = True - for suffix in settings.ab_suffixes: - new_p = copy.deepcopy(p) - new_p.label += suffix - expanded_partitions.append(new_p) - else: - expanded_partitions.append(p) - partitions = expanded_partitions - - # Expand Disk GUID if needed. - if not settings.disk_guid or settings.disk_guid == JSON_KEYWORD_AUTO: - settings.disk_guid = guid_generator.dispense_guid(0) - - # Sort according to 'position' attribute. - partitions = sorted(partitions, cmp=lambda x, y: x.cmp(y)) - - # Automatically generate GUIDs if the GUID is unset or set to - # 'auto'. Also validate the rest of the fields. - part_no = 1 - for p in partitions: - p.expand_guid(guid_generator, part_no) - p.validate() - part_no += 1 - - # Idenfify partition to grow and lay out partitions, ignoring the - # one to grow. This way we can figure out how much space is left. - # - # Right now we only support a single 'grow' partition but we could - # support more in the future by splitting up the available bytes - # between them. - grow_part = None - # offset minimal size: DISK_SECTOR_SIZE*(1 + GPT_NUM_LBAS) - offset = max(settings.partitions_offset_begin, - DISK_SECTOR_SIZE*(1 + GPT_NUM_LBAS)) - for p in partitions: - if p.grow: - if grow_part: - raise BptError('Only a single partition can be automatically ' - 'grown.\n') - grow_part = p - else: - # Ensure size is a multiple of DISK_SECTOR_SIZE by rounding up - # (user may specify it as e.g. "1.5 GB" which is not divisible - # by 512). - p.size = RoundToMultiple(p.size, DISK_SECTOR_SIZE) - # Align offset to disk alignment. - offset = RoundToMultiple(offset, settings.disk_alignment) - offset += p.size - - # After laying out (respecting alignment) all non-grow - # partitions, check that the given disk size is big enough. - if offset > settings.disk_size - DISK_SECTOR_SIZE*GPT_NUM_LBAS: - raise BptError('Disk size of {} bytes is too small for partitions ' - 'totaling {} bytes.\n'.format( - settings.disk_size, offset)) - - # If we have a grow partition, it'll starts at the next - # available alignment offset and we can calculate its size as - # follows. - if grow_part: - offset = RoundToMultiple(offset, settings.disk_alignment) - grow_part.size = RoundToMultiple( - settings.disk_size - DISK_SECTOR_SIZE*GPT_NUM_LBAS - offset, - settings.disk_alignment, - round_down=True) - if grow_part.size < DISK_SECTOR_SIZE: - raise BptError('Not enough space for partition "{}" to be ' - 'automatically grown.\n'.format(grow_part.label)) - - # Now we can assign partition start offsets for all partitions, - # including the grow partition. - # offset minimal size: DISK_SECTOR_SIZE*(1 + GPT_NUM_LBAS) - offset = max(settings.partitions_offset_begin, - DISK_SECTOR_SIZE*(1 + GPT_NUM_LBAS)) - for p in partitions: - # Align offset. - offset = RoundToMultiple(offset, settings.disk_alignment) - p.offset = offset - offset += p.size - assert offset <= settings.disk_size - DISK_SECTOR_SIZE*GPT_NUM_LBAS - - json_str = self._generate_json(partitions, settings) - - gpt_bin = self._generate_gpt_bin(partitions, settings) - - return json_str, gpt_bin - - def make_disk_image(self, output, bpt, images, allow_empty_partitions=False): - """Implementation of the 'make_disk_image' command. - - This function takes in a list of partitions images and a bpt file - for the purpose of creating a raw disk image with a protective MBR, - primary and secondary GPT, and content for each partition as specified. - - Arguments: - output: Output file where disk image is to be written to. - bpt: BPT JSON file to parse. - images: List of partition image paths to be combined (as specified by - bpt). Each element is of the form. - 'PARTITION_NAME:/PATH/TO/PARTITION_IMAGE' - allow_empty_partitions: If True, partitions defined in |bpt| need not to - be present in |images|. Otherwise an exception is - thrown if a partition is referenced in |bpt| but - not in |images|. - - Raises: - BptParsingError: If an image file has an error. - BptError: If another application-specific error occurs. - """ - # Generate partition list and settings. - partitions, settings = self._read_json([bpt], ab_collapse=False) - - # Validated partition sizes and offsets. - self._validate_disk_partitions(partitions, settings.disk_size) - - # Sort according to 'offset' attribute. - partitions = sorted(partitions, cmp=lambda x, y: cmp(x.offset, y.offset)) - - # Create necessary tables. - protective_mbr = self._generate_protective_mbr(settings) - primary_gpt = self._generate_gpt(partitions, settings) - secondary_gpt = self._generate_gpt(partitions, settings, primary=False) - - # Start at 0 offset for mbr and primary gpt. - output.seek(0) - output.write(protective_mbr) - output.write(primary_gpt) - - # Create mapping of partition name to partition image file. - image_file_names = {} - try: - for name_path in images: - name, path = name_path.split(":") - image_file_names[name] = path - except ValueError as e: - raise BptParsingError(name_path, 'Bad image argument {}.'.format( - images[i])) - - # Read image and insert in correct offset. - for p in partitions: - if p.label not in image_file_names: - if allow_empty_partitions: - continue - else: - raise BptParsingError(bpt.name, 'No content specified for partition' - ' with label {}'.format(p.label)) - - input_image = ImageHandler(image_file_names[p.label]) - output.seek(p.offset) - partition_blob = input_image.read(p.size) - output.write(partition_blob) - - # Put secondary GPT and end of disk. - output.seek(settings.disk_size - len(secondary_gpt)) - output.write(secondary_gpt) - - def query_partition(self, input_file, part_label, query_type, ab_collapse): - """Implementation of the 'query_partition' command. - - This reads the partition definition file given by |input_file| and - returns information of type |query_type| for the partition with - label |part_label|. - - Arguments: - input_file: A JSON file to parse. - part_label: Label of partition to query information about. - query_type: The information to query, see |QUERY_PARTITION_TYPES|. - ab_collapse: If True, collapse A/B partitions. - - Returns: - The requested information as a string or None if there is no - partition with the given label. - - Raises: - BptParsingError: If an input file has an error. - BptError: If another application-specific error occurs - """ - - partitions, _ = self._read_json([input_file], ab_collapse) - - part = None - for p in partitions: - if p.label == part_label: - part = p - break - - if not part: - return None - - value = part.__dict__.get(query_type) - # Print out flags as a hex-value. - if query_type == 'flags': - return '{:#018x}'.format(value) - return str(value) - - -class BptTool(object): - """Object for bpttool command-line tool.""" - - def __init__(self): - """Initializer method.""" - self.bpt = Bpt() - - def run(self, argv): - """Command-line processor. - - Arguments: - argv: Pass sys.argv from main. - """ - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(title='subcommands') - - sub_parser = subparsers.add_parser( - 'version', - help='Prints version of bpttool.') - sub_parser.set_defaults(func=self.version) - - sub_parser = subparsers.add_parser( - 'make_table', - help='Lays out partitions and creates partition table.') - sub_parser.add_argument('--input', - help='Path to partition definition file.', - type=argparse.FileType('r'), - action='append') - sub_parser.add_argument('--ab_suffixes', - help='Set or override A/B suffixes.') - sub_parser.add_argument('--partitions_offset_begin', - help='Set or override disk partitions ' - 'offset begin size.', - type=ParseSize) - sub_parser.add_argument('--disk_size', - help='Set or override disk size.', - type=ParseSize) - sub_parser.add_argument('--disk_alignment', - help='Set or override disk alignment.', - type=ParseSize) - sub_parser.add_argument('--disk_guid', - help='Set or override disk GUID.', - type=ParseGuid) - sub_parser.add_argument('--output_json', - help='JSON output file name.', - type=argparse.FileType('w')) - sub_parser.add_argument('--output_gpt', - help='Output file name for MBR/GPT/GPT file.', - type=argparse.FileType('w')) - sub_parser.set_defaults(func=self.make_table) - - sub_parser = subparsers.add_parser( - 'make_disk_image', - help='Creates disk image for loaded with partitions.') - sub_parser.add_argument('--output', - help='Path to image output.', - type=argparse.FileType('w'), - required=True) - sub_parser.add_argument('--input', - help='Path to bpt file input.', - type=argparse.FileType('r'), - required=True) - sub_parser.add_argument('--image', - help='Partition name and path to image file.', - metavar='PARTITION_NAME:PATH', - action='append') - sub_parser.add_argument('--allow_empty_partitions', - help='Allow skipping partitions in bpt file.', - action='store_true') - sub_parser.set_defaults(func=self.make_disk_image) - - sub_parser = subparsers.add_parser( - 'query_partition', - help='Looks up informtion about a partition.') - sub_parser.add_argument('--input', - help='Path to partition definition file.', - type=argparse.FileType('r'), - required=True) - sub_parser.add_argument('--label', - help='Label of partition to look up.', - required=True) - sub_parser.add_argument('--ab_collapse', - help='Collapse A/B partitions.', - action='store_true') - sub_parser.add_argument('--type', - help='Type of information to look up.', - choices=QUERY_PARTITION_TYPES, - required=True) - sub_parser.set_defaults(func=self.query_partition) - - args = parser.parse_args(argv[1:]) - args.func(args) - - def version(self, _): - """Implements the 'version' sub-command.""" - print '{}.{}'.format(BPT_VERSION_MAJOR, BPT_VERSION_MINOR) - - def query_partition(self, args): - """Implements the 'query_partition' sub-command.""" - try: - result = self.bpt.query_partition(args.input, - args.label, - args.type, - args.ab_collapse) - except BptParsingError as e: - sys.stderr.write('{}: Error parsing: {}\n'.format(e.filename, e.message)) - sys.exit(1) - except BptError as e: - sys.stderr.write('{}\n'.format(e.message)) - sys.exit(1) - - if not result: - sys.stderr.write('No partition with label "{}".\n'.format(args.label)) - sys.exit(1) - - print result - - def make_table(self, args): - """Implements the 'make_table' sub-command.""" - if not args.input: - sys.stderr.write('Option --input is required one or more times.\n') - sys.exit(1) - - try: - (json_str, gpt_bin) = self.bpt.make_table(args.input, args.ab_suffixes, - args.partitions_offset_begin, - args.disk_size, - args.disk_alignment, - args.disk_guid) - except BptParsingError as e: - sys.stderr.write('{}: Error parsing: {}\n'.format(e.filename, e.message)) - sys.exit(1) - except BptError as e: - sys.stderr.write('{}\n'.format(e.message)) - sys.exit(1) - - if args.output_json: - args.output_json.write(json_str) - if args.output_gpt: - args.output_gpt.write(gpt_bin) - - def make_disk_image(self, args): - """Implements the 'make_disk_image' sub-command.""" - if not args.input: - sys.stderr.write('Option --input is required.\n') - sys.exit(1) - if not args.output: - sys.stderr.write('Option --ouptut is required.\n') - sys.exit(1) - - try: - self.bpt.make_disk_image(args.output, - args.input, - args.image, - args.allow_empty_partitions) - except BptParsingError as e: - sys.stderr.write('{}: Error parsing: {}\n'.format(e.filename, e.message)) - sys.exit(1) - except 'BptError' as e: - sys.stderr.write('{}\n'.format(e.message)) - sys.exit(1) - -if __name__ == '__main__': - tool = BptTool() - tool.run(sys.argv) diff --git a/host/commands/assemble_cvd/data_image.cc b/host/commands/assemble_cvd/data_image.cc deleted file mode 100644 index 82dad14b..00000000 --- a/host/commands/assemble_cvd/data_image.cc +++ /dev/null @@ -1,149 +0,0 @@ -#include "host/commands/assemble_cvd/data_image.h" - -#include <glog/logging.h> - -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" - -namespace { -const std::string kDataPolicyUseExisting = "use_existing"; -const std::string kDataPolicyCreateIfMissing = "create_if_missing"; -const std::string kDataPolicyAlwaysCreate = "always_create"; -const std::string kDataPolicyResizeUpTo= "resize_up_to"; - -const int FSCK_ERROR_CORRECTED = 1; -const int FSCK_ERROR_CORRECTED_REQUIRES_REBOOT = 2; - -bool ForceFsckImage(const char* data_image) { - int fsck_status = cvd::execute({"/sbin/e2fsck", "-y", "-f", data_image}); - if (fsck_status & ~(FSCK_ERROR_CORRECTED|FSCK_ERROR_CORRECTED_REQUIRES_REBOOT)) { - LOG(ERROR) << "`e2fsck -y -f " << data_image << "` failed with code " - << fsck_status; - return false; - } - return true; -} - -bool ResizeImage(const char* data_image, int data_image_mb) { - auto file_mb = cvd::FileSize(data_image) >> 20; - if (file_mb > data_image_mb) { - LOG(ERROR) << data_image << " is already " << file_mb << " MB, will not " - << "resize down."; - return false; - } else if (file_mb == data_image_mb) { - LOG(INFO) << data_image << " is already the right size"; - return true; - } else { - off_t raw_target = static_cast<off_t>(data_image_mb) << 20; - int truncate_status = - cvd::SharedFD::Open(data_image, O_RDWR)->Truncate(raw_target); - if (truncate_status != 0) { - LOG(ERROR) << "`truncate --size=" << data_image_mb << "M " - << data_image << "` failed with code " << truncate_status; - return false; - } - bool fsck_success = ForceFsckImage(data_image); - if (!fsck_success) { - return false; - } - int resize_status = cvd::execute({"/sbin/resize2fs", data_image}); - if (resize_status != 0) { - LOG(ERROR) << "`resize2fs " << data_image << "` failed with code " - << resize_status; - return false; - } - fsck_success = ForceFsckImage(data_image); - if (!fsck_success) { - return false; - } - } - return true; -} -} // namespace - -void CreateBlankImage( - const std::string& image, int image_mb, const std::string& image_fmt) { - LOG(INFO) << "Creating " << image; - std::string of = "of="; - of += image; - std::string count = "count="; - count += std::to_string(image_mb); - cvd::execute({"/bin/dd", "if=/dev/zero", of, "bs=1M", count}); - if (image_fmt != "none") { - cvd::execute({"/sbin/mkfs", "-t", image_fmt, image}, {"PATH=/sbin"}); - } -} - -bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config, - const std::string& data_image) { - bool data_exists = cvd::FileHasContent(data_image.c_str()); - bool remove{}; - bool create{}; - bool resize{}; - - if (config.data_policy() == kDataPolicyUseExisting) { - if (!data_exists) { - LOG(ERROR) << "Specified data image file does not exists: " << data_image; - return false; - } - if (config.blank_data_image_mb() > 0) { - LOG(ERROR) << "You should NOT use -blank_data_image_mb with -data_policy=" - << kDataPolicyUseExisting; - return false; - } - create = false; - remove = false; - resize = false; - } else if (config.data_policy() == kDataPolicyAlwaysCreate) { - remove = data_exists; - create = true; - resize = false; - } else if (config.data_policy() == kDataPolicyCreateIfMissing) { - create = !data_exists; - remove = false; - resize = false; - } else if (config.data_policy() == kDataPolicyResizeUpTo) { - create = false; - remove = false; - resize = true; - } else { - LOG(ERROR) << "Invalid data_policy: " << config.data_policy(); - return false; - } - - if (remove) { - cvd::RemoveFile(data_image.c_str()); - } - - if (create) { - if (config.blank_data_image_mb() <= 0) { - LOG(ERROR) << "-blank_data_image_mb is required to create data image"; - return false; - } - CreateBlankImage(data_image.c_str(), config.blank_data_image_mb(), - config.blank_data_image_fmt()); - } else if (resize) { - if (!data_exists) { - LOG(ERROR) << data_image << " does not exist, but resizing was requested"; - return false; - } - return ResizeImage(data_image.c_str(), config.blank_data_image_mb()); - } else { - LOG(INFO) << data_image << " exists. Not creating it."; - } - - return true; -} - -bool InitializeMiscImage(const std::string& misc_image) { - bool misc_exists = cvd::FileHasContent(misc_image.c_str()); - - if (misc_exists) { - LOG(INFO) << "misc partition image: use existing"; - return true; - } - - LOG(INFO) << "misc partition image: creating empty"; - CreateBlankImage(misc_image, 1 /* mb */, "none"); - return true; -} diff --git a/host/commands/assemble_cvd/data_image.h b/host/commands/assemble_cvd/data_image.h deleted file mode 100644 index aed01c3a..00000000 --- a/host/commands/assemble_cvd/data_image.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include <string> - -#include "host/libs/config/cuttlefish_config.h" - -bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config, - const std::string& path); -bool InitializeMiscImage(const std::string& misc_image); -void CreateBlankImage( - const std::string& image, int image_mb, const std::string& image_fmt); diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc deleted file mode 100644 index 2d6007ef..00000000 --- a/host/commands/assemble_cvd/flags.cc +++ /dev/null @@ -1,758 +0,0 @@ -#include "host/commands/assemble_cvd/flags.h" - -#include <iostream> -#include <fstream> - -#include <android-base/strings.h> -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/utils/environment.h" -#include "common/libs/utils/files.h" -#include "host/commands/assemble_cvd/boot_image_unpacker.h" -#include "host/commands/assemble_cvd/data_image.h" -#include "host/commands/assemble_cvd/image_aggregator.h" -#include "host/commands/assemble_cvd/assembler_defs.h" -#include "host/commands/assemble_cvd/super_image_mixer.h" -#include "host/libs/config/fetcher_config.h" -#include "host/libs/vm_manager/crosvm_manager.h" -#include "host/libs/vm_manager/qemu_manager.h" -#include "host/libs/vm_manager/vm_manager.h" - -using vsoc::GetPerInstanceDefault; -using cvd::AssemblerExitCodes; - -DEFINE_string(cache_image, "", "Location of the cache partition image."); -DEFINE_string(metadata_image, "", "Location of the metadata partition image " - "to be generated."); -DEFINE_int32(blank_metadata_image_mb, 16, - "The size of the blank metadata image to generate, MB."); -DEFINE_int32(cpus, 2, "Virtual CPU count."); -DEFINE_string(data_image, "", "Location of the data partition image."); -DEFINE_string(data_policy, "use_existing", "How to handle userdata partition." - " Either 'use_existing', 'create_if_missing', 'resize_up_to', or " - "'always_create'."); -DEFINE_int32(blank_data_image_mb, 0, - "The size of the blank data image to generate, MB."); -DEFINE_string(blank_data_image_fmt, "ext4", - "The fs format for the blank data image. Used with mkfs."); -DEFINE_string(qemu_gdb, "", - "Debug flag to pass to qemu. e.g. -qemu_gdb=tcp::1234"); - -DEFINE_int32(x_res, 720, "Width of the screen in pixels"); -DEFINE_int32(y_res, 1280, "Height of the screen in pixels"); -DEFINE_int32(dpi, 160, "Pixels per inch for the screen"); -DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz"); -DEFINE_int32(num_screen_buffers, 3, "The number of screen buffers"); -DEFINE_string(kernel_path, "", - "Path to the kernel. Overrides the one from the boot image"); -DEFINE_string(initramfs_path, "", "Path to the initramfs"); -DEFINE_bool(decompress_kernel, false, - "Whether to decompress the kernel image."); -DEFINE_string(kernel_decompresser_executable, - vsoc::DefaultHostArtifactsPath("bin/extract-vmlinux"), - "Path to the extract-vmlinux executable."); -DEFINE_string(extra_kernel_cmdline, "", - "Additional flags to put on the kernel command line"); -DEFINE_int32(loop_max_part, 7, "Maximum number of loop partitions"); -DEFINE_bool(guest_enforce_security, true, - "Whether to run in enforcing mode (non permissive)."); -DEFINE_bool(guest_audit_security, true, - "Whether to log security audits."); -DEFINE_string(boot_image, "", - "Location of cuttlefish boot image. If empty it is assumed to be " - "boot.img in the directory specified by -system_image_dir."); -DEFINE_string(vendor_boot_image, "", - "Location of cuttlefish vendor boot image. If empty it is assumed to " - "be vendor_boot.img in the directory specified by -system_image_dir."); -DEFINE_int32(memory_mb, 2048, - "Total amount of memory available for guest, MB."); -DEFINE_string(mobile_interface, GetPerInstanceDefault("cvd-mbr-"), - "Network interface to use for mobile networking"); -DEFINE_string(mobile_tap_name, GetPerInstanceDefault("cvd-mtap-"), - "The name of the tap interface to use for mobile"); -DEFINE_string(serial_number, GetPerInstanceDefault("CUTTLEFISHCVD"), - "Serial number to use for the device"); -DEFINE_string(instance_dir, "", // default handled on ParseCommandLine - "A directory to put all instance specific files"); -DEFINE_string( - vm_manager, vm_manager::CrosvmManager::name(), - "What virtual machine manager to use, one of {qemu_cli, crosvm}"); -DEFINE_string( - gpu_mode, vsoc::kGpuModeGuestSwiftshader, - "What gpu configuration to use, one of {guest_swiftshader, drm_virgl}"); -DEFINE_string(wayland_socket, "", - "Location of the wayland socket to use for drm_virgl gpu_mode."); -DEFINE_string(x_display, "", - "X display to use for drm_virgl gpu_mode."); - -DEFINE_string(system_image_dir, vsoc::DefaultGuestImagePath(""), - "Location of the system partition images."); -DEFINE_string(super_image, "", "Location of the super partition image."); -DEFINE_string(misc_image, "", - "Location of the misc partition image. If the image does not " - "exist, a blank new misc partition image is created."); -DEFINE_string(composite_disk, "", "Location of the composite disk image. " - "If empty, a composite disk is not used."); - -DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to" - " host kernel. This is only used during transition of our clients." - " Will be deprecated soon."); -DEFINE_bool(start_vnc_server, true, "Whether to start the vnc server process."); -DEFINE_string(vnc_server_binary, - vsoc::DefaultHostArtifactsPath("bin/vnc_server"), - "Location of the vnc server binary."); -DEFINE_string(virtual_usb_manager_binary, - vsoc::DefaultHostArtifactsPath("bin/virtual_usb_manager"), - "Location of the virtual usb manager binary."); -DEFINE_string(kernel_log_monitor_binary, - vsoc::DefaultHostArtifactsPath("bin/kernel_log_monitor"), - "Location of the log monitor binary."); -DEFINE_int32(vnc_server_port, GetPerInstanceDefault(6444), - "The port on which the vnc server should listen"); -DEFINE_string(socket_forward_proxy_binary, - vsoc::DefaultHostArtifactsPath("bin/socket_forward_proxy"), - "Location of the socket_forward_proxy binary."); -DEFINE_string(socket_vsock_proxy_binary, - vsoc::DefaultHostArtifactsPath("bin/socket_vsock_proxy"), - "Location of the socket_vsock_proxy binary."); -DEFINE_string(adb_mode, "vsock_half_tunnel", - "Mode for ADB connection. Can be 'usb' for USB forwarding, " - "'tunnel' for a TCP connection tunneled through VSoC, " - "'vsock_tunnel' for a TCP connection tunneled through vsock, " - "'native_vsock' for a direct connection to the guest ADB over " - "vsock, 'vsock_half_tunnel' for a TCP connection forwarded to " - "the guest ADB server, or a comma separated list of types as in " - "'usb,tunnel'"); -DEFINE_bool(run_adb_connector, true, - "Maintain adb connection by sending 'adb connect' commands to the " - "server. Only relevant with -adb_mode=tunnel or vsock_tunnel"); -DEFINE_string(adb_connector_binary, - vsoc::DefaultHostArtifactsPath("bin/adb_connector"), - "Location of the adb_connector binary. Only relevant if " - "-run_adb_connector is true"); -DEFINE_int32(vhci_port, GetPerInstanceDefault(0), "VHCI port to use for usb"); -DEFINE_string(wifi_tap_name, GetPerInstanceDefault("cvd-wtap-"), - "The name of the tap interface to use for wifi"); -DEFINE_int32(vsock_guest_cid, - vsoc::GetDefaultPerInstanceVsockCid(), - "Guest identifier for vsock. Disabled if under 3."); - -DEFINE_string(uuid, vsoc::GetPerInstanceDefault(vsoc::kDefaultUuidPrefix), - "UUID to use for the device. Random if not specified"); -DEFINE_bool(daemon, false, - "Run cuttlefish in background, the launcher exits on boot " - "completed/failed"); - -DEFINE_string(device_title, "", "Human readable name for the instance, " - "used by the vnc_server for its server title"); -DEFINE_string(setupwizard_mode, "DISABLED", - "One of DISABLED,OPTIONAL,REQUIRED"); - -DEFINE_string(qemu_binary, - "/usr/bin/qemu-system-x86_64", - "The qemu binary to use"); -DEFINE_string(crosvm_binary, - vsoc::DefaultHostArtifactsPath("bin/crosvm"), - "The Crosvm binary to use"); -DEFINE_string(console_forwarder_binary, - vsoc::DefaultHostArtifactsPath("bin/console_forwarder"), - "The Console Forwarder binary to use"); -DEFINE_bool(restart_subprocesses, true, "Restart any crashed host process"); -DEFINE_string(logcat_receiver_binary, - vsoc::DefaultHostArtifactsPath("bin/logcat_receiver"), - "Binary for the logcat server"); -DEFINE_string(logcat_mode, "", "How to send android's log messages from " - "guest to host. One of [serial, vsock]"); -DEFINE_int32(logcat_vsock_port, vsoc::GetPerInstanceDefault(5620), - "The port for logcat over vsock"); -DEFINE_string(config_server_binary, - vsoc::DefaultHostArtifactsPath("bin/config_server"), - "Binary for the configuration server"); -DEFINE_int32(config_server_port, vsoc::GetPerInstanceDefault(4680), - "The (vsock) port for the configuration server"); -DEFINE_int32(frames_vsock_port, vsoc::GetPerInstanceDefault(5580), - "The vsock port to receive frames from the guest on"); -DEFINE_bool(enable_tombstone_receiver, true, "Enables the tombstone logger on " - "both the guest and the host"); -DEFINE_string(tombstone_receiver_binary, - vsoc::DefaultHostArtifactsPath("bin/tombstone_receiver"), - "Binary for the tombstone server"); -DEFINE_int32(tombstone_receiver_port, vsoc::GetPerInstanceDefault(5630), - "The vsock port for tombstones"); -DEFINE_int32(keyboard_server_port, GetPerInstanceDefault(5540), - "The port on which the vsock keyboard server should listen"); -DEFINE_int32(touch_server_port, GetPerInstanceDefault(5640), - "The port on which the vsock touch server should listen"); -DEFINE_bool(use_bootloader, false, "Boots the device using a bootloader"); -DEFINE_string(bootloader, "", "Bootloader binary path"); -DEFINE_string(boot_slot, "", "Force booting into the given slot. If empty, " - "the slot will be chosen based on the misc partition if using a " - "bootloader. It will default to 'a' if empty and not using a " - "bootloader."); - -namespace { - -const std::string kKernelDefaultPath = "kernel"; -const std::string kInitramfsImg = "initramfs.img"; -const std::string kRamdiskConcatExt = ".concat"; - -bool ResolveInstanceFiles() { - if (FLAGS_system_image_dir.empty()) { - LOG(ERROR) << "--system_image_dir must be specified."; - return false; - } - - // If user did not specify location of either of these files, expect them to - // be placed in --system_image_dir location. - std::string default_boot_image = FLAGS_system_image_dir + "/boot.img"; - SetCommandLineOptionWithMode("boot_image", default_boot_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_cache_image = FLAGS_system_image_dir + "/cache.img"; - SetCommandLineOptionWithMode("cache_image", default_cache_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_data_image = FLAGS_system_image_dir + "/userdata.img"; - SetCommandLineOptionWithMode("data_image", default_data_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_metadata_image = FLAGS_system_image_dir + "/metadata.img"; - SetCommandLineOptionWithMode("metadata_image", default_metadata_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_super_image = FLAGS_system_image_dir + "/super.img"; - SetCommandLineOptionWithMode("super_image", default_super_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_misc_image = FLAGS_system_image_dir + "/misc.img"; - SetCommandLineOptionWithMode("misc_image", default_misc_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_composite_disk = FLAGS_system_image_dir + "/composite.img"; - SetCommandLineOptionWithMode("composite_disk", default_composite_disk.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - std::string default_vendor_boot_image = FLAGS_system_image_dir - + "/vendor_boot.img"; - SetCommandLineOptionWithMode("vendor_boot_image", - default_vendor_boot_image.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - - return true; -} - -std::string GetCuttlefishEnvPath() { - return cvd::StringFromEnv("HOME", ".") + "/.cuttlefish.sh"; -} - -int GetHostPort() { - constexpr int kFirstHostPort = 6520; - return vsoc::GetPerInstanceDefault(kFirstHostPort); -} - -// Initializes the config object and saves it to file. It doesn't return it, all -// further uses of the config should happen through the singleton -bool InitializeCuttlefishConfiguration( - const cvd::BootImageUnpacker& boot_image_unpacker, - const cvd::FetcherConfig& fetcher_config) { - vsoc::CuttlefishConfig tmp_config_obj; - // Set this first so that calls to PerInstancePath below are correct - tmp_config_obj.set_instance_dir(FLAGS_instance_dir); - if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) { - LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager; - return false; - } - if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) { - LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager; - return false; - } - tmp_config_obj.set_vm_manager(FLAGS_vm_manager); - tmp_config_obj.set_gpu_mode(FLAGS_gpu_mode); - if (vm_manager::VmManager::ConfigureGpuMode(tmp_config_obj.vm_manager(), - tmp_config_obj.gpu_mode()).empty()) { - LOG(ERROR) << "Invalid gpu_mode=" << FLAGS_gpu_mode << - " does not work with vm_manager=" << FLAGS_vm_manager; - return false; - } - tmp_config_obj.set_wayland_socket(FLAGS_wayland_socket); - tmp_config_obj.set_x_display(FLAGS_x_display); - - tmp_config_obj.set_serial_number(FLAGS_serial_number); - - tmp_config_obj.set_cpus(FLAGS_cpus); - tmp_config_obj.set_memory_mb(FLAGS_memory_mb); - - tmp_config_obj.set_dpi(FLAGS_dpi); - tmp_config_obj.set_setupwizard_mode(FLAGS_setupwizard_mode); - tmp_config_obj.set_x_res(FLAGS_x_res); - tmp_config_obj.set_y_res(FLAGS_y_res); - tmp_config_obj.set_num_screen_buffers(FLAGS_num_screen_buffers); - tmp_config_obj.set_refresh_rate_hz(FLAGS_refresh_rate_hz); - tmp_config_obj.set_gdb_flag(FLAGS_qemu_gdb); - std::vector<std::string> adb = android::base::Split(FLAGS_adb_mode, ","); - tmp_config_obj.set_adb_mode(std::set<std::string>(adb.begin(), adb.end())); - tmp_config_obj.set_host_port(GetHostPort()); - tmp_config_obj.set_adb_ip_and_port("127.0.0.1:" + std::to_string(GetHostPort())); - - tmp_config_obj.set_device_title(FLAGS_device_title); - std::string discovered_kernel = fetcher_config.FindCvdFileWithSuffix(kKernelDefaultPath); - std::string foreign_kernel = FLAGS_kernel_path.size() ? FLAGS_kernel_path : discovered_kernel; - if (foreign_kernel.size()) { - tmp_config_obj.set_kernel_image_path(foreign_kernel); - tmp_config_obj.set_use_unpacked_kernel(false); - } else { - tmp_config_obj.set_kernel_image_path( - tmp_config_obj.PerInstancePath(kKernelDefaultPath.c_str())); - tmp_config_obj.set_use_unpacked_kernel(true); - } - tmp_config_obj.set_decompress_kernel(FLAGS_decompress_kernel); - if (FLAGS_decompress_kernel) { - tmp_config_obj.set_decompressed_kernel_image_path( - tmp_config_obj.PerInstancePath("vmlinux")); - } - - auto ramdisk_path = tmp_config_obj.PerInstancePath("ramdisk.img"); - auto vendor_ramdisk_path = tmp_config_obj.PerInstancePath("vendor_ramdisk.img"); - if (!boot_image_unpacker.HasRamdiskImage()) { - LOG(INFO) << "A ramdisk is required, but the boot image did not have one."; - return false; - } - - tmp_config_obj.set_boot_image_kernel_cmdline(boot_image_unpacker.kernel_cmdline()); - tmp_config_obj.set_loop_max_part(FLAGS_loop_max_part); - tmp_config_obj.set_guest_enforce_security(FLAGS_guest_enforce_security); - tmp_config_obj.set_guest_audit_security(FLAGS_guest_audit_security); - tmp_config_obj.set_extra_kernel_cmdline(FLAGS_extra_kernel_cmdline); - - tmp_config_obj.set_virtual_disk_paths({FLAGS_composite_disk}); - - tmp_config_obj.set_ramdisk_image_path(ramdisk_path); - tmp_config_obj.set_vendor_ramdisk_image_path(vendor_ramdisk_path); - - std::string discovered_ramdisk = fetcher_config.FindCvdFileWithSuffix(kInitramfsImg); - std::string foreign_ramdisk = FLAGS_initramfs_path.size () ? FLAGS_initramfs_path : discovered_ramdisk; - if (foreign_kernel.size() && !foreign_ramdisk.size()) { - // If there's a kernel that's passed in without an initramfs, that implies - // user error or a kernel built with no modules. In either case, let's - // choose to avoid loading the modules from the vendor ramdisk which are - // built for the default cf kernel. Once boot occurs, user error will - // become obvious. - tmp_config_obj.set_final_ramdisk_path(ramdisk_path); - } else { - tmp_config_obj.set_final_ramdisk_path(ramdisk_path + kRamdiskConcatExt); - if(foreign_ramdisk.size()) { - tmp_config_obj.set_initramfs_path(foreign_ramdisk); - } - } - - if (tmp_config_obj.adb_mode().count(vsoc::AdbMode::Usb) > 0) { - tmp_config_obj.set_usb_v1_socket_name( - tmp_config_obj.PerInstanceInternalPath("usb-v1")); - tmp_config_obj.set_vhci_port(FLAGS_vhci_port); - tmp_config_obj.set_usb_ip_socket_name( - tmp_config_obj.PerInstanceInternalPath("usb-ip")); - } - - tmp_config_obj.set_kernel_log_pipe_name( - tmp_config_obj.PerInstanceInternalPath("kernel-log-pipe")); - tmp_config_obj.set_console_pipe_name( - tmp_config_obj.PerInstanceInternalPath("console-pipe")); - tmp_config_obj.set_deprecated_boot_completed(FLAGS_deprecated_boot_completed); - tmp_config_obj.set_console_path(tmp_config_obj.PerInstancePath("console")); - tmp_config_obj.set_logcat_path(tmp_config_obj.PerInstancePath("logcat")); - tmp_config_obj.set_logcat_receiver_binary(FLAGS_logcat_receiver_binary); - tmp_config_obj.set_config_server_binary(FLAGS_config_server_binary); - tmp_config_obj.set_launcher_log_path( - tmp_config_obj.PerInstancePath("launcher.log")); - tmp_config_obj.set_launcher_monitor_socket_path( - tmp_config_obj.PerInstancePath("launcher_monitor.sock")); - - tmp_config_obj.set_mobile_bridge_name(FLAGS_mobile_interface); - tmp_config_obj.set_mobile_tap_name(FLAGS_mobile_tap_name); - - tmp_config_obj.set_wifi_tap_name(FLAGS_wifi_tap_name); - - tmp_config_obj.set_vsock_guest_cid(FLAGS_vsock_guest_cid); - - tmp_config_obj.set_uuid(FLAGS_uuid); - - tmp_config_obj.set_qemu_binary(FLAGS_qemu_binary); - tmp_config_obj.set_crosvm_binary(FLAGS_crosvm_binary); - tmp_config_obj.set_console_forwarder_binary(FLAGS_console_forwarder_binary); - tmp_config_obj.set_kernel_log_monitor_binary(FLAGS_kernel_log_monitor_binary); - - tmp_config_obj.set_enable_vnc_server(FLAGS_start_vnc_server); - tmp_config_obj.set_vnc_server_binary(FLAGS_vnc_server_binary); - tmp_config_obj.set_vnc_server_port(FLAGS_vnc_server_port); - - tmp_config_obj.set_restart_subprocesses(FLAGS_restart_subprocesses); - tmp_config_obj.set_run_adb_connector(FLAGS_run_adb_connector); - tmp_config_obj.set_adb_connector_binary(FLAGS_adb_connector_binary); - tmp_config_obj.set_virtual_usb_manager_binary( - FLAGS_virtual_usb_manager_binary); - tmp_config_obj.set_socket_forward_proxy_binary( - FLAGS_socket_forward_proxy_binary); - tmp_config_obj.set_socket_vsock_proxy_binary(FLAGS_socket_vsock_proxy_binary); - tmp_config_obj.set_run_as_daemon(FLAGS_daemon); - - tmp_config_obj.set_data_policy(FLAGS_data_policy); - tmp_config_obj.set_blank_data_image_mb(FLAGS_blank_data_image_mb); - tmp_config_obj.set_blank_data_image_fmt(FLAGS_blank_data_image_fmt); - - if(tmp_config_obj.adb_mode().count(vsoc::AdbMode::Usb) == 0) { - tmp_config_obj.disable_usb_adb(); - } - - tmp_config_obj.set_logcat_mode(FLAGS_logcat_mode); - tmp_config_obj.set_logcat_vsock_port(FLAGS_logcat_vsock_port); - tmp_config_obj.set_config_server_port(FLAGS_config_server_port); - tmp_config_obj.set_frames_vsock_port(FLAGS_frames_vsock_port); - - tmp_config_obj.set_enable_tombstone_receiver(FLAGS_enable_tombstone_receiver); - tmp_config_obj.set_tombstone_receiver_port(FLAGS_tombstone_receiver_port); - tmp_config_obj.set_tombstone_receiver_binary(FLAGS_tombstone_receiver_binary); - - tmp_config_obj.set_touch_socket_port(FLAGS_touch_server_port); - tmp_config_obj.set_keyboard_socket_port(FLAGS_keyboard_server_port); - - tmp_config_obj.set_use_bootloader(FLAGS_use_bootloader); - tmp_config_obj.set_bootloader(FLAGS_bootloader); - - if (!FLAGS_boot_slot.empty()) { - tmp_config_obj.set_boot_slot(FLAGS_boot_slot); - } - - tmp_config_obj.set_cuttlefish_env_path(GetCuttlefishEnvPath()); - - auto config_file = GetConfigFilePath(tmp_config_obj); - auto config_link = vsoc::GetGlobalConfigFileLink(); - // Save the config object before starting any host process - if (!tmp_config_obj.SaveToFile(config_file)) { - LOG(ERROR) << "Unable to save config object"; - return false; - } - setenv(vsoc::kCuttlefishConfigEnvVarName, config_file.c_str(), true); - if (symlink(config_file.c_str(), config_link.c_str()) != 0) { - LOG(ERROR) << "Failed to create symlink to config file at " << config_link - << ": " << strerror(errno); - return false; - } - - return true; -} - -void SetDefaultFlagsForQemu() { - auto default_instance_dir = - cvd::StringFromEnv("HOME", ".") + "/cuttlefish_runtime"; - SetCommandLineOptionWithMode("instance_dir", - default_instance_dir.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - // TODO(b/144119457) Use the serial port. - SetCommandLineOptionWithMode("logcat_mode", cvd::kLogcatVsockMode, - google::FlagSettingMode::SET_FLAGS_DEFAULT); -} - -void SetDefaultFlagsForCrosvm() { - auto default_instance_dir = - cvd::StringFromEnv("HOME", ".") + "/cuttlefish_runtime"; - SetCommandLineOptionWithMode("instance_dir", - default_instance_dir.c_str(), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - SetCommandLineOptionWithMode("wayland_socket", - "", - google::FlagSettingMode::SET_FLAGS_DEFAULT); - SetCommandLineOptionWithMode("x_display", - getenv("DISPLAY"), - google::FlagSettingMode::SET_FLAGS_DEFAULT); - SetCommandLineOptionWithMode("logcat_mode", cvd::kLogcatVsockMode, - google::FlagSettingMode::SET_FLAGS_DEFAULT); -} - -bool ParseCommandLineFlags(int* argc, char*** argv) { - google::ParseCommandLineNonHelpFlags(argc, argv, true); - bool invalid_manager = false; - if (FLAGS_vm_manager == vm_manager::QemuManager::name()) { - SetDefaultFlagsForQemu(); - } else if (FLAGS_vm_manager == vm_manager::CrosvmManager::name()) { - SetDefaultFlagsForCrosvm(); - } else { - std::cerr << "Unknown Virtual Machine Manager: " << FLAGS_vm_manager - << std::endl; - invalid_manager = true; - } - google::HandleCommandLineHelpFlags(); - if (invalid_manager) { - return false; - } - // Set the env variable to empty (in case the caller passed a value for it). - unsetenv(vsoc::kCuttlefishConfigEnvVarName); - - return ResolveInstanceFiles(); -} - -bool CleanPriorFiles() { - // Everything on the instance directory - std::string prior_files = FLAGS_instance_dir + "/*"; - // The environment file - prior_files += " " + GetCuttlefishEnvPath(); - // The global link to the config file - prior_files += " " + vsoc::GetGlobalConfigFileLink(); - LOG(INFO) << "Assuming prior files of " << prior_files; - std::string fuser_cmd = "fuser " + prior_files + " 2> /dev/null"; - int rval = std::system(fuser_cmd.c_str()); - // fuser returns 0 if any of the files are open - if (WEXITSTATUS(rval) == 0) { - LOG(ERROR) << "Clean aborted: files are in use"; - return false; - } - std::string clean_command = "rm -rf " + prior_files; - rval = std::system(clean_command.c_str()); - if (WEXITSTATUS(rval) != 0) { - LOG(ERROR) << "Remove of files failed"; - return false; - } - return true; -} - -bool DecompressKernel(const std::string& src, const std::string& dst) { - cvd::Command decomp_cmd(FLAGS_kernel_decompresser_executable); - decomp_cmd.AddParameter(src); - auto output_file = cvd::SharedFD::Creat(dst.c_str(), 0666); - if (!output_file->IsOpen()) { - LOG(ERROR) << "Unable to create decompressed image file: " - << output_file->StrError(); - return false; - } - decomp_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, output_file); - auto decomp_proc = decomp_cmd.Start(false); - return decomp_proc.Started() && decomp_proc.Wait() == 0; -} - -void ValidateAdbModeFlag(const vsoc::CuttlefishConfig& config) { - auto adb_modes = config.adb_mode(); - adb_modes.erase(vsoc::AdbMode::Unknown); - if (adb_modes.size() < 1) { - LOG(INFO) << "ADB not enabled"; - } -} - -} // namespace - -namespace { - -std::vector<ImagePartition> disk_config() { - std::vector<ImagePartition> partitions; - partitions.push_back(ImagePartition { - .label = "super", - .image_file_path = FLAGS_super_image, - }); - partitions.push_back(ImagePartition { - .label = "userdata", - .image_file_path = FLAGS_data_image, - }); - partitions.push_back(ImagePartition { - .label = "cache", - .image_file_path = FLAGS_cache_image, - }); - partitions.push_back(ImagePartition { - .label = "metadata", - .image_file_path = FLAGS_metadata_image, - }); - partitions.push_back(ImagePartition { - .label = "boot", - .image_file_path = FLAGS_boot_image, - }); - partitions.push_back(ImagePartition { - .label = "misc", - .image_file_path = FLAGS_misc_image - }); - return partitions; -} - -bool ShouldCreateCompositeDisk() { - if (FLAGS_vm_manager == vm_manager::CrosvmManager::name()) { - // The crosvm implementation is very fast to rebuild but also more brittle due to being split - // into multiple files. The QEMU implementation is slow to build, but completely self-contained - // at that point. Therefore, always rebuild on crosvm but check if it is necessary for QEMU. - return true; - } - auto composite_age = cvd::FileModificationTime(FLAGS_composite_disk); - for (auto& partition : disk_config()) { - auto partition_age = cvd::FileModificationTime(partition.image_file_path); - if (partition_age >= composite_age) { - LOG(INFO) << "composite disk age was \"" << std::chrono::system_clock::to_time_t(composite_age) << "\", " - << "partition age was \"" << std::chrono::system_clock::to_time_t(partition_age) << "\""; - return true; - } - } - return false; -} - -bool ConcatRamdisks(const std::string& new_ramdisk_path, const std::string& ramdisk_a_path, - const std::string& ramdisk_b_path) { - // clear out file of any pre-existing content - std::ofstream new_ramdisk(new_ramdisk_path, std::ios_base::binary | std::ios_base::trunc); - std::ifstream ramdisk_a(ramdisk_a_path, std::ios_base::binary); - std::ifstream ramdisk_b(ramdisk_b_path, std::ios_base::binary); - - if(!new_ramdisk.is_open() || !ramdisk_a.is_open() || !ramdisk_b.is_open()) { - return false; - } - - new_ramdisk << ramdisk_a.rdbuf() << ramdisk_b.rdbuf(); - return true; -} - -void CreateCompositeDisk(const vsoc::CuttlefishConfig& config) { - if (FLAGS_composite_disk.empty()) { - LOG(FATAL) << "asked to create composite disk, but path was empty"; - } - if (FLAGS_vm_manager == vm_manager::CrosvmManager::name()) { - std::string header_path = config.PerInstancePath("gpt_header.img"); - std::string footer_path = config.PerInstancePath("gpt_footer.img"); - create_composite_disk(disk_config(), header_path, footer_path, FLAGS_composite_disk); - } else { - aggregate_image(disk_config(), FLAGS_composite_disk); - } -} - -} // namespace - -const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig( - int* argc, char*** argv, cvd::FetcherConfig fetcher_config) { - if (!ParseCommandLineFlags(argc, argv)) { - LOG(ERROR) << "Failed to parse command arguments"; - exit(AssemblerExitCodes::kArgumentParsingError); - } - - // Clean up prior files before saving the config file (doing it after would - // delete it) - if (!CleanPriorFiles()) { - LOG(ERROR) << "Failed to clean prior files"; - exit(AssemblerExitCodes::kPrioFilesCleanupError); - } - // Create instance directory if it doesn't exist. - if (!cvd::DirectoryExists(FLAGS_instance_dir.c_str())) { - LOG(INFO) << "Setting up " << FLAGS_instance_dir; - if (mkdir(FLAGS_instance_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) { - LOG(ERROR) << "Failed to create instance directory: " - << FLAGS_instance_dir << ". Error: " << errno; - exit(AssemblerExitCodes::kInstanceDirCreationError); - } - } - - auto internal_dir = FLAGS_instance_dir + "/" + vsoc::kInternalDirName; - if (!cvd::DirectoryExists(internal_dir)) { - if (mkdir(internal_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < - 0) { - LOG(ERROR) << "Failed to create internal instance directory: " - << internal_dir << ". Error: " << errno; - exit(AssemblerExitCodes::kInstanceDirCreationError); - } - } - - if (!cvd::FileHasContent(FLAGS_boot_image)) { - LOG(ERROR) << "File not found: " << FLAGS_boot_image; - exit(cvd::kCuttlefishConfigurationInitError); - } - - if (!cvd::FileHasContent(FLAGS_vendor_boot_image)) { - LOG(ERROR) << "File not found: " << FLAGS_vendor_boot_image; - exit(cvd::kCuttlefishConfigurationInitError); - } - - auto boot_img_unpacker = - cvd::BootImageUnpacker::FromImages(FLAGS_boot_image, - FLAGS_vendor_boot_image); - - if (!InitializeCuttlefishConfiguration(*boot_img_unpacker, fetcher_config)) { - LOG(ERROR) << "Failed to initialize configuration"; - exit(AssemblerExitCodes::kCuttlefishConfigurationInitError); - } - // Do this early so that the config object is ready for anything that needs it - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Failed to obtain config singleton"; - exit(AssemblerExitCodes::kCuttlefishConfigurationInitError); - } - - if (!boot_img_unpacker->Unpack(config->ramdisk_image_path(), - config->vendor_ramdisk_image_path(), - config->use_unpacked_kernel() - ? config->kernel_image_path() - : "")) { - LOG(ERROR) << "Failed to unpack boot image"; - exit(AssemblerExitCodes::kBootImageUnpackError); - } - - // TODO(134522463) as part of the bootloader refactor, repack the vendor boot - // image and use the bootloader to load both the boot and vendor ramdisk. - // Until then, this hack to get gki modules into cuttlefish will suffice. - - // If a vendor ramdisk comes in via this mechanism, let it supercede the one - // in the vendor boot image. This flag is what kernel presubmit testing uses - // to pass in the kernel ramdisk. - - // If no kernel is passed in or an initramfs is made available, the default - // vendor boot ramdisk or the initramfs provided should be appended to the - // boot ramdisk. If a kernel IS provided with no initramfs, it is safe to - // safe to assume that the kernel was built with no modules and expects no - // modules for cf to run properly. - std::string discovered_kernel = fetcher_config.FindCvdFileWithSuffix(kKernelDefaultPath); - std::string foreign_kernel = FLAGS_kernel_path.size() ? FLAGS_kernel_path : discovered_kernel; - std::string discovered_ramdisk = fetcher_config.FindCvdFileWithSuffix(kInitramfsImg); - std::string foreign_ramdisk = FLAGS_initramfs_path.size () ? FLAGS_initramfs_path : discovered_ramdisk; - if(!foreign_kernel.size() || foreign_ramdisk.size()) { - const std::string& vendor_ramdisk_path = - config->initramfs_path().size() ? config->initramfs_path() - : config->vendor_ramdisk_image_path(); - if(!ConcatRamdisks(config->final_ramdisk_path(), - config->ramdisk_image_path(), vendor_ramdisk_path)) { - LOG(ERROR) << "Failed to concatenate ramdisk and vendor ramdisk"; - exit(AssemblerExitCodes::kInitRamFsConcatError); - } - } - - if (config->decompress_kernel()) { - if (!DecompressKernel(config->kernel_image_path(), - config->decompressed_kernel_image_path())) { - LOG(ERROR) << "Failed to decompress kernel"; - exit(AssemblerExitCodes::kKernelDecompressError); - } - } - - ValidateAdbModeFlag(*config); - - // Create misc if necessary - if (!InitializeMiscImage(FLAGS_misc_image)) { - exit(cvd::kCuttlefishConfigurationInitError); - } - - // Create data if necessary - if (!ApplyDataImagePolicy(*config, FLAGS_data_image)) { - exit(cvd::kCuttlefishConfigurationInitError); - } - - if (!cvd::FileExists(FLAGS_metadata_image)) { - CreateBlankImage(FLAGS_metadata_image, FLAGS_blank_metadata_image_mb, "none"); - } - - if (SuperImageNeedsRebuilding(fetcher_config, *config)) { - if (!RebuildSuperImage(fetcher_config, *config, FLAGS_super_image)) { - LOG(ERROR) << "Super image rebuilding requested but could not be completed."; - exit(cvd::kCuttlefishConfigurationInitError); - } - } - - if (ShouldCreateCompositeDisk()) { - CreateCompositeDisk(*config); - } - - // Check that the files exist - for (const auto& file : config->virtual_disk_paths()) { - if (!file.empty() && !cvd::FileHasContent(file.c_str())) { - LOG(ERROR) << "File not found: " << file; - exit(cvd::kCuttlefishConfigurationInitError); - } - } - - return config; -} - -std::string GetConfigFilePath(const vsoc::CuttlefishConfig& config) { - return config.PerInstancePath("cuttlefish_config.json"); -} diff --git a/host/commands/assemble_cvd/flags.h b/host/commands/assemble_cvd/flags.h deleted file mode 100644 index 03733881..00000000 --- a/host/commands/assemble_cvd/flags.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/config/fetcher_config.h" - -const vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig( - int* argc, char*** argv, cvd::FetcherConfig config); -std::string GetConfigFilePath(const vsoc::CuttlefishConfig& config); diff --git a/host/commands/assemble_cvd/image_aggregator.cc b/host/commands/assemble_cvd/image_aggregator.cc deleted file mode 100644 index ed537d1d..00000000 --- a/host/commands/assemble_cvd/image_aggregator.cc +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/assemble_cvd/image_aggregator.h" - -#include <fstream> -#include <string> -#include <vector> - -#include <glog/logging.h> -#include <json/json.h> -#include <google/protobuf/text_format.h> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" -#include "host/libs/config/cuttlefish_config.h" -#include "device/google/cuttlefish_common/host/commands/assemble_cvd/cdisk_spec.pb.h" - -namespace { - -const int GPT_HEADER_SIZE = 512 * 34; -const int GPT_FOOTER_SIZE = 512 * 33; - -const std::string BPTTOOL_FILE_PATH = "bin/cf_bpttool"; - -Json::Value bpttool_input(const std::vector<ImagePartition>& partitions) { - std::vector<off_t> file_sizes; - off_t total_size = 20 << 20; // 20 MB for padding - for (auto& partition : partitions) { - off_t partition_file_size = cvd::FileSize(partition.image_file_path); - if (partition_file_size == 0) { - LOG(FATAL) << "Expected partition file \"" << partition.image_file_path - << "\" but it was missing"; - } - total_size += partition_file_size; - file_sizes.push_back(partition_file_size); - } - Json::Value bpttool_input_json; - bpttool_input_json["settings"] = Json::Value(); - bpttool_input_json["settings"]["disk_size"] = (Json::Int64) total_size; - bpttool_input_json["partitions"] = Json::Value(Json::arrayValue); - for (size_t i = 0; i < partitions.size(); i++) { - Json::Value partition_json; - partition_json["label"] = partitions[i].label; - partition_json["size"] = (Json::Int64) file_sizes[i]; - partition_json["guid"] = "auto"; - partition_json["type_guid"] = "linux_fs"; - bpttool_input_json["partitions"].append(partition_json); - } - return bpttool_input_json; -} - -std::string create_file(size_t len) { - char file_template[] = "/tmp/diskXXXXXX"; - int fd = mkstemp(file_template); - if (fd < 0) { - LOG(FATAL) << "not able to create disk hole temp file"; - } - char data[4096]; - for (size_t i = 0; i < sizeof(data); i++) { - data[i] = '\0'; - } - for (size_t i = 0; i < len + 2 * sizeof(data); i+= sizeof(data)) { - if (write(fd, data, sizeof(data)) < (ssize_t) sizeof(data)) { - LOG(FATAL) << "not able to write to disk hole temp file"; - } - } - close(fd); - return std::string(file_template); -} - -CompositeDisk MakeCompositeDiskSpec(const Json::Value& bpt_file, - const std::vector<ImagePartition>& partitions, - const std::string& header_file, - const std::string& footer_file) { - CompositeDisk disk; - disk.set_version(1); - ComponentDisk* header = disk.add_component_disks(); - header->set_file_path(header_file); - header->set_offset(0); - size_t previous_end = GPT_HEADER_SIZE; - for (auto& bpt_partition: bpt_file["partitions"]) { - if (bpt_partition["offset"].asUInt64() != previous_end) { - ComponentDisk* component = disk.add_component_disks(); - component->set_file_path(create_file(bpt_partition["offset"].asUInt64() - previous_end)); - component->set_offset(previous_end); - } - ComponentDisk* component = disk.add_component_disks(); - for (auto& partition : partitions) { - if (bpt_partition["label"] == partition.label) { - component->set_file_path(partition.image_file_path); - } - } - component->set_offset(bpt_partition["offset"].asUInt64()); - component->set_read_write_capability(ReadWriteCapability::READ_WRITE); - previous_end = bpt_partition["offset"].asUInt64() + bpt_partition["size"].asUInt64(); - } - size_t footer_start = bpt_file["settings"]["disk_size"].asUInt64() - GPT_FOOTER_SIZE; - if (footer_start != previous_end) { - ComponentDisk* component = disk.add_component_disks(); - component->set_file_path(create_file(footer_start - previous_end)); - component->set_offset(previous_end); - } - ComponentDisk* footer = disk.add_component_disks(); - footer->set_file_path(footer_file); - footer->set_offset(bpt_file["settings"]["disk_size"].asUInt64() - GPT_FOOTER_SIZE); - disk.set_length(bpt_file["settings"]["disk_size"].asUInt64()); - return disk; -} - -cvd::SharedFD json_to_fd(const Json::Value& json) { - Json::FastWriter json_writer; - std::string json_string = json_writer.write(json); - cvd::SharedFD pipe[2]; - cvd::SharedFD::Pipe(&pipe[0], &pipe[1]); - int written = pipe[1]->Write(json_string.c_str(), json_string.size()); - if (written < 0) { - LOG(FATAL) << "Failed to write to pipe, errno is " << pipe[0]->GetErrno(); - } else if (written < (int) json_string.size()) { - LOG(FATAL) << "Failed to write full json to pipe, only did " << written; - } - return pipe[0]; -} - -Json::Value fd_to_json(cvd::SharedFD fd) { - std::string contents; - cvd::ReadAll(fd, &contents); - Json::Reader reader; - Json::Value json; - if (!reader.parse(contents, json)) { - LOG(FATAL) << "Could not parse json: " << reader.getFormattedErrorMessages(); - } - return json; -} - -cvd::SharedFD bpttool_make_table(const cvd::SharedFD& input) { - auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH); - cvd::Command bpttool_cmd(bpttool_path); - bpttool_cmd.AddParameter("make_table"); - bpttool_cmd.AddParameter("--input=/dev/stdin"); - bpttool_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, input); - bpttool_cmd.AddParameter("--output_json=/dev/stdout"); - cvd::SharedFD output_pipe[2]; - cvd::SharedFD::Pipe(&output_pipe[0], &output_pipe[1]); - bpttool_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, output_pipe[1]); - int success = bpttool_cmd.Start().Wait(); - if (success != 0) { - LOG(FATAL) << "Unable to run bpttool. Exited with status " << success; - } - return output_pipe[0]; -} - -cvd::SharedFD bpttool_make_partition_table(cvd::SharedFD input) { - auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH); - cvd::Command bpttool_cmd(bpttool_path); - bpttool_cmd.AddParameter("make_table"); - bpttool_cmd.AddParameter("--input=/dev/stdin"); - bpttool_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, input); - bpttool_cmd.AddParameter("--output_gpt=/dev/stdout"); - cvd::SharedFD output_pipe[2]; - cvd::SharedFD::Pipe(&output_pipe[0], &output_pipe[1]); - bpttool_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, output_pipe[1]); - int success = bpttool_cmd.Start().Wait(); - if (success != 0) { - LOG(FATAL) << "Unable to run bpttool. Exited with status " << success; - } - return output_pipe[0]; -} - -void CreateGptFiles(cvd::SharedFD gpt, const std::string& header_file, - const std::string& footer_file) { - std::string content; - content.resize(GPT_HEADER_SIZE); - if (cvd::ReadExact(gpt, &content) < GPT_HEADER_SIZE) { - LOG(FATAL) << "Unable to run read full gpt. Errno is " << gpt->GetErrno(); - } - auto header_fd = cvd::SharedFD::Open(header_file.c_str(), O_CREAT | O_RDWR, 0755); - if (cvd::WriteAll(header_fd, content) < GPT_HEADER_SIZE) { - LOG(FATAL) << "Unable to run write full gpt. Errno is " << gpt->GetErrno(); - } - content.resize(GPT_FOOTER_SIZE); - if (cvd::ReadExact(gpt, &content) < GPT_FOOTER_SIZE) { - LOG(FATAL) << "Unable to run read full gpt. Errno is " << gpt->GetErrno(); - } - auto footer_fd = cvd::SharedFD::Open(footer_file.c_str(), O_CREAT | O_RDWR, 0755); - if (cvd::WriteAll(footer_fd, content) < GPT_FOOTER_SIZE) { - LOG(FATAL) << "Unable to run write full gpt. Errno is " << gpt->GetErrno(); - } -} - -void bpttool_make_disk_image(const std::vector<ImagePartition>& partitions, - cvd::SharedFD table, const std::string& output) { - auto bpttool_path = vsoc::DefaultHostArtifactsPath(BPTTOOL_FILE_PATH); - cvd::Command bpttool_cmd(bpttool_path); - bpttool_cmd.AddParameter("make_disk_image"); - bpttool_cmd.AddParameter("--input=/dev/stdin"); - bpttool_cmd.AddParameter("--output=", cvd::AbsolutePath(output)); - bpttool_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, table); - for (auto& partition : partitions) { - auto abs_path = cvd::AbsolutePath(partition.image_file_path); - bpttool_cmd.AddParameter("--image=" + partition.label + ":" + abs_path); - } - int success = bpttool_cmd.Start().Wait(); - if (success != 0) { - LOG(FATAL) << "Unable to run bpttool. Exited with status " << success; - } -} - -} // namespace - -void aggregate_image(const std::vector<ImagePartition>& partitions, - const std::string& output_path) { - auto bpttool_input_json = bpttool_input(partitions); - auto input_json_fd = json_to_fd(bpttool_input_json); - auto table_fd = bpttool_make_table(input_json_fd); - bpttool_make_disk_image(partitions, table_fd, output_path); -}; - -void create_composite_disk(std::vector<ImagePartition> partitions, - const std::string& header_file, - const std::string& footer_file, - const std::string& output_path) { - auto bpttool_input_json = bpttool_input(partitions); - auto table_fd = bpttool_make_table(json_to_fd(bpttool_input_json)); - auto table = fd_to_json(table_fd); - auto partition_table_fd = bpttool_make_partition_table(json_to_fd(bpttool_input_json)); - CreateGptFiles(partition_table_fd, header_file, footer_file); - auto composite_proto = MakeCompositeDiskSpec(table, partitions, header_file, footer_file); - std::ofstream output(output_path.c_str(), std::ios::binary | std::ios::trunc); - output << "composite_disk\x1d"; - composite_proto.SerializeToOstream(&output); - output.flush(); -} diff --git a/host/commands/assemble_cvd/image_aggregator.h b/host/commands/assemble_cvd/image_aggregator.h deleted file mode 100644 index a4394e8f..00000000 --- a/host/commands/assemble_cvd/image_aggregator.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <string> -#include <vector> - -struct ImagePartition { - std::string label; - std::string image_file_path; -}; - -void aggregate_image(const std::vector<ImagePartition>& partitions, - const std::string& output_path); -void create_composite_disk(std::vector<ImagePartition> partitions, - const std::string& header_file, - const std::string& footer_file, - const std::string& output_path); diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc deleted file mode 100644 index 1960d418..00000000 --- a/host/commands/assemble_cvd/super_image_mixer.cc +++ /dev/null @@ -1,196 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "super_image_mixer.h" - -#include <sys/stat.h> - -#include <algorithm> -#include <cstdio> -#include <functional> -#include <memory> - -#include <android-base/strings.h> -#include <glog/logging.h> - -#include "common/libs/utils/archive.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/config/fetcher_config.h" - -namespace { - -using cvd::FileExists; -using vsoc::DefaultHostArtifactsPath; - -std::string TargetFilesZip(const cvd::FetcherConfig& fetcher_config, - cvd::FileSource source) { - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - const auto& file_path = file_iter.first; - const auto& file_info = file_iter.second; - if (file_info.source != source) { - continue; - } - std::string expected_filename = "target_files-" + file_iter.second.build_id + ".zip"; - if (!android::base::EndsWith(file_path, expected_filename)) { - continue; - } - return file_path;; - } - return ""; -} - -const std::string kMiscInfoPath = "META/misc_info.txt"; -const std::set<std::string> kDefaultTargetImages = { - "IMAGES/boot.img", - "IMAGES/cache.img", - "IMAGES/recovery.img", - "IMAGES/userdata.img", - "IMAGES/vendor.img", -}; - -bool CombineTargetZipFiles(const std::string& default_target_zip, - const std::string& system_target_zip, - const std::string& output_path) { - cvd::Archive default_target_archive(default_target_zip); - cvd::Archive system_target_archive(system_target_zip); - - auto default_target_contents = default_target_archive.Contents(); - if (default_target_contents.size() == 0) { - LOG(ERROR) << "Could not open " << default_target_zip; - return false; - } - auto system_target_contents = system_target_archive.Contents(); - if (system_target_contents.size() == 0) { - LOG(ERROR) << "Could not open " << system_target_zip; - return false; - } - if (mkdir(output_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) { - LOG(ERROR) << "Could not create directory " << output_path; - return false; - } - - if (std::find(default_target_contents.begin(), default_target_contents.end(), kMiscInfoPath) - == default_target_contents.end()) { - LOG(ERROR) << "Default target files zip does not have " << kMiscInfoPath; - return false; - } - if (!default_target_archive.ExtractFiles({kMiscInfoPath}, output_path)) { - LOG(ERROR) << "Failed to write misc info to output directory"; - return false; - } - - for (const auto& name : default_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { - continue; - } else if (kDefaultTargetImages.count(name) == 0) { - continue; - } - LOG(INFO) << "Writing " << name; - if (!default_target_archive.ExtractFiles({name}, output_path)) { - LOG(ERROR) << "Failed to extract " << name << " from the default target zip"; - return false; - } - } - - for (const auto& name : system_target_contents) { - if (!android::base::StartsWith(name, "IMAGES/")) { - continue; - } else if (!android::base::EndsWith(name, ".img")) { - continue; - } else if (kDefaultTargetImages.count(name) > 0) { - continue; - } - LOG(INFO) << "Writing " << name; - if (!system_target_archive.ExtractFiles({name}, output_path)) { - LOG(ERROR) << "Failed to extract " << name << " from the system target zip"; - return false; - } - } - - return true; -} - -bool BuildSuperImage(const std::string& combined_target_zip, - const std::string& output_path) { - std::string build_super_image_binary; - std::string otatools_path; - if (FileExists(DefaultHostArtifactsPath("otatools/bin/build_super_image"))) { - build_super_image_binary = - DefaultHostArtifactsPath("otatools/bin/build_super_image"); - otatools_path = DefaultHostArtifactsPath("otatools"); - } else if (FileExists(DefaultHostArtifactsPath("bin/build_super_image"))) { - build_super_image_binary = - DefaultHostArtifactsPath("bin/build_super_image"); - otatools_path = DefaultHostArtifactsPath(""); - } else { - LOG(ERROR) << "Could not find otatools"; - return false; - } - return cvd::execute({ - build_super_image_binary, - "--path=" + otatools_path, - combined_target_zip, - output_path, - }) == 0; -} - -} // namespace - -bool SuperImageNeedsRebuilding(const cvd::FetcherConfig& fetcher_config, - const vsoc::CuttlefishConfig&) { - bool has_default_build = false; - bool has_system_build = false; - for (const auto& file_iter : fetcher_config.get_cvd_files()) { - if (file_iter.second.source == cvd::FileSource::DEFAULT_BUILD) { - has_default_build = true; - } else if (file_iter.second.source == cvd::FileSource::SYSTEM_BUILD) { - has_system_build = true; - } - } - return has_default_build && has_system_build; -} - -bool RebuildSuperImage(const cvd::FetcherConfig& fetcher_config, - const vsoc::CuttlefishConfig& config, - const std::string& output_path) { - std::string default_target_zip = - TargetFilesZip(fetcher_config, cvd::FileSource::DEFAULT_BUILD); - if (default_target_zip == "") { - LOG(ERROR) << "Unable to find default target zip file."; - return false; - } - std::string system_target_zip = - TargetFilesZip(fetcher_config, cvd::FileSource::SYSTEM_BUILD); - if (system_target_zip == "") { - LOG(ERROR) << "Unable to find system target zip file."; - return false; - } - std::string combined_target_path = config.PerInstanceInternalPath("target_combined"); - // TODO(schuffelen): Use otatools/bin/merge_target_files - if (!CombineTargetZipFiles(default_target_zip, system_target_zip, - combined_target_path)) { - LOG(ERROR) << "Could not combine target zip files."; - return false; - } - bool success = BuildSuperImage(combined_target_path, output_path); - if (!success) { - LOG(ERROR) << "Could not write the final output super image."; - } - return success; -} diff --git a/host/commands/assemble_cvd/super_image_mixer.h b/host/commands/assemble_cvd/super_image_mixer.h deleted file mode 100644 index 1b8c4201..00000000 --- a/host/commands/assemble_cvd/super_image_mixer.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/config/fetcher_config.h" - -bool SuperImageNeedsRebuilding(const cvd::FetcherConfig& fetcher_config, - const vsoc::CuttlefishConfig& config); -bool RebuildSuperImage(const cvd::FetcherConfig& fetcher_config, - const vsoc::CuttlefishConfig& config, - const std::string& output_path); diff --git a/host/commands/config_server/Android.bp b/host/commands/config_server/Android.bp deleted file mode 100644 index fcf6d392..00000000 --- a/host/commands/config_server/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "config_server", - srcs: [ - "main.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "liblog", - "libcuttlefish_utils", - "libcuttlefish_device_config", - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/config_server/main.cpp b/host/commands/config_server/main.cpp deleted file mode 100644 index 5970edfa..00000000 --- a/host/commands/config_server/main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <common/libs/device_config/device_config.h> -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "host/libs/config/cuttlefish_config.h" - -DEFINE_int32( - server_fd, -1, - "File descriptor to an already created vsock server. If negative a new " - "server will be created at the port specified on the config file"); - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - - cvd::SharedFD server_fd; - if (FLAGS_server_fd < 0) { - unsigned int port = config->config_server_port(); - server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - } else { - server_fd = cvd::SharedFD::Dup(FLAGS_server_fd); - close(FLAGS_server_fd); - } - - CHECK(server_fd->IsOpen()) << "Error creating or inheriting logcat server: " - << server_fd->StrError(); - - auto device_config = cvd::DeviceConfig::Get(); - if (!device_config) { - LOG(ERROR) << "Failed to obtain device configuration"; - return -1; - } - - // Server loop - while (true) { - auto conn = cvd::SharedFD::Accept(*server_fd); - LOG(INFO) << "Connection received on configuration server"; - - bool succeeded = device_config->SendRawData(conn); - if (succeeded) { - LOG(INFO) << "Successfully sent device configuration"; - } else { - LOG(ERROR) << "Failed to send the device configuration: " - << conn->StrError(); - } - } -} diff --git a/host/commands/console_forwarder/Android.bp b/host/commands/console_forwarder/Android.bp deleted file mode 100644 index a090e983..00000000 --- a/host/commands/console_forwarder/Android.bp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "console_forwarder", - srcs: [ - "main.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libjsoncpp", - "libgflags", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/console_forwarder/main.cpp b/host/commands/console_forwarder/main.cpp deleted file mode 100644 index e5edff2a..00000000 --- a/host/commands/console_forwarder/main.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <signal.h> - -#include <deque> -#include <thread> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include <common/libs/fs/shared_fd.h> -#include <common/libs/fs/shared_select.h> -#include <host/libs/config/cuttlefish_config.h> - -DEFINE_int32(console_in_fd, - -1, - "File descriptor for the console's input channel"); -DEFINE_int32(console_out_fd, - -1, - "File descriptor for the console's output channel"); - -// Handles forwarding the serial console to a socket. -// It receives the socket fd along with a couple of fds for the console (could -// be the same fd twice if, for example a socket_pair were used). -// Data available in the console's output needs to be read immediately to avoid -// the having the VMM blocked on writes to the pipe. To achieve this one thread -// takes care of (and only of) all read calls (from console output and from the -// socket client), using select(2) to ensure it never blocks. Writes are handled -// in a different thread, the two threads communicate through a buffer queue -// protected by a mutex. -class ConsoleForwarder { - public: - ConsoleForwarder(cvd::SharedFD socket, - cvd::SharedFD console_in, - cvd::SharedFD console_out) : socket_(socket), - console_in_(console_in), - console_out_(console_out) {} - [[noreturn]] void StartServer() { - // Create a new thread to handle writes to the console and to the any client - // connected to the socket. - writer_thread_ = std::thread([this]() { WriteLoop(); }); - // Use the calling thread (likely the process' main thread) to handle - // reading the console's output and input from the client. - ReadLoop(); - } - private: - void EnqueueWrite(std::vector<char> buffer, cvd::SharedFD fd) { - std::lock_guard<std::mutex> lock(write_queue_mutex_); - write_queue_.emplace_back(fd, std::move(buffer)); - condvar_.notify_one(); - } - - [[noreturn]] void WriteLoop() { - while (true) { - while (!write_queue_.empty()) { - std::vector<char> buffer; - cvd::SharedFD fd; - { - std::lock_guard<std::mutex> lock(write_queue_mutex_); - auto& front = write_queue_.front(); - buffer = std::move(front.second); - fd = front.first; - write_queue_.pop_front(); - } - // Write all bytes to the file descriptor. Writes may block, so the - // mutex lock should NOT be held while writing to avoid blocking the - // other thread. - ssize_t bytes_written = 0; - ssize_t bytes_to_write = buffer.size(); - while (bytes_to_write > 0) { - bytes_written = - fd->Write(buffer.data() + bytes_written, bytes_to_write); - if (bytes_written < 0) { - LOG(ERROR) << "Error writing to fd: " << fd->StrError(); - // Don't try to write from this buffer anymore, error handling will - // be done on the reading thread (failed client will be - // disconnected, on serial console failure this process will abort). - break; - } - bytes_to_write -= bytes_written; - } - } - { - std::unique_lock<std::mutex> lock(write_queue_mutex_); - // Check again before sleeping, state may have changed - if (write_queue_.empty()) { - condvar_.wait(lock); - } - } - } - } - - [[noreturn]] void ReadLoop() { - cvd::SharedFD client_fd; - while (true) { - cvd::SharedFDSet read_set; - if (client_fd->IsOpen()) { - read_set.Set(client_fd); - } else { - read_set.Set(socket_); - } - read_set.Set(console_out_); - cvd::Select(&read_set, nullptr, nullptr, nullptr); - if (read_set.IsSet(console_out_)) { - std::vector<char> buffer(4096); - auto bytes_read = console_out_->Read(buffer.data(), buffer.size()); - if (bytes_read <= 0) { - LOG(ERROR) << "Error reading from console output: " - << console_out_->StrError(); - // This is likely unrecoverable, so exit here - std::exit(-4); - } - buffer.resize(bytes_read); - if (client_fd->IsOpen()) { - EnqueueWrite(std::move(buffer), client_fd); - } - } - if (read_set.IsSet(socket_)) { - // socket_ will only be included in the select call (and therefore only - // present in the read set) if there is no client connected, so this - // assignment is safe. - client_fd = cvd::SharedFD::Accept(*socket_); - if (!client_fd->IsOpen()) { - LOG(ERROR) << "Error accepting connection on socket: " - << client_fd->StrError(); - } - } - if (read_set.IsSet(client_fd)) { - std::vector<char> buffer(4096); - auto bytes_read = client_fd->Read(buffer.data(), buffer.size()); - if (bytes_read <= 0) { - LOG(ERROR) << "Error reading from client fd: " - << client_fd->StrError(); - client_fd->Close(); // ignore errors here - } else { - buffer.resize(bytes_read); - EnqueueWrite(std::move(buffer), console_in_); - } - } - } - } - - cvd::SharedFD socket_; - cvd::SharedFD console_in_; - cvd::SharedFD console_out_; - std::thread writer_thread_; - std::mutex write_queue_mutex_; - std::condition_variable condvar_; - std::deque<std::pair<cvd::SharedFD, std::vector<char>>> write_queue_; -}; - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - ::gflags::ParseCommandLineFlags(&argc, &argv, true); - - if (FLAGS_console_in_fd < 0 || FLAGS_console_out_fd < 0) { - LOG(ERROR) << "Invalid file descriptors: " << FLAGS_console_in_fd << ", " - << FLAGS_console_out_fd; - return -1; - } - - auto console_in = cvd::SharedFD::Dup(FLAGS_console_in_fd); - close(FLAGS_console_in_fd); - if (!console_in->IsOpen()) { - LOG(ERROR) << "Error dupping fd " << FLAGS_console_in_fd << ": " - << console_in->StrError(); - return -2; - } - close(FLAGS_console_in_fd); - - auto console_out = cvd::SharedFD::Dup(FLAGS_console_out_fd); - close(FLAGS_console_out_fd); - if (!console_out->IsOpen()) { - LOG(ERROR) << "Error dupping fd " << FLAGS_console_out_fd << ": " - << console_out->StrError(); - return -2; - } - - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Unable to get config object"; - return -3; - } - - auto console_socket_name = config->console_path(); - auto socket = cvd::SharedFD::SocketLocalServer(console_socket_name.c_str(), - false, - SOCK_STREAM, - 0600); - if (!socket->IsOpen()) { - LOG(ERROR) << "Failed to create console socket at " << console_socket_name - << ": " << socket->StrError(); - return -5; - } - - ConsoleForwarder console_forwarder(socket, console_in, console_out); - - // Don't get a SIGPIPE from the clients - if (sigaction(SIGPIPE, nullptr, nullptr) != 0) { - LOG(FATAL) << "Failed to set SIGPIPE to be ignored: " << strerror(errno); - return -6; - } - - console_forwarder.StartServer(); -} diff --git a/host/commands/cvd_status/Android.bp b/host/commands/cvd_status/Android.bp deleted file mode 100644 index 3b1cbbc2..00000000 --- a/host/commands/cvd_status/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_binary_host { - name: "cvd_status", - srcs: [ - "cvd_status.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libcuttlefish_vm_manager", - "libjsoncpp", - "libgflags", - "libxml2", - ], - defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"], -} diff --git a/host/commands/cvd_status/cvd_status.cc b/host/commands/cvd_status/cvd_status.cc deleted file mode 100644 index fb9911f1..00000000 --- a/host/commands/cvd_status/cvd_status.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <inttypes.h> -#include <limits.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> -#include <signal.h> - -#include <algorithm> -#include <cstdlib> -#include <fstream> -#include <iomanip> -#include <memory> -#include <sstream> -#include <string> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "common/libs/utils/environment.h" -#include "host/commands/run_cvd/runner_defs.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/vm_manager/vm_manager.h" - -DEFINE_int32(wait_for_launcher, 5, - "How many seconds to wait for the launcher to respond to the status " - "command. A value of zero means wait indefinetly"); - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Failed to obtain config object"; - return 1; - } - - auto monitor_path = config->launcher_monitor_socket_path(); - if (monitor_path.empty()) { - LOG(ERROR) << "No path to launcher monitor found"; - return 2; - } - auto monitor_socket = cvd::SharedFD::SocketLocalClient(monitor_path.c_str(), - false, SOCK_STREAM); - if (!monitor_socket->IsOpen()) { - LOG(ERROR) << "Unable to connect to launcher monitor at " << monitor_path - << ": " << monitor_socket->StrError(); - return 3; - } - auto request = cvd::LauncherAction::kStatus; - auto bytes_sent = monitor_socket->Send(&request, sizeof(request), 0); - if (bytes_sent < 0) { - LOG(ERROR) << "Error sending launcher monitor the status command: " - << monitor_socket->StrError(); - return 4; - } - // Perform a select with a timeout to guard against launcher hanging - cvd::SharedFDSet read_set; - read_set.Set(monitor_socket); - struct timeval timeout = {FLAGS_wait_for_launcher, 0}; - int selected = cvd::Select(&read_set, nullptr, nullptr, - FLAGS_wait_for_launcher <= 0 ? nullptr : &timeout); - if (selected < 0){ - LOG(ERROR) << "Failed communication with the launcher monitor: " - << strerror(errno); - return 5; - } - if (selected == 0) { - LOG(ERROR) << "Timeout expired waiting for launcher monitor to respond"; - return 6; - } - cvd::LauncherResponse response; - auto bytes_recv = monitor_socket->Recv(&response, sizeof(response), 0); - if (bytes_recv < 0) { - LOG(ERROR) << "Error receiving response from launcher monitor: " - << monitor_socket->StrError(); - return 7; - } - if (response != cvd::LauncherResponse::kSuccess) { - LOG(ERROR) << "Received '" << static_cast<char>(response) - << "' response from launcher monitor"; - return 8; - } - LOG(INFO) << "run_cvd is active."; - return 0; -} diff --git a/host/commands/fetcher/Android.bp b/host/commands/fetcher/Android.bp deleted file mode 100644 index 0677d761..00000000 --- a/host/commands/fetcher/Android.bp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "fetch_cvd", - srcs: [ - "build_api.cc", - "credential_source.cc", - "curl_wrapper.cc", - "fetch_cvd.cc", - "install_zip.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - stl: "libc++_static", - static_libs: [ - "libbase", - "libcuttlefish_host_config", - "libcuttlefish_fs", - "libcuttlefish_utils", - "libcurl", - "libcrypto", - "libgflags", - "libssl", - "libz", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/fetcher/build_api.cc b/host/commands/fetcher/build_api.cc deleted file mode 100644 index ff2b65e7..00000000 --- a/host/commands/fetcher/build_api.cc +++ /dev/null @@ -1,155 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "build_api.h" - -#include <chrono> -#include <set> -#include <string> -#include <thread> - -#include <glog/logging.h> - -namespace { - -const std::string BUILD_API = - "https://www.googleapis.com/android/internal/build/v3"; - -bool StatusIsTerminal(const std::string& status) { - const static std::set<std::string> terminal_statuses = { - "abandoned", - "complete", - "error", - "ABANDONED", - "COMPLETE", - "ERROR", - }; - return terminal_statuses.count(status) > 0; -} - -} // namespace - -Artifact::Artifact(const Json::Value& json_artifact) { - name = json_artifact["name"].asString(); - size = std::stol(json_artifact["size"].asString()); - last_modified_time = std::stol(json_artifact["lastModifiedTime"].asString()); - md5 = json_artifact["md5"].asString(); - content_type = json_artifact["contentType"].asString(); - revision = json_artifact["revision"].asString(); - creation_time = std::stol(json_artifact["creationTime"].asString()); - crc32 = json_artifact["crc32"].asUInt(); -} - -std::ostream& operator<<(std::ostream& out, const DeviceBuild& build) { - return out << "(id=\"" << build.id << "\", target=\"" << build.target << "\")"; -} - -BuildApi::BuildApi(std::unique_ptr<CredentialSource> credential_source) - : credential_source(std::move(credential_source)) {} - -std::vector<std::string> BuildApi::Headers() { - std::vector<std::string> headers; - if (credential_source) { - headers.push_back("Authorization:Bearer " + credential_source->Credential()); - } - return headers; -} - -std::string BuildApi::LatestBuildId(const std::string& branch, - const std::string& target) { - std::string url = BUILD_API + "/builds?branch=" + branch - + "&buildAttemptStatus=complete" - + "&buildType=submitted&maxResults=1&successful=true&target=" + target; - auto response = curl.DownloadToJson(url, Headers()); - CHECK(!response.isMember("error")) << "Error fetching the latest build of \"" - << target << "\" on \"" << branch << "\". Response was " << response; - - if (!response.isMember("builds") || response["builds"].size() != 1) { - LOG(WARNING) << "expected to receive 1 build for \"" << target << "\" on \"" - << branch << "\", but received " << response["builds"].size() - << ". Full response was " << response; - return ""; - } - return response["builds"][0]["buildId"].asString(); -} - -std::string BuildApi::BuildStatus(const DeviceBuild& build) { - std::string url = BUILD_API + "/builds/" + build.id + "/" + build.target; - auto response_json = curl.DownloadToJson(url, Headers()); - CHECK(!response_json.isMember("error")) << "Error fetching the status of " - << "build " << build << ". Response was " << response_json; - - return response_json["buildAttemptStatus"].asString(); -} - -std::vector<Artifact> BuildApi::Artifacts(const DeviceBuild& build) { - std::string url = BUILD_API + "/builds/" + build.id + "/" + build.target - + "/attempts/latest/artifacts?maxResults=1000"; - auto artifacts_json = curl.DownloadToJson(url, Headers()); - CHECK(!artifacts_json.isMember("error")) << "Error fetching the artifacts of " - << build << ". Response was " << artifacts_json; - - std::vector<Artifact> artifacts; - for (const auto& artifact_json : artifacts_json["artifacts"]) { - artifacts.emplace_back(artifact_json); - } - return artifacts; -} - -bool BuildApi::ArtifactToFile(const DeviceBuild& build, - const std::string& artifact, - const std::string& path) { - std::string url = BUILD_API + "/builds/" + build.id + "/" + build.target - + "/attempts/latest/artifacts/" + artifact + "?alt=media"; - return curl.DownloadToFile(url, path, Headers()); -} - -DeviceBuild ArgumentToBuild(BuildApi* build_api, const std::string& arg, - const std::string& default_build_target, - const std::chrono::seconds& retry_period) { - size_t slash_pos = arg.find('/'); - if (slash_pos != std::string::npos - && arg.find('/', slash_pos + 1) != std::string::npos) { - LOG(FATAL) << "Build argument cannot have more than one '/' slash. Was at " - << slash_pos << " and " << arg.find('/', slash_pos + 1); - } - std::string build_target = slash_pos == std::string::npos - ? default_build_target : arg.substr(slash_pos + 1); - std::string branch_or_id = slash_pos == std::string::npos - ? arg: arg.substr(0, slash_pos); - std::string branch_latest_build_id = - build_api->LatestBuildId(branch_or_id, build_target); - std::string build_id = branch_or_id; - if (branch_latest_build_id != "") { - LOG(INFO) << "The latest good build on branch \"" << branch_or_id - << "\"with build target \"" << build_target - << "\" is \"" << branch_latest_build_id << "\""; - build_id = branch_latest_build_id; - } - DeviceBuild proposed_build = DeviceBuild(build_id, build_target); - std::string status = build_api->BuildStatus(proposed_build); - if (status == "") { - LOG(FATAL) << proposed_build << " is not a valid branch or build id."; - } - LOG(INFO) << "Status for build " << proposed_build << " is " << status; - while (retry_period != std::chrono::seconds::zero() && !StatusIsTerminal(status)) { - LOG(INFO) << "Status is \"" << status << "\". Waiting for " << retry_period.count() - << " seconds."; - std::this_thread::sleep_for(retry_period); - status = build_api->BuildStatus(proposed_build); - } - LOG(INFO) << "Status for build " << proposed_build << " is " << status; - return proposed_build; -} diff --git a/host/commands/fetcher/build_api.h b/host/commands/fetcher/build_api.h deleted file mode 100644 index bb89e815..00000000 --- a/host/commands/fetcher/build_api.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include <chrono> -#include <functional> -#include <memory> -#include <ostream> -#include <string> - -#include "credential_source.h" -#include "curl_wrapper.h" - -class Artifact { - std::string name; - size_t size; - unsigned long last_modified_time; - std::string md5; - std::string content_type; - std::string revision; - unsigned long creation_time; - unsigned int crc32; -public: - Artifact(const Json::Value&); - - const std::string& Name() const { return name; } - size_t Size() const { return size; } - unsigned long LastModifiedTime() const { return last_modified_time; } - const std::string& Md5() const { return md5; } - const std::string& ContentType() const { return content_type; } - const std::string& Revision() const { return revision; } - unsigned long CreationTime() const { return creation_time; } - unsigned int Crc32() const { return crc32; } -}; - -struct DeviceBuild { - DeviceBuild(const std::string& id, const std::string& target) { - this->id = id; - this->target = target; - } - - std::string id; - std::string target; -}; - -std::ostream& operator<<(std::ostream&, const DeviceBuild&); - -class BuildApi { - CurlWrapper curl; - std::unique_ptr<CredentialSource> credential_source; - - std::vector<std::string> Headers(); -public: - BuildApi(std::unique_ptr<CredentialSource> credential_source); - ~BuildApi() = default; - - std::string LatestBuildId(const std::string& branch, - const std::string& target); - - std::string BuildStatus(const DeviceBuild&); - - std::vector<Artifact> Artifacts(const DeviceBuild&); - - bool ArtifactToFile(const DeviceBuild& build, const std::string& artifact, - const std::string& path); -}; - -DeviceBuild ArgumentToBuild(BuildApi* api, const std::string& arg, - const std::string& default_build_target, - const std::chrono::seconds& retry_period); diff --git a/host/commands/fetcher/credential_source.cc b/host/commands/fetcher/credential_source.cc deleted file mode 100644 index 89d6b14b..00000000 --- a/host/commands/fetcher/credential_source.cc +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "credential_source.h" - -#include <glog/logging.h> - -namespace { - -std::chrono::steady_clock::duration REFRESH_WINDOW = - std::chrono::minutes(2); -std::string REFRESH_URL = "http://metadata.google.internal/computeMetadata/" - "v1/instance/service-accounts/default/token"; - -} - -GceMetadataCredentialSource::GceMetadataCredentialSource() { - latest_credential = ""; - expiration = std::chrono::steady_clock::now(); -} - -std::string GceMetadataCredentialSource::Credential() { - if (expiration - std::chrono::steady_clock::now() < REFRESH_WINDOW) { - RefreshCredential(); - } - return latest_credential; -} - -void GceMetadataCredentialSource::RefreshCredential() { - Json::Value credential_json = - curl.DownloadToJson(REFRESH_URL, {"Metadata-Flavor: Google"}); - - CHECK(!credential_json.isMember("error")) << "Error fetching credentials. " << - "Response was " << credential_json; - bool has_access_token = credential_json.isMember("access_token"); - bool has_expires_in = credential_json.isMember("expires_in"); - if (!has_access_token || !has_expires_in) { - LOG(FATAL) << "GCE credential was missing access_token or expires_in. " - << "Full response was " << credential_json << ""; - } - - expiration = std::chrono::steady_clock::now() - + std::chrono::seconds(credential_json["expires_in"].asInt()); - latest_credential = credential_json["access_token"].asString(); -} - -std::unique_ptr<CredentialSource> GceMetadataCredentialSource::make() { - return std::unique_ptr<CredentialSource>(new GceMetadataCredentialSource()); -} - -FixedCredentialSource::FixedCredentialSource(const std::string& credential) { - this->credential = credential; -} - -std::string FixedCredentialSource::Credential() { - return credential; -} - -std::unique_ptr<CredentialSource> FixedCredentialSource::make( - const std::string& credential) { - return std::unique_ptr<CredentialSource>(new FixedCredentialSource(credential)); -} diff --git a/host/commands/fetcher/credential_source.h b/host/commands/fetcher/credential_source.h deleted file mode 100644 index fa82eab8..00000000 --- a/host/commands/fetcher/credential_source.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include <chrono> -#include <memory> - -#include "curl_wrapper.h" - -class CredentialSource { -public: - virtual ~CredentialSource() = default; - virtual std::string Credential() = 0; -}; - -class GceMetadataCredentialSource : public CredentialSource { - CurlWrapper curl; - std::string latest_credential; - std::chrono::steady_clock::time_point expiration; - - void RefreshCredential(); -public: - GceMetadataCredentialSource(); - GceMetadataCredentialSource(GceMetadataCredentialSource&&) = default; - - virtual std::string Credential(); - - static std::unique_ptr<CredentialSource> make(); -}; - -class FixedCredentialSource : public CredentialSource { - std::string credential; -public: - FixedCredentialSource(const std::string& credential); - - virtual std::string Credential(); - - static std::unique_ptr<CredentialSource> make(const std::string& credential); -}; diff --git a/host/commands/fetcher/curl_wrapper.cc b/host/commands/fetcher/curl_wrapper.cc deleted file mode 100644 index 472963a0..00000000 --- a/host/commands/fetcher/curl_wrapper.cc +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "curl_wrapper.h" - -#include <sstream> -#include <string> -#include <stdio.h> - -#include <glog/logging.h> - -#include <curl/curl.h> -#include <json/json.h> - -namespace { - -size_t file_write_callback(char *ptr, size_t, size_t nmemb, void *userdata) { - std::stringstream* stream = (std::stringstream*) userdata; - stream->write(ptr, nmemb); - return nmemb; -} - -curl_slist* build_slist(const std::vector<std::string>& strings) { - curl_slist* curl_headers = nullptr; - for (const auto& str : strings) { - curl_slist* temp = curl_slist_append(curl_headers, str.c_str()); - if (temp == nullptr) { - LOG(ERROR) << "curl_slist_append failed to add " << str; - if (curl_headers) { - curl_slist_free_all(curl_headers); - return nullptr; - } - } - curl_headers = temp; - } - return curl_headers; -} - -} // namespace - -CurlWrapper::CurlWrapper() { - curl = curl_easy_init(); - if (!curl) { - LOG(ERROR) << "failed to initialize curl"; - return; - } -} - -CurlWrapper::~CurlWrapper() { - curl_easy_cleanup(curl); -} - -bool CurlWrapper::DownloadToFile(const std::string& url, const std::string& path) { - return CurlWrapper::DownloadToFile(url, path, {}); -} - -bool CurlWrapper::DownloadToFile(const std::string& url, const std::string& path, - const std::vector<std::string>& headers) { - LOG(INFO) << "Attempting to save \"" << url << "\" to \"" << path << "\""; - if (!curl) { - LOG(ERROR) << "curl was not initialized\n"; - return false; - } - curl_slist* curl_headers = build_slist(headers); - curl_easy_reset(curl); - curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/ssl/certs/ca-certificates.crt"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - char error_buf[CURL_ERROR_SIZE]; - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buf); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - FILE* file = fopen(path.c_str(), "w"); - if (!file) { - LOG(ERROR) << "could not open file " << path; - return false; - } - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*) file); - CURLcode res = curl_easy_perform(curl); - if (curl_headers) { - curl_slist_free_all(curl_headers); - } - fclose(file); - if (res != CURLE_OK) { - LOG(ERROR) << "curl_easy_perform() failed. " - << "Code was \"" << res << "\". " - << "Strerror was \"" << curl_easy_strerror(res) << "\". " - << "Error buffer was \"" << error_buf << "\"."; - return false; - } - return true; -} - -std::string CurlWrapper::DownloadToString(const std::string& url) { - return DownloadToString(url, {}); -} - -std::string CurlWrapper::DownloadToString(const std::string& url, - const std::vector<std::string>& headers) { - LOG(INFO) << "Attempting to download \"" << url << "\""; - if (!curl) { - LOG(ERROR) << "curl was not initialized\n"; - return ""; - } - curl_slist* curl_headers = build_slist(headers); - curl_easy_reset(curl); - curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/ssl/certs/ca-certificates.crt"); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers); - curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - std::stringstream data; - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, file_write_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); - char error_buf[CURL_ERROR_SIZE]; - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buf); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - CURLcode res = curl_easy_perform(curl); - if (curl_headers) { - curl_slist_free_all(curl_headers); - } - if (res != CURLE_OK) { - LOG(ERROR) << "curl_easy_perform() failed. " - << "Code was \"" << res << "\". " - << "Strerror was \"" << curl_easy_strerror(res) << "\". " - << "Error buffer was \"" << error_buf << "\"."; - return ""; - } - return data.str(); -} - -Json::Value CurlWrapper::DownloadToJson(const std::string& url) { - return DownloadToJson(url, {}); -} - -Json::Value CurlWrapper::DownloadToJson(const std::string& url, - const std::vector<std::string>& headers) { - std::string contents = DownloadToString(url, headers); - Json::Reader reader; - Json::Value json; - if (!reader.parse(contents, json)) { - LOG(ERROR) << "Could not parse json: " << reader.getFormattedErrorMessages(); - json["error"] = "Failed to parse json."; - json["response"] = contents; - } - return json; -} diff --git a/host/commands/fetcher/curl_wrapper.h b/host/commands/fetcher/curl_wrapper.h deleted file mode 100644 index 5a5ba9c0..00000000 --- a/host/commands/fetcher/curl_wrapper.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include <string> - -#include <curl/curl.h> -#include <json/json.h> - -class CurlWrapper { - CURL* curl; -public: - CurlWrapper(); - ~CurlWrapper(); - CurlWrapper(const CurlWrapper&) = delete; - CurlWrapper& operator=(const CurlWrapper*) = delete; - CurlWrapper(CurlWrapper&&) = default; - - bool DownloadToFile(const std::string& url, const std::string& path); - bool DownloadToFile(const std::string& url, const std::string& path, - const std::vector<std::string>& headers); - std::string DownloadToString(const std::string& url); - std::string DownloadToString(const std::string& url, - const std::vector<std::string>& headers); - Json::Value DownloadToJson(const std::string& url); - Json::Value DownloadToJson(const std::string& url, - const std::vector<std::string>& headers); -}; diff --git a/host/commands/fetcher/fetch_cvd.cc b/host/commands/fetcher/fetch_cvd.cc deleted file mode 100644 index 5e314c88..00000000 --- a/host/commands/fetcher/fetch_cvd.cc +++ /dev/null @@ -1,422 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <iostream> -#include <iterator> -#include <string> - -#include <sys/stat.h> -#include <unistd.h> - -#include "gflags/gflags.h" -#include <glog/logging.h> - -#include "common/libs/utils/archive.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" - -#include "host/libs/config/fetcher_config.h" - -#include "build_api.h" -#include "credential_source.h" -#include "install_zip.h" - -namespace { - -const std::string DEFAULT_BRANCH = "aosp-master"; -const std::string DEFAULT_BUILD_TARGET = "aosp_cf_x86_phone-userdebug"; - -} - -DEFINE_string(default_build, DEFAULT_BRANCH + "/" + DEFAULT_BUILD_TARGET, - "source for the cuttlefish build to use (vendor.img + host)"); -DEFINE_string(system_build, "", "source for system.img and product.img"); -DEFINE_string(kernel_build, "", "source for the kernel or gki target"); -DEFINE_string(otatools_build, "", "source for the host ota tools"); - -DEFINE_bool(download_img_zip, true, "Whether to fetch the -img-*.zip file."); -DEFINE_bool(download_target_files_zip, false, "Whether to fetch the " - "-target_files-*.zip file."); - -DEFINE_string(credential_source, "", "Build API credential source"); -DEFINE_string(directory, cvd::CurrentDirectory(), "Target directory to fetch " - "files into"); -DEFINE_bool(run_next_stage, false, "Continue running the device through the next stage."); -DEFINE_string(wait_retry_period, "20", "Retry period for pending builds given " - "in seconds. Set to 0 to not wait."); - -namespace { - -const std::string HOST_TOOLS = "cvd-host_package.tar.gz"; -const std::string OTA_TOOLS = "otatools.zip"; -const std::string OTA_TOOLS_DIR = "/otatools/"; - -/** Returns the name of one of the artifact target zip files. - * - * For example, for a target "aosp_cf_x86_phone-userdebug" at a build "5824130", - * the image zip file would be "aosp_cf_x86_phone-img-5824130.zip" - */ -std::string target_build_zip(const DeviceBuild& build, const std::string& name) { - std::string target = build.target; - size_t dash_pos = target.find("-"); - if (dash_pos != std::string::npos) { - target.replace(dash_pos, target.size() - dash_pos, ""); - } - return target + "-" + name + "-" + build.id + ".zip"; -} - -std::vector<std::string> download_images(BuildApi* build_api, - const DeviceBuild& build, - const std::string& target_directory, - const std::vector<std::string>& images) { - std::string img_zip_name = target_build_zip(build, "img"); - auto artifacts = build_api->Artifacts(build); - bool has_image_zip = false; - for (const auto& artifact : artifacts) { - has_image_zip |= artifact.Name() == img_zip_name; - } - if (!has_image_zip) { - LOG(FATAL) << "Target " << build.target << " at id " << build.id - << " did not have " << img_zip_name; - return {}; - } - std::string local_path = target_directory + "/" + img_zip_name; - if (!build_api->ArtifactToFile(build, img_zip_name, local_path)) { - LOG(FATAL) << "Unable to download " << build << ":" << img_zip_name << " to " - << local_path; - return {}; - } - - std::vector<std::string> files = ExtractImages(local_path, target_directory, images); - if (files.empty()) { - LOG(ERROR) << "Could not extract " << local_path; - return {}; - } - if (unlink(local_path.c_str()) != 0) { - LOG(ERROR) << "Could not delete " << local_path; - files.push_back(local_path); - } - return files; -} -std::vector<std::string> download_images(BuildApi* build_api, - const DeviceBuild& build, - const std::string& target_directory) { - return download_images(build_api, build, target_directory, {}); -} - -std::vector<std::string> download_target_files(BuildApi* build_api, - const DeviceBuild& build, - const std::string& target_directory) { - std::string target_zip = target_build_zip(build, "target_files"); - auto artifacts = build_api->Artifacts(build); - bool has_target_zip = false; - for (const auto& artifact : artifacts) { - has_target_zip |= artifact.Name() == target_zip; - } - if (!has_target_zip) { - LOG(FATAL) << "Target " << build.target << " at id " << build.id - << " did not have " << target_zip; - return {}; - } - std::string local_path = target_directory + "/" + target_zip; - if (!build_api->ArtifactToFile(build, target_zip, local_path)) { - LOG(FATAL) << "Unable to download " << build << ":" << target_zip << " to " - << local_path; - return {}; - } - return {local_path}; -} - -std::vector<std::string> download_host_package(BuildApi* build_api, - const DeviceBuild& build, - const std::string& target_directory) { - auto artifacts = build_api->Artifacts(build); - bool has_host_package = false; - for (const auto& artifact : artifacts) { - has_host_package |= artifact.Name() == HOST_TOOLS; - } - if (!has_host_package) { - LOG(FATAL) << "Target " << build.target << " at id " << build.id - << " did not have " << HOST_TOOLS; - return {}; - } - std::string local_path = target_directory + "/" + HOST_TOOLS; - - if (!build_api->ArtifactToFile(build, HOST_TOOLS, local_path)) { - LOG(FATAL) << "Unable to download " << build << ":" << HOST_TOOLS << " to " - << local_path; - return {}; - } - - cvd::Archive archive(local_path); - if (!archive.ExtractAll(target_directory)) { - LOG(FATAL) << "Could not extract " << local_path; - return {}; - } - std::vector<std::string> files = archive.Contents(); - for (auto& file : files) { - file = target_directory + "/" + file; - } - if (unlink(local_path.c_str()) != 0) { - LOG(ERROR) << "Could not delete " << local_path; - files.push_back(local_path); - } - return files; -} - -bool desparse(const std::string& file) { - LOG(INFO) << "Unsparsing " << file; - cvd::Command dd_cmd("/bin/dd"); - dd_cmd.AddParameter("if=", file); - dd_cmd.AddParameter("of=", file); - dd_cmd.AddParameter("conv=notrunc"); - dd_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, - cvd::Subprocess::StdIOChannel::kStdErr); - if (dd_cmd.Start().Wait() != 0) { - LOG(ERROR) << "Could not unsparse " << file; - return false; - } - return true; -} - -std::vector<std::string> download_ota_tools(BuildApi* build_api, - const DeviceBuild& build, - const std::string& target_directory) { - auto artifacts = build_api->Artifacts(build); - bool has_host_package = false; - for (const auto& artifact : artifacts) { - has_host_package |= artifact.Name() == OTA_TOOLS; - } - if (!has_host_package) { - LOG(ERROR) << "Target " << build.target << " at id " << build.id - << " did not have " << OTA_TOOLS; - return {}; - } - std::string local_path = target_directory + "/" + OTA_TOOLS; - - if (!build_api->ArtifactToFile(build, OTA_TOOLS, local_path)) { - LOG(ERROR) << "Unable to download " << build << ":" << OTA_TOOLS << " to " - << local_path; - return {}; - } - - std::string otatools_dir = target_directory + OTA_TOOLS_DIR; - if (!cvd::DirectoryExists(otatools_dir) && mkdir(otatools_dir.c_str(), 0777) != 0) { - LOG(FATAL) << "Could not create " << otatools_dir; - return {}; - } - cvd::Archive archive(local_path); - if (!archive.ExtractAll(otatools_dir)) { - LOG(FATAL) << "Could not extract " << local_path; - return {}; - } - std::vector<std::string> files = archive.Contents(); - for (auto& file : files) { - file = target_directory + OTA_TOOLS_DIR + file; - } - files.push_back(local_path); - return files; -} - -void AddFilesToConfig(cvd::FileSource purpose, const DeviceBuild& build, - const std::vector<std::string>& paths, cvd::FetcherConfig* config, - bool override_entry = false) { - for (const std::string& path : paths) { - cvd::CvdFile file(purpose, build.id, build.target, path); - bool added = config->add_cvd_file(file, override_entry); - if (!added) { - LOG(ERROR) << "Duplicate file " << file; - LOG(ERROR) << "Existing file: " << config->get_cvd_files()[path]; - LOG(FATAL) << "Failed to add path " << path; - } - } -} - -std::string USAGE_MESSAGE = - "<flags>\n" - "\n" - "\"*_build\" flags accept values in the following format:\n" - "\"branch/build_target\" - latest build of \"branch\" for \"build_target\"\n" - "\"build_id/build_target\" - build \"build_id\" for \"build_target\"\n" - "\"branch\" - latest build of \"branch\" for \"aosp_cf_x86_phone-userdebug\"\n" - "\"build_id\" - build \"build_id\" for \"aosp_cf_x86_phone-userdebug\"\n"; - -} // namespace - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - gflags::SetUsageMessage(USAGE_MESSAGE); - gflags::ParseCommandLineFlags(&argc, &argv, true); - - cvd::FetcherConfig config; - config.RecordFlags(); - - std::string target_dir = cvd::AbsolutePath(FLAGS_directory); - if (!cvd::DirectoryExists(target_dir) && mkdir(target_dir.c_str(), 0777) != 0) { - LOG(FATAL) << "Could not create " << target_dir; - } - std::chrono::seconds retry_period(std::stoi(FLAGS_wait_retry_period)); - - curl_global_init(CURL_GLOBAL_DEFAULT); - { - std::unique_ptr<CredentialSource> credential_source; - if (FLAGS_credential_source == "gce") { - credential_source = GceMetadataCredentialSource::make(); - } else if (FLAGS_credential_source != "") { - credential_source = FixedCredentialSource::make(FLAGS_credential_source); - } - BuildApi build_api(std::move(credential_source)); - - DeviceBuild default_build = ArgumentToBuild(&build_api, FLAGS_default_build, - DEFAULT_BUILD_TARGET, - retry_period); - - std::vector<std::string> host_package_files = - download_host_package(&build_api, default_build, target_dir); - if (host_package_files.empty()) { - LOG(FATAL) << "Could not download host package for " << default_build; - } - AddFilesToConfig(cvd::FileSource::DEFAULT_BUILD, default_build, host_package_files, &config); - - if (FLAGS_system_build != "" || FLAGS_kernel_build != "" || FLAGS_otatools_build != "") { - DeviceBuild ota_build = default_build; - if (FLAGS_otatools_build != "") { - ota_build = ArgumentToBuild(&build_api, FLAGS_otatools_build, - DEFAULT_BUILD_TARGET, retry_period); - } - std::vector<std::string> ota_tools_files = - download_ota_tools(&build_api, ota_build, target_dir); - if (ota_tools_files.empty()) { - LOG(FATAL) << "Could not download ota tools for " << ota_build; - } - AddFilesToConfig(cvd::FileSource::DEFAULT_BUILD, default_build, ota_tools_files, &config); - } - if (FLAGS_download_img_zip) { - std::vector<std::string> image_files = - download_images(&build_api, default_build, target_dir); - if (image_files.empty()) { - LOG(FATAL) << "Could not download images for " << default_build; - } - desparse(target_dir + "/userdata.img"); - AddFilesToConfig(cvd::FileSource::DEFAULT_BUILD, default_build, image_files, &config); - } - if (FLAGS_system_build != "" || FLAGS_download_target_files_zip) { - std::vector<std::string> target_files = - download_target_files(&build_api, default_build, target_dir); - if (target_files.empty()) { - LOG(FATAL) << "Could not download target files for " << default_build; - } - AddFilesToConfig(cvd::FileSource::DEFAULT_BUILD, default_build, target_files, &config); - } - - if (FLAGS_system_build != "") { - DeviceBuild system_build = ArgumentToBuild(&build_api, FLAGS_system_build, - DEFAULT_BUILD_TARGET, - retry_period); - if (FLAGS_download_img_zip) { - std::vector<std::string> image_files = - download_images(&build_api, system_build, target_dir, {"system.img"}); - if (image_files.empty()) { - LOG(INFO) << "Could not find system image for " << system_build - << "in the img zip. Assuming a super image build, which will " - << "get the super image from the target zip."; - } else { - AddFilesToConfig(cvd::FileSource::SYSTEM_BUILD, system_build, image_files, - &config, true); - } - } - std::vector<std::string> target_files = - download_target_files(&build_api, system_build, target_dir); - if (target_files.empty()) { - LOG(FATAL) << "Could not download target files for " << system_build; - } - AddFilesToConfig(cvd::FileSource::SYSTEM_BUILD, system_build, target_files, &config); - } - - if (FLAGS_kernel_build != "") { - DeviceBuild kernel_build = ArgumentToBuild(&build_api, FLAGS_kernel_build, - "kernel", retry_period); - - std::string local_path = target_dir + "/kernel"; - if (build_api.ArtifactToFile(kernel_build, "bzImage", local_path)) { - AddFilesToConfig(cvd::FileSource::KERNEL_BUILD, kernel_build, {local_path}, &config); - } else { - LOG(FATAL) << "Could not download " << kernel_build << ":bzImage to " - << local_path; - } - std::vector<Artifact> kernel_artifacts = build_api.Artifacts(kernel_build); - for (const auto& artifact : kernel_artifacts) { - if (artifact.Name() != "initramfs.img") { - continue; - } - bool downloaded = build_api.ArtifactToFile( - kernel_build, "initramfs.img", target_dir + "/initramfs.img"); - if (!downloaded) { - LOG(FATAL) << "Could not download " << kernel_build << ":initramfs.img to " - << target_dir + "/initramfs.img"; - } - AddFilesToConfig(cvd::FileSource::KERNEL_BUILD, kernel_build, - {target_dir + "/initramfs.img"}, &config); - } - } - } - curl_global_cleanup(); - - // Due to constraints of the build system, artifacts intentionally cannot determine - // their own build id. So it's unclear which build number fetch_cvd itself was built at. - // https://android.googlesource.com/platform/build/+/979c9f3/Changes.md#build_number - std::string fetcher_path = target_dir + "/fetcher_config.json"; - AddFilesToConfig(cvd::GENERATED, DeviceBuild("", ""), {fetcher_path}, &config); - config.SaveToFile(fetcher_path); - - for (const auto& file : config.get_cvd_files()) { - std::cout << file.second.file_path << "\n"; - } - std::cout << std::flush; - - if (!FLAGS_run_next_stage) { - return 0; - } - - if (chdir(target_dir.c_str()) != 0) { - int error_num = errno; - LOG(FATAL) << "Could not change directory to \"" << target_dir << "\"." - << "errno was " << error_num << " \"" << strerror(error_num) << "\""; - } - - // Ignore return code. We want to make sure there is no running instance, - // and stop_cvd will exit with an error code if there is already no running instance. - cvd::Command stop_cmd("bin/stop_cvd"); - stop_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, - cvd::Subprocess::StdIOChannel::kStdErr); - stop_cmd.Start().Wait(); - - // gflags::ParseCommandLineFlags will remove fetch_cvd's flags from this. - // This depends the remove_flags argument (3rd) is "true". - - // TODO(b/139199114): Go into assemble_cvd when the interface is stable and implemented. - - std::string next_stage = "bin/launch_cvd"; - std::vector<const char*> next_stage_argv = {"launch_cvd"}; - LOG(INFO) << "Running " << next_stage; - for (int i = 1; i < argc; i++) { - LOG(INFO) << argv[i]; - next_stage_argv.push_back(argv[i]); - } - next_stage_argv.push_back(nullptr); - execv(next_stage.c_str(), const_cast<char* const*>(next_stage_argv.data())); - int error = errno; - LOG(FATAL) << "execv returned with errno " << error << ":" << strerror(error); -} diff --git a/host/commands/fetcher/install_zip.cc b/host/commands/fetcher/install_zip.cc deleted file mode 100644 index bd6294f2..00000000 --- a/host/commands/fetcher/install_zip.cc +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "install_zip.h" - -#include <stdlib.h> - -#include <string> -#include <vector> - -#include <glog/logging.h> - -#include "common/libs/utils/archive.h" -#include "common/libs/utils/subprocess.h" - -std::vector<std::string> ExtractImages(const std::string& archive_file, - const std::string& target_directory, - const std::vector<std::string>& images) { - cvd::Archive archive(archive_file); - bool extracted = - images.size() > 0 - ? archive.ExtractFiles(images, target_directory) - : archive.ExtractAll(target_directory); - if (!extracted) { - LOG(ERROR) << "Unable to extract images."; - return {}; - } - - bool extraction_success = true; - std::vector<std::string> files = - images.size() > 0 ? images : archive.Contents(); - for (const auto& file : files) { - if (file.find(".img") == std::string::npos) { - continue; - } - std::string extracted_file = target_directory + "/" + file; - - std::string file_input, file_output; - cvd::Command file_cmd("/usr/bin/file"); - file_cmd.AddParameter(extracted_file); - auto file_ret = cvd::RunWithManagedStdio(std::move(file_cmd), &file_input, - &file_output, nullptr); - if (file_ret != 0) { - LOG(ERROR) << "Unable to run file on " << file << ", returned" << file_ret; - extraction_success = false; - continue; - } - if (file_output.find("Android sparse image,") == std::string::npos) { - continue; - } - std::string inflated_file = extracted_file + ".inflated"; - cvd::Command simg_cmd("/usr/bin/simg2img"); - simg_cmd.AddParameter(extracted_file); - simg_cmd.AddParameter(inflated_file); - simg_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, - cvd::Subprocess::StdIOChannel::kStdErr); - if (simg_cmd.Start().Wait() != 0) { - LOG(ERROR) << "Unable to run simg2img on " << file; - extraction_success = false; - continue; - } - auto rename_ret = rename(inflated_file.c_str(), extracted_file.c_str()); - if (rename_ret != 0) { - LOG(ERROR) << "Unable to rename deflated version of " << file; - extraction_success = false; - } - } - for (auto& file : files) { - file = target_directory + "/" + file; - } - return extraction_success ? files : std::vector<std::string>{}; -} diff --git a/host/commands/fetcher/install_zip.h b/host/commands/fetcher/install_zip.h deleted file mode 100644 index c59ff33a..00000000 --- a/host/commands/fetcher/install_zip.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include <string> -#include <vector> - -std::vector<std::string> ExtractImages(const std::string& archive, - const std::string& target_directory, - const std::vector<std::string>& images); diff --git a/host/commands/kernel_log_monitor/Android.bp b/host/commands/kernel_log_monitor/Android.bp deleted file mode 100644 index 54dda47f..00000000 --- a/host/commands/kernel_log_monitor/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_binary_host { - name: "kernel_log_monitor", - srcs: [ - "main.cc", - "kernel_log_server.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/kernel_log_monitor/kernel_log_server.cc b/host/commands/kernel_log_monitor/kernel_log_server.cc deleted file mode 100644 index 42317517..00000000 --- a/host/commands/kernel_log_monitor/kernel_log_server.cc +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/kernel_log_monitor/kernel_log_server.h" - -#include <map> -#include <utility> - -#include <glog/logging.h> -#include <netinet/in.h> -#include "common/libs/fs/shared_select.h" -#include "host/libs/config/cuttlefish_config.h" - -using cvd::SharedFD; - -namespace { -static const std::map<std::string, std::string> kInformationalPatterns = { - {"] Linux version ", "GUEST_KERNEL_VERSION: "}, - {"GUEST_BUILD_FINGERPRINT: ", "GUEST_BUILD_FINGERPRINT: "}, -}; - -static const std::map<std::string, monitor::BootEvent> kStageToEventMap = { - {vsoc::kBootStartedMessage, monitor::BootEvent::BootStarted}, - {vsoc::kBootCompletedMessage, monitor::BootEvent::BootCompleted}, - {vsoc::kBootFailedMessage, monitor::BootEvent::BootFailed}, - {vsoc::kMobileNetworkConnectedMessage, - monitor::BootEvent::MobileNetworkConnected}, - {vsoc::kWifiConnectedMessage, monitor::BootEvent::WifiNetworkConnected}, - // TODO(b/131864854): Replace this with a string less likely to change - {"init: starting service 'adbd'", monitor::BootEvent::AdbdStarted}, -}; - -void ProcessSubscriptions( - monitor::BootEvent evt, - std::vector<monitor::BootEventCallback>* subscribers) { - auto active_subscription_count = subscribers->size(); - std::size_t idx = 0; - while (idx < active_subscription_count) { - // Call the callback - auto action = (*subscribers)[idx](evt); - if (action == monitor::SubscriptionAction::ContinueSubscription) { - ++idx; - } else { - // Cancel the subscription by swaping it with the last active subscription - // and decreasing the active subscription count - --active_subscription_count; - std::swap((*subscribers)[idx], (*subscribers)[active_subscription_count]); - } - } - // Keep only the active subscriptions - subscribers->resize(active_subscription_count); -} -} // namespace - -namespace monitor { -KernelLogServer::KernelLogServer(cvd::SharedFD pipe_fd, - const std::string& log_name, - bool deprecated_boot_completed) - : pipe_fd_(pipe_fd), - log_fd_(cvd::SharedFD::Open(log_name.c_str(), O_CREAT | O_RDWR, 0666)), - deprecated_boot_completed_(deprecated_boot_completed) {} - -void KernelLogServer::BeforeSelect(cvd::SharedFDSet* fd_read) const { - fd_read->Set(pipe_fd_); -} - -void KernelLogServer::AfterSelect(const cvd::SharedFDSet& fd_read) { - if (fd_read.IsSet(pipe_fd_)) { - HandleIncomingMessage(); - } -} - -void KernelLogServer::SubscribeToBootEvents( - monitor::BootEventCallback callback) { - subscribers_.push_back(callback); -} - -bool KernelLogServer::HandleIncomingMessage() { - const size_t buf_len = 256; - char buf[buf_len]; - ssize_t ret = pipe_fd_->Read(buf, buf_len); - if (ret < 0) { - LOG(ERROR) << "Could not read kernel logs: " << pipe_fd_->StrError(); - return false; - } - if (ret == 0) return false; - // Write the log to a file - if (log_fd_->Write(buf, ret) < 0) { - LOG(ERROR) << "Could not write kernel log to file: " << log_fd_->StrError(); - return false; - } - - // Detect VIRTUAL_DEVICE_BOOT_* - for (ssize_t i=0; i<ret; i++) { - if ('\n' == buf[i]) { - for (auto& info_kv : kInformationalPatterns) { - auto& match = info_kv.first; - auto& prefix = info_kv.second; - auto pos = line_.find(match); - if (std::string::npos != pos) { - LOG(INFO) << prefix << line_.substr(pos + match.size()); - } - } - for (auto& stage_kv : kStageToEventMap) { - auto& stage = stage_kv.first; - auto event = stage_kv.second; - if (std::string::npos != line_.find(stage)) { - // Log the stage - LOG(INFO) << stage; - ProcessSubscriptions(event, &subscribers_); - //TODO(b/69417553) Remove this when our clients have transitioned to the - // new boot completed - if (deprecated_boot_completed_) { - // Write to host kernel log - FILE* log = popen("/usr/bin/sudo /usr/bin/tee /dev/kmsg", "w"); - fprintf(log, "%s\n", stage.c_str()); - fclose(log); - } - } - } - line_.clear(); - } - line_.append(1, buf[i]); - } - - return true; -} - -} // namespace monitor diff --git a/host/commands/kernel_log_monitor/kernel_log_server.h b/host/commands/kernel_log_monitor/kernel_log_server.h deleted file mode 100644 index f5709eec..00000000 --- a/host/commands/kernel_log_monitor/kernel_log_server.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <stdint.h> - -#include <functional> -#include <string> -#include <vector> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" - -namespace monitor { - -enum BootEvent : int32_t { - BootStarted = 0, - BootCompleted = 1, - BootFailed = 2, - WifiNetworkConnected = 3, - MobileNetworkConnected = 4, - AdbdStarted = 5, -}; - -enum class SubscriptionAction { - ContinueSubscription, - CancelSubscription, -}; - -using BootEventCallback = std::function<SubscriptionAction(BootEvent)>; - -// KernelLogServer manages incoming kernel log connection from QEmu. Only accept -// one connection. -class KernelLogServer { - public: - KernelLogServer(cvd::SharedFD pipe_fd, - const std::string& log_name, - bool deprecated_boot_completed); - - ~KernelLogServer() = default; - - // BeforeSelect is Called right before Select() to populate interesting - // SharedFDs. - void BeforeSelect(cvd::SharedFDSet* fd_read) const; - - // AfterSelect is Called right after Select() to detect and respond to changes - // on affected SharedFDs. - void AfterSelect(const cvd::SharedFDSet& fd_read); - - void SubscribeToBootEvents(BootEventCallback callback); - private: - // Respond to message from remote client. - // Returns false, if client disconnected. - bool HandleIncomingMessage(); - - cvd::SharedFD pipe_fd_; - cvd::SharedFD log_fd_; - std::string line_; - bool deprecated_boot_completed_; - std::vector<BootEventCallback> subscribers_; - - KernelLogServer(const KernelLogServer&) = delete; - KernelLogServer& operator=(const KernelLogServer&) = delete; -}; - -} // namespace monitor diff --git a/host/commands/kernel_log_monitor/main.cc b/host/commands/kernel_log_monitor/main.cc deleted file mode 100644 index 6956e68c..00000000 --- a/host/commands/kernel_log_monitor/main.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <signal.h> -#include <unistd.h> - -#include <string> -#include <vector> - -#include <android-base/strings.h> -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include <common/libs/fs/shared_fd.h> -#include <common/libs/fs/shared_select.h> -#include <host/libs/config/cuttlefish_config.h> -#include "host/commands/kernel_log_monitor/kernel_log_server.h" - -DEFINE_int32(log_pipe_fd, -1, - "A file descriptor representing a (UNIX) socket from which to " - "read the logs. If -1 is given the socket is created according to " - "the instance configuration"); -DEFINE_string(subscriber_fds, "", - "A comma separated list of file descriptors (most likely pipes) to" - " send boot events to."); - -std::vector<cvd::SharedFD> SubscribersFromCmdline() { - // Validate the parameter - std::string fd_list = FLAGS_subscriber_fds; - for (auto c: fd_list) { - if (c != ',' && (c < '0' || c > '9')) { - LOG(ERROR) << "Invalid file descriptor list: " << fd_list; - std::exit(1); - } - } - - auto fds = android::base::Split(FLAGS_subscriber_fds, ","); - std::vector<cvd::SharedFD> shared_fds; - for (auto& fd_str: fds) { - auto fd = std::stoi(fd_str); - auto shared_fd = cvd::SharedFD::Dup(fd); - close(fd); - shared_fds.push_back(shared_fd); - } - - return shared_fds; -} - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto subscriber_fds = SubscribersFromCmdline(); - - // Disable default handling of SIGPIPE - struct sigaction new_action { - }, old_action{}; - new_action.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &new_action, &old_action); - - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Unable to get config object"; - return 1; - } - - cvd::SharedFD pipe; - if (FLAGS_log_pipe_fd < 0) { - auto log_name = config->kernel_log_pipe_name(); - pipe = cvd::SharedFD::Open(log_name.c_str(), O_RDONLY); - } else { - pipe = cvd::SharedFD::Dup(FLAGS_log_pipe_fd); - close(FLAGS_log_pipe_fd); - } - - if (!pipe->IsOpen()) { - LOG(ERROR) << "Error opening log pipe: " << pipe->StrError(); - return 2; - } - - monitor::KernelLogServer klog{pipe, config->PerInstancePath("kernel.log"), - config->deprecated_boot_completed()}; - - for (auto subscriber_fd: subscriber_fds) { - if (subscriber_fd->IsOpen()) { - klog.SubscribeToBootEvents([subscriber_fd](monitor::BootEvent evt) { - int retval = subscriber_fd->Write(&evt, sizeof(evt)); - if (retval < 0) { - if (subscriber_fd->GetErrno() != EPIPE) { - LOG(ERROR) << "Error while writing to pipe: " - << subscriber_fd->StrError(); - } - subscriber_fd->Close(); - return monitor::SubscriptionAction::CancelSubscription; - } - return monitor::SubscriptionAction::ContinueSubscription; - }); - } else { - LOG(ERROR) << "Subscriber fd isn't valid: " << subscriber_fd->StrError(); - // Don't return here, we still need to write the logs to a file - } - } - - for (;;) { - cvd::SharedFDSet fd_read; - fd_read.Zero(); - - klog.BeforeSelect(&fd_read); - - int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr); - if (ret <= 0) continue; - - klog.AfterSelect(fd_read); - } - - return 0; -} diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp deleted file mode 100644 index dafe9907..00000000 --- a/host/commands/launch/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_binary_host { - name: "launch_cvd", - srcs: [ - "filesystem_explorer.cc", - "flag_forwarder.cc", - "launch_cvd.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - "libnl", - ], - static_libs: [ - "libcuttlefish_host_config", - "libcuttlefish_vm_manager", - "libgflags", - "libxml2", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"], -} diff --git a/host/commands/launch/filesystem_explorer.cc b/host/commands/launch/filesystem_explorer.cc deleted file mode 100644 index 4d43dcfa..00000000 --- a/host/commands/launch/filesystem_explorer.cc +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "filesystem_explorer.h" - -#include <set> -#include <string> - -#include <dirent.h> -#include <errno.h> -#include <sys/types.h> - -#include <glog/logging.h> - -#include "common/libs/utils/files.h" -#include "common/libs/utils/environment.h" -#include "host/libs/config/fetcher_config.h" - -cvd::FetcherConfig AvailableFilesReport() { - std::string current_directory = cvd::AbsolutePath(cvd::CurrentDirectory()); - if (cvd::FileExists(current_directory + "/fetcher_config.json")) { - cvd::FetcherConfig config; - config.LoadFromFile(current_directory + "/fetcher_config.json"); - return config; - } - - std::set<std::string> files; - - std::string psuedo_fetcher_dir = - cvd::StringFromEnv("ANDROID_HOST_OUT", - cvd::StringFromEnv("HOME", current_directory)); - std::string psuedo_fetcher_config = - psuedo_fetcher_dir + "/launcher_pseudo_fetcher_config.json"; - files.insert(psuedo_fetcher_config); - - cvd::FetcherConfig config; - config.RecordFlags(); - for (const auto& file : files) { - config.add_cvd_file(cvd::CvdFile(cvd::FileSource::LOCAL_FILE, "", "", file)); - } - config.SaveToFile(psuedo_fetcher_config); - return config; -} diff --git a/host/commands/launch/filesystem_explorer.h b/host/commands/launch/filesystem_explorer.h deleted file mode 100644 index 3290ebd8..00000000 --- a/host/commands/launch/filesystem_explorer.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "host/libs/config/fetcher_config.h" - -cvd::FetcherConfig AvailableFilesReport(); diff --git a/host/commands/launch/flag_forwarder.cc b/host/commands/launch/flag_forwarder.cc deleted file mode 100644 index 9a8e6a22..00000000 --- a/host/commands/launch/flag_forwarder.cc +++ /dev/null @@ -1,324 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "flag_forwarder.h" - -#include <cstring> - -#include <sstream> -#include <map> -#include <string> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> -#include <libxml/tree.h> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/subprocess.h" - -/** - * Superclass for a flag loaded from another process. - * - * An instance of this class defines a flag available either in this subprocess - * or another flag. If a flag needs to be registered in the current process, see - * the DynamicFlag subclass. If multiple subprocesses declare a flag with the - * same name, they all should receive that flag, but the DynamicFlag should only - * be created zero or one times. Zero times if the parent process defines it as - * well, one time if the parent does not define it. - * - * Notably, gflags itself defines some flags that are present in every binary. - */ -class SubprocessFlag { - std::string subprocess_; - std::string name_; -public: - SubprocessFlag(const std::string& subprocess, const std::string& name) - : subprocess_(subprocess), name_(name) { - } - virtual ~SubprocessFlag() = default; - SubprocessFlag(const SubprocessFlag&) = delete; - SubprocessFlag& operator=(const SubprocessFlag&) = delete; - SubprocessFlag(SubprocessFlag&&) = delete; - SubprocessFlag& operator=(SubprocessFlag&&) = delete; - - const std::string& Subprocess() const { return subprocess_; } - const std::string& Name() const { return name_; } -}; - -/* - * A dynamic gflags flag. Creating an instance of this class is equivalent to - * registering a flag with DEFINE_<type>. Instances of this class should not - * be deleted while flags are still in use (likely through the end of main). - * - * This is implemented as a wrapper around gflags::FlagRegisterer. This class - * serves a dual purpose of holding the memory for gflags::FlagRegisterer as - * that normally expects memory to be held statically. The other reason is to - * subclass class SubprocessFlag to fit into the flag-forwarding scheme. - */ -template<typename T> -class DynamicFlag : public SubprocessFlag { - std::string help_; - std::string filename_; - T current_storage_; - T defvalue_storage_; - gflags::FlagRegisterer registerer_; -public: - DynamicFlag(const std::string& subprocess, const std::string& name, - const std::string& help, const std::string& filename, - const T& current, const T& defvalue) - : SubprocessFlag(subprocess, name), help_(help), filename_(filename), - current_storage_(current), defvalue_storage_(defvalue), - registerer_(Name().c_str(), help_.c_str(), filename_.c_str(), - ¤t_storage_, &defvalue_storage_) { - } -}; - -namespace { - -/** - * Returns a mapping between flag name and "gflags type" as strings for flags - * defined in the binary. - */ -std::map<std::string, std::string> CurrentFlagsToTypes() { - std::map<std::string, std::string> name_to_type; - std::vector<gflags::CommandLineFlagInfo> self_flags; - gflags::GetAllFlags(&self_flags); - for (auto& flag : self_flags) { - name_to_type[flag.name] = flag.type; - } - return name_to_type; -} - -/** - * Returns a pointer to the child of `node` with name `name`. - * - * For example, invoking `xmlChildWithName(<foo><bar>abc</bar></foo>, "foo")` - * will return <bar>abc</bar>. - */ -xmlNodePtr xmlChildWithName(xmlNodePtr node, const std::string& name) { - for (xmlNodePtr child = node->children; child != nullptr; child = child->next) { - if (child->type != XML_ELEMENT_NODE) { - continue; - } - if (std::strcmp((const char*) child->name, name.c_str()) == 0) { - return child; - } - } - LOG(WARNING) << "no child with name " << name; - return nullptr; -} - -/** - * Returns a string with the content of an xml node. - * - * For example, calling `xmlContent(<bar>abc</bar>)` will return "abc". - */ -std::string xmlContent(xmlNodePtr node) { - if (node == nullptr || node->children == NULL - || node->children->type != xmlElementType::XML_TEXT_NODE) { - return ""; - } - return std::string((char*) node->children->content); -} - -template<typename T> -T FromString(const std::string& str) { - std::stringstream stream(str); - T output; - stream >> output; - return output; -} - -/** - * Creates a dynamic flag - */ -std::unique_ptr<SubprocessFlag> MakeDynamicFlag( - const std::string& subprocess, - const gflags::CommandLineFlagInfo& flag_info) { - std::unique_ptr<SubprocessFlag> ptr; - if (flag_info.type == "bool") { - ptr.reset(new DynamicFlag<bool>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<bool>(flag_info.default_value), - FromString<bool>(flag_info.current_value))); - } else if (flag_info.type == "int32") { - ptr.reset(new DynamicFlag<int32_t>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<int32_t>(flag_info.default_value), - FromString<int32_t>(flag_info.current_value))); - } else if (flag_info.type == "uint32") { - ptr.reset(new DynamicFlag<uint32_t>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<uint32_t>(flag_info.default_value), - FromString<uint32_t>(flag_info.current_value))); - } else if (flag_info.type == "int64") { - ptr.reset(new DynamicFlag<int64_t>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<int64_t>(flag_info.default_value), - FromString<int64_t>(flag_info.current_value))); - } else if (flag_info.type == "uint64") { - ptr.reset(new DynamicFlag<uint64_t>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<uint64_t>(flag_info.default_value), - FromString<uint64_t>(flag_info.current_value))); - } else if (flag_info.type == "double") { - ptr.reset(new DynamicFlag<double>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - FromString<double>(flag_info.default_value), - FromString<double>(flag_info.current_value))); - } else if (flag_info.type == "string") { - ptr.reset(new DynamicFlag<std::string>(subprocess, flag_info.name, - flag_info.description, - flag_info.filename, - flag_info.default_value, - flag_info.current_value)); - } else { - LOG(FATAL) << "Unknown type \"" << flag_info.type << "\" for flag " << flag_info.name; - } - return ptr; -} - -std::vector<gflags::CommandLineFlagInfo> FlagsForSubprocess(std::string helpxml_output) { - // Hack to try to filter out log messages that come before the xml - helpxml_output = helpxml_output.substr(helpxml_output.find("<?xml")); - - xmlDocPtr doc = xmlReadMemory(helpxml_output.c_str(), helpxml_output.size(), - NULL, NULL, 0); - if (doc == NULL) { - LOG(FATAL) << "Could not parse xml of subprocess `--helpxml`"; - } - xmlNodePtr root_element = xmlDocGetRootElement(doc); - std::vector<gflags::CommandLineFlagInfo> flags; - for (xmlNodePtr flag = root_element->children; flag != nullptr; flag = flag->next) { - if (std::strcmp((const char*) flag->name, "flag") != 0) { - continue; - } - gflags::CommandLineFlagInfo flag_info; - flag_info.name = xmlContent(xmlChildWithName(flag, "name")); - flag_info.type = xmlContent(xmlChildWithName(flag, "type")); - flag_info.filename = xmlContent(xmlChildWithName(flag, "file")); - flag_info.description = xmlContent(xmlChildWithName(flag, "meaning")); - flag_info.current_value = xmlContent(xmlChildWithName(flag, "current")); - flag_info.default_value = xmlContent(xmlChildWithName(flag, "default")); - flags.emplace_back(std::move(flag_info)); - } - xmlFree(doc); - xmlCleanupParser(); - return flags; -} - -} // namespace - -FlagForwarder::FlagForwarder(std::set<std::string> subprocesses) - : subprocesses_(std::move(subprocesses)) { - std::map<std::string, std::string> flag_to_type = CurrentFlagsToTypes(); - - for (const auto& subprocess : subprocesses_) { - cvd::Command cmd(subprocess); - cmd.SetVerbose(false); - cmd.AddParameter("--helpxml"); - std::string helpxml_input, helpxml_output, helpxml_error; - int helpxml_ret = cvd::RunWithManagedStdio(std::move(cmd), &helpxml_input, - &helpxml_output, &helpxml_error); - if (helpxml_ret != 1) { - LOG(FATAL) << subprocess << " --helpxml returned unexpected response " - << helpxml_ret << ". Stderr was " << helpxml_error; - return; - } - - auto subprocess_flags = FlagsForSubprocess(helpxml_output); - for (const auto& flag : subprocess_flags) { - if (flag_to_type.count(flag.name)) { - if (flag_to_type[flag.name] == flag.type) { - flags_.emplace(std::make_unique<SubprocessFlag>(subprocess, flag.name)); - } else { - LOG(FATAL) << flag.name << "defined as " << flag_to_type[flag.name] - << " and " << flag.type; - return; - } - } else { - flag_to_type[flag.name] = flag.type; - flags_.emplace(MakeDynamicFlag(subprocess, flag)); - } - } - } -} - -// Destructor must be defined in an implementation file. -// https://stackoverflow.com/questions/6012157 -FlagForwarder::~FlagForwarder() = default; - -void FlagForwarder::UpdateFlagDefaults() const { - - for (const auto& subprocess : subprocesses_) { - cvd::Command cmd(subprocess); - cmd.SetVerbose(false); - std::vector<std::string> invocation = {subprocess}; - for (const auto& flag : ArgvForSubprocess(subprocess)) { - cmd.AddParameter(flag); - } - // Disable flags that could cause the subprocess to exit before helpxml. - // See gflags_reporting.cc. - cmd.AddParameter("--nohelp"); - cmd.AddParameter("--nohelpfull"); - cmd.AddParameter("--nohelpshort"); - cmd.AddParameter("--helpon="); - cmd.AddParameter("--helpmatch="); - cmd.AddParameter("--nohelppackage="); - cmd.AddParameter("--noversion"); - // Ensure this is set on by putting it at the end. - cmd.AddParameter("--helpxml"); - std::string helpxml_input, helpxml_output, helpxml_error; - int helpxml_ret = cvd::RunWithManagedStdio(std::move(cmd), &helpxml_input, - &helpxml_output, &helpxml_error); - if (helpxml_ret != 1) { - LOG(FATAL) << subprocess << " --helpxml returned unexpected response " - << helpxml_ret << ". Stderr was " << helpxml_error; - return; - } - - auto subprocess_flags = FlagsForSubprocess(helpxml_output); - for (const auto& flag : subprocess_flags) { - gflags::SetCommandLineOptionWithMode( - flag.name.c_str(), - flag.default_value.c_str(), - gflags::FlagSettingMode::SET_FLAGS_DEFAULT); - } - } -} - -std::vector<std::string> FlagForwarder::ArgvForSubprocess( - const std::string& subprocess) const { - std::vector<std::string> subprocess_argv; - for (const auto& flag : flags_) { - if (flag->Subprocess() == subprocess) { - gflags::CommandLineFlagInfo flag_info = - gflags::GetCommandLineFlagInfoOrDie(flag->Name().c_str()); - if (!flag_info.is_default) { - subprocess_argv.push_back("--" + flag->Name() + "=" + flag_info.current_value); - } - } - } - return subprocess_argv; -} - diff --git a/host/commands/launch/flag_forwarder.h b/host/commands/launch/flag_forwarder.h deleted file mode 100644 index b0f5cfe1..00000000 --- a/host/commands/launch/flag_forwarder.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include <memory> -#include <set> -#include <string> -#include <vector> - -class SubprocessFlag; - -class FlagForwarder { - std::set<std::string> subprocesses_; - std::set<std::unique_ptr<SubprocessFlag>> flags_; - -public: - FlagForwarder(std::set<std::string> subprocesses); - ~FlagForwarder(); - FlagForwarder(FlagForwarder&&) = default; - FlagForwarder(const FlagForwarder&) = delete; - FlagForwarder& operator=(FlagForwarder&&) = default; - FlagForwarder& operator=(const FlagForwarder&) = delete; - - void UpdateFlagDefaults() const; - std::vector<std::string> ArgvForSubprocess(const std::string& subprocess) const; -}; diff --git a/host/commands/launch/launch_cvd.cc b/host/commands/launch/launch_cvd.cc deleted file mode 100644 index 9d3b108a..00000000 --- a/host/commands/launch/launch_cvd.cc +++ /dev/null @@ -1,134 +0,0 @@ -// -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <sstream> - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/subprocess.h" -#include "host/commands/launch/filesystem_explorer.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/config/fetcher_config.h" - -#include "flag_forwarder.h" - -/** - * If stdin is a tty, that means a user is invoking launch_cvd on the command - * line and wants automatic file detection for assemble_cvd. - * - * If stdin is not a tty, that means launch_cvd is being passed a list of files - * and that list should be forwarded to assemble_cvd. - * - * Controllable with a flag for extraordinary scenarios such as running from a - * daemon which closes its own stdin. - */ -DEFINE_bool(run_file_discovery, true, - "Whether to run file discovery or get input files from stdin."); - -namespace { - -std::string kAssemblerBin = vsoc::DefaultHostArtifactsPath("bin/assemble_cvd"); -std::string kRunnerBin = vsoc::DefaultHostArtifactsPath("bin/run_cvd"); - -cvd::Subprocess StartAssembler(cvd::SharedFD assembler_stdin, - cvd::SharedFD assembler_stdout, - const std::vector<std::string>& argv) { - cvd::Command assemble_cmd(kAssemblerBin); - for (const auto& arg : argv) { - assemble_cmd.AddParameter(arg); - } - if (assembler_stdin->IsOpen()) { - assemble_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, assembler_stdin); - } - assemble_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, assembler_stdout); - return assemble_cmd.Start(); -} - -cvd::Subprocess StartRunner(cvd::SharedFD runner_stdin, - const std::vector<std::string>& argv) { - cvd::Command run_cmd(kRunnerBin); - for (const auto& arg : argv) { - run_cmd.AddParameter(arg); - } - run_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, runner_stdin); - return run_cmd.Start(); -} - -void WriteFiles(cvd::FetcherConfig fetcher_config, cvd::SharedFD out) { - std::stringstream output_streambuf; - for (const auto& file : fetcher_config.get_cvd_files()) { - output_streambuf << file.first << "\n"; - } - std::string output_string = output_streambuf.str(); - int written = cvd::WriteAll(out, output_string); - if (written < 0) { - LOG(FATAL) << "Could not write file report (" << strerror(out->GetErrno()) - << ")"; - } -} - -} // namespace - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - - FlagForwarder forwarder({kAssemblerBin, kRunnerBin}); - - gflags::ParseCommandLineNonHelpFlags(&argc, &argv, false); - - forwarder.UpdateFlagDefaults(); - - gflags::HandleCommandLineHelpFlags(); - - cvd::SharedFD assembler_stdout, runner_stdin; - cvd::SharedFD::Pipe(&runner_stdin, &assembler_stdout); - - cvd::SharedFD launcher_report, assembler_stdin; - bool should_generate_report = FLAGS_run_file_discovery; - if (should_generate_report) { - cvd::SharedFD::Pipe(&assembler_stdin, &launcher_report); - } - - // SharedFDs are std::move-d in to avoid dangling references. - // Removing the std::move will probably make run_cvd hang as its stdin never closes. - auto assemble_proc = StartAssembler(std::move(assembler_stdin), - std::move(assembler_stdout), - forwarder.ArgvForSubprocess(kAssemblerBin)); - auto run_proc = StartRunner(std::move(runner_stdin), - forwarder.ArgvForSubprocess(kRunnerBin)); - - if (should_generate_report) { - WriteFiles(AvailableFilesReport(), std::move(launcher_report)); - } - - auto assemble_ret = assemble_proc.Wait(); - if (assemble_ret != 0) { - LOG(ERROR) << "assemble_cvd returned " << assemble_ret; - return assemble_ret; - } else { - LOG(INFO) << "assemble_cvd exited successfully."; - } - - auto run_ret = run_proc.Wait(); - if (run_ret != 0) { - LOG(ERROR) << "run_cvd returned " << run_ret; - } else { - LOG(INFO) << "run_cvd exited successfully."; - } - return run_ret; -} diff --git a/host/commands/logcat_receiver/Android.bp b/host/commands/logcat_receiver/Android.bp deleted file mode 100644 index 72438c71..00000000 --- a/host/commands/logcat_receiver/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "logcat_receiver", - srcs: [ - "main.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "liblog", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/logcat_receiver/main.cpp b/host/commands/logcat_receiver/main.cpp deleted file mode 100644 index e9cbad2d..00000000 --- a/host/commands/logcat_receiver/main.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "host/libs/config/cuttlefish_config.h" - -DEFINE_int32( - server_fd, -1, - "File descriptor to an already created vsock server. If negative a new " - "server will be created at the port specified on the config file"); - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - - auto path = config->logcat_path(); - auto logcat_file = - cvd::SharedFD::Open(path.c_str(), O_CREAT | O_APPEND | O_WRONLY, 0666); - CHECK(logcat_file->IsOpen()) - << "Unable to open logcat file: " << logcat_file->StrError(); - - cvd::SharedFD server_fd; - if (FLAGS_server_fd < 0) { - unsigned int port = config->logcat_vsock_port(); - server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - } else { - server_fd = cvd::SharedFD::Dup(FLAGS_server_fd); - close(FLAGS_server_fd); - } - - CHECK(server_fd->IsOpen()) << "Error creating or inheriting logcat server: " - << server_fd->StrError(); - - // Server loop - while (true) { - auto conn = cvd::SharedFD::Accept(*server_fd); - - while (true) { - char buff[1024]; - auto read = conn->Read(buff, sizeof(buff)); - if (read <= 0) { - // Close here to ensure the other side gets reset if it's still - // connected - conn->Close(); - LOG(WARNING) << "Detected close from the other side"; - break; - } - auto written = logcat_file->Write(buff, read); - CHECK(written == read) - << "Error writing to log file: " << logcat_file->StrError() - << ". This is unrecoverable."; - } - } - return 0; -}
\ No newline at end of file diff --git a/host/commands/run_cvd/Android.bp b/host/commands/run_cvd/Android.bp deleted file mode 100644 index a7893fed..00000000 --- a/host/commands/run_cvd/Android.bp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "run_cvd", - srcs: [ - "launch.cc", - "process_monitor.cc", - "main.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - "libnl" - ], - static_libs: [ - "libcuttlefish_host_config", - "libcuttlefish_vm_manager", - "libgflags", - "libxml2", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"], -} diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc deleted file mode 100644 index e4eb858c..00000000 --- a/host/commands/run_cvd/launch.cc +++ /dev/null @@ -1,317 +0,0 @@ -#include "host/commands/run_cvd/launch.h" - -#include <sys/types.h> -#include <sys/stat.h> - -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/size_utils.h" -#include "host/commands/run_cvd/runner_defs.h" -#include "host/commands/run_cvd/pre_launch_initializers.h" -#include "host/libs/vm_manager/crosvm_manager.h" -#include "host/libs/vm_manager/qemu_manager.h" - -using cvd::RunnerExitCodes; -using cvd::MonitorEntry; - -namespace { - -std::string GetAdbConnectorTcpArg(const vsoc::CuttlefishConfig& config) { - return std::string{"127.0.0.1:"} + std::to_string(config.host_port()); -} - -std::string GetAdbConnectorVsockArg(const vsoc::CuttlefishConfig& config) { - return std::string{"vsock:"} - + std::to_string(config.vsock_guest_cid()) - + std::string{":5555"}; -} - -bool AdbModeEnabled(const vsoc::CuttlefishConfig& config, vsoc::AdbMode mode) { - return config.adb_mode().count(mode) > 0; -} - -bool AdbVsockTunnelEnabled(const vsoc::CuttlefishConfig& config) { - return config.vsock_guest_cid() > 2 - && AdbModeEnabled(config, vsoc::AdbMode::VsockTunnel); -} - -bool AdbVsockHalfTunnelEnabled(const vsoc::CuttlefishConfig& config) { - return config.vsock_guest_cid() > 2 - && AdbModeEnabled(config, vsoc::AdbMode::VsockHalfTunnel); -} - -bool AdbTcpConnectorEnabled(const vsoc::CuttlefishConfig& config) { - bool vsock_tunnel = AdbVsockTunnelEnabled(config); - bool vsock_half_tunnel = AdbVsockHalfTunnelEnabled(config); - return config.run_adb_connector() && (vsock_tunnel || vsock_half_tunnel); -} - -bool AdbVsockConnectorEnabled(const vsoc::CuttlefishConfig& config) { - return config.run_adb_connector() - && AdbModeEnabled(config, vsoc::AdbMode::NativeVsock); -} - -bool AdbUsbEnabled(const vsoc::CuttlefishConfig& config) { - return AdbModeEnabled(config, vsoc::AdbMode::Usb); -} - -cvd::OnSocketReadyCb GetOnSubprocessExitCallback( - const vsoc::CuttlefishConfig& config) { - if (config.restart_subprocesses()) { - return cvd::ProcessMonitor::RestartOnExitCb; - } else { - return cvd::ProcessMonitor::DoNotMonitorCb; - } -} -} // namespace - -bool LogcatReceiverEnabled(const vsoc::CuttlefishConfig& config) { - return config.logcat_mode() == cvd::kLogcatVsockMode; -} - -std::vector<cvd::SharedFD> LaunchKernelLogMonitor( - const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor, - unsigned int number_of_event_pipes) { - auto log_name = config.kernel_log_pipe_name(); - if (mkfifo(log_name.c_str(), 0600) != 0) { - LOG(ERROR) << "Unable to create named pipe at " << log_name << ": " - << strerror(errno); - return {}; - } - - cvd::SharedFD pipe; - // Open the pipe here (from the launcher) to ensure the pipe is not deleted - // due to the usage counters in the kernel reaching zero. If this is not done - // and the kernel_log_monitor crashes for some reason the VMM may get SIGPIPE. - pipe = cvd::SharedFD::Open(log_name.c_str(), O_RDWR); - cvd::Command command(config.kernel_log_monitor_binary()); - command.AddParameter("-log_pipe_fd=", pipe); - - std::vector<cvd::SharedFD> ret; - - if (number_of_event_pipes > 0) { - auto param_builder = command.GetParameterBuilder(); - param_builder << "-subscriber_fds="; - for (unsigned int i = 0; i < number_of_event_pipes; ++i) { - cvd::SharedFD event_pipe_write_end, event_pipe_read_end; - if (!cvd::SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) { - LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno); - std::exit(RunnerExitCodes::kPipeIOError); - } - if (i > 0) { - param_builder << ","; - } - param_builder << event_pipe_write_end; - ret.push_back(event_pipe_read_end); - } - param_builder.Build(); - } - - process_monitor->StartSubprocess(std::move(command), - GetOnSubprocessExitCallback(config)); - - return ret; -} - -void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor) { - if (!LogcatReceiverEnabled(config)) { - return; - } - auto port = config.logcat_vsock_port(); - auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - if (!socket->IsOpen()) { - LOG(ERROR) << "Unable to create logcat server socket: " - << socket->StrError(); - std::exit(RunnerExitCodes::kLogcatServerError); - } - cvd::Command cmd(config.logcat_receiver_binary()); - cmd.AddParameter("-server_fd=", socket); - process_monitor->StartSubprocess(std::move(cmd), - GetOnSubprocessExitCallback(config)); -} - -void LaunchConfigServer(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor) { - auto port = config.config_server_port(); - auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - if (!socket->IsOpen()) { - LOG(ERROR) << "Unable to create configuration server socket: " - << socket->StrError(); - std::exit(RunnerExitCodes::kConfigServerError); - } - cvd::Command cmd(config.config_server_binary()); - cmd.AddParameter("-server_fd=", socket); - process_monitor->StartSubprocess(std::move(cmd), - GetOnSubprocessExitCallback(config)); -} - -void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor) { - if (!config.enable_tombstone_receiver()) { - return; - } - - std::string tombstoneDir = config.PerInstancePath("tombstones"); - if (!cvd::DirectoryExists(tombstoneDir.c_str())) { - LOG(INFO) << "Setting up " << tombstoneDir; - if (mkdir(tombstoneDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < - 0) { - LOG(ERROR) << "Failed to create tombstone directory: " << tombstoneDir - << ". Error: " << errno; - exit(RunnerExitCodes::kTombstoneDirCreationError); - } - } - - auto port = config.tombstone_receiver_port(); - auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - if (!socket->IsOpen()) { - LOG(ERROR) << "Unable to create tombstone server socket: " - << socket->StrError(); - std::exit(RunnerExitCodes::kTombstoneServerError); - } - cvd::Command cmd(config.tombstone_receiver_binary()); - cmd.AddParameter("-server_fd=", socket); - cmd.AddParameter("-tombstone_dir=", tombstoneDir); - - process_monitor->StartSubprocess(std::move(cmd), - GetOnSubprocessExitCallback(config)); -} - -void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor) { - if (!AdbUsbEnabled(config)) { - return; - } - auto socket_name = config.usb_v1_socket_name(); - auto usb_v1_server = cvd::SharedFD::SocketLocalServer( - socket_name.c_str(), false, SOCK_STREAM, 0666); - if (!usb_v1_server->IsOpen()) { - LOG(ERROR) << "Unable to create USB v1 server socket: " - << usb_v1_server->StrError(); - std::exit(cvd::RunnerExitCodes::kUsbV1SocketError); - } - cvd::Command usb_server(config.virtual_usb_manager_binary()); - usb_server.AddParameter("-usb_v1_fd=", usb_v1_server); - process_monitor->StartSubprocess(std::move(usb_server), - GetOnSubprocessExitCallback(config)); -} - -cvd::SharedFD CreateUnixVncInputServer(const std::string& path) { - auto server = cvd::SharedFD::SocketLocalServer(path.c_str(), false, SOCK_STREAM, 0666); - if (!server->IsOpen()) { - LOG(ERROR) << "Unable to create unix input server: " - << server->StrError(); - return cvd::SharedFD(); - } - return server; -} - -cvd::SharedFD CreateVsockVncInputServer(int port) { - auto server = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - if (!server->IsOpen()) { - LOG(ERROR) << "Unable to create vsock input server: " - << server->StrError(); - return cvd::SharedFD(); - } - return server; -} - -bool LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor, - std::function<bool(MonitorEntry*)> callback) { - if (config.enable_vnc_server()) { - // Launch the vnc server, don't wait for it to complete - auto port_options = "-port=" + std::to_string(config.vnc_server_port()); - cvd::Command vnc_server(config.vnc_server_binary()); - vnc_server.AddParameter(port_options); - if (config.vm_manager() == vm_manager::QemuManager::name()) { - vnc_server.AddParameter("-write_virtio_input"); - } - // When the ivserver is not enabled, the vnc touch_server needs to serve - // on sockets and send input events to whoever connects to it (the VMM). - auto touch_server = - config.vm_manager() == vm_manager::CrosvmManager::name() - ? CreateUnixVncInputServer(config.touch_socket_path()) - : CreateVsockVncInputServer(config.touch_socket_port()); - if (!touch_server->IsOpen()) { - return false; - } - vnc_server.AddParameter("-touch_fd=", touch_server); - - auto keyboard_server = - config.vm_manager() == vm_manager::CrosvmManager::name() - ? CreateUnixVncInputServer(config.keyboard_socket_path()) - : CreateVsockVncInputServer(config.keyboard_socket_port()); - if (!keyboard_server->IsOpen()) { - return false; - } - vnc_server.AddParameter("-keyboard_fd=", keyboard_server); - // TODO(b/128852363): This should be handled through the wayland mock - // instead. - // Additionally it receives the frame updates from a virtual socket - // instead - auto frames_server = - cvd::SharedFD::VsockServer(config.frames_vsock_port(), SOCK_STREAM); - if (!frames_server->IsOpen()) { - return false; - } - vnc_server.AddParameter("-frame_server_fd=", frames_server); - process_monitor->StartSubprocess(std::move(vnc_server), callback); - return true; - } - return false; -} - -void LaunchAdbConnectorIfEnabled(cvd::ProcessMonitor* process_monitor, - const vsoc::CuttlefishConfig& config, - cvd::SharedFD adbd_events_pipe) { - cvd::Command adb_connector(config.adb_connector_binary()); - adb_connector.AddParameter("-adbd_events_fd=", adbd_events_pipe); - std::set<std::string> addresses; - - if (AdbTcpConnectorEnabled(config)) { - addresses.insert(GetAdbConnectorTcpArg(config)); - } - if (AdbVsockConnectorEnabled(config)) { - addresses.insert(GetAdbConnectorVsockArg(config)); - } - - if (addresses.size() > 0) { - std::string address_arg = "--addresses="; - for (auto& arg : addresses) { - address_arg += arg + ","; - } - address_arg.pop_back(); - adb_connector.AddParameter(address_arg); - process_monitor->StartSubprocess(std::move(adb_connector), - GetOnSubprocessExitCallback(config)); - } -} - -void LaunchSocketVsockProxyIfEnabled(cvd::ProcessMonitor* process_monitor, - const vsoc::CuttlefishConfig& config) { - if (AdbVsockTunnelEnabled(config)) { - cvd::Command adb_tunnel(config.socket_vsock_proxy_binary()); - adb_tunnel.AddParameter("--vsock_port=6520"); - adb_tunnel.AddParameter( - std::string{"--tcp_port="} + std::to_string(config.host_port())); - adb_tunnel.AddParameter(std::string{"--vsock_guest_cid="} + - std::to_string(config.vsock_guest_cid())); - process_monitor->StartSubprocess(std::move(adb_tunnel), - GetOnSubprocessExitCallback(config)); - } - if (AdbVsockHalfTunnelEnabled(config)) { - cvd::Command adb_tunnel(config.socket_vsock_proxy_binary()); - adb_tunnel.AddParameter("--vsock_port=5555"); - adb_tunnel.AddParameter( - std::string{"--tcp_port="} + std::to_string(config.host_port())); - adb_tunnel.AddParameter(std::string{"--vsock_guest_cid="} + - std::to_string(config.vsock_guest_cid())); - process_monitor->StartSubprocess(std::move(adb_tunnel), - GetOnSubprocessExitCallback(config)); - } -} diff --git a/host/commands/run_cvd/launch.h b/host/commands/run_cvd/launch.h deleted file mode 100644 index 4db6e127..00000000 --- a/host/commands/run_cvd/launch.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include <functional> - -#include "common/libs/utils/subprocess.h" -#include "host/commands/run_cvd/process_monitor.h" -#include "host/libs/config/cuttlefish_config.h" - -std::vector <cvd::SharedFD> LaunchKernelLogMonitor( - const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor, - unsigned int number_of_event_pipes); -void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor); -void LaunchConfigServer(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor); -void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor); -bool LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor, - std::function<bool(cvd::MonitorEntry*)> callback); -void LaunchAdbConnectorIfEnabled(cvd::ProcessMonitor* process_monitor, - const vsoc::CuttlefishConfig& config, - cvd::SharedFD adbd_events_pipe); -void LaunchSocketVsockProxyIfEnabled(cvd::ProcessMonitor* process_monitor, - const vsoc::CuttlefishConfig& config); -void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config, - cvd::ProcessMonitor* process_monitor); diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc deleted file mode 100644 index 486a0db4..00000000 --- a/host/commands/run_cvd/main.cc +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> - -#include <algorithm> -#include <functional> -#include <iostream> -#include <fstream> -#include <iomanip> -#include <memory> -#include <sstream> -#include <string> -#include <thread> -#include <vector> - -#include <android-base/strings.h> -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_buf.h" -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "common/libs/utils/environment.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" -#include "common/libs/utils/size_utils.h" -#include "host/commands/run_cvd/launch.h" -#include "host/commands/run_cvd/runner_defs.h" -#include "host/commands/run_cvd/process_monitor.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/commands/kernel_log_monitor/kernel_log_server.h" -#include <host/libs/vm_manager/crosvm_manager.h> -#include "host/libs/vm_manager/vm_manager.h" -#include "host/libs/vm_manager/qemu_manager.h" - -using vsoc::GetPerInstanceDefault; -using cvd::RunnerExitCodes; - -namespace { - -cvd::OnSocketReadyCb GetOnSubprocessExitCallback( - const vsoc::CuttlefishConfig& config) { - if (config.restart_subprocesses()) { - return cvd::ProcessMonitor::RestartOnExitCb; - } else { - return cvd::ProcessMonitor::DoNotMonitorCb; - } -} - -// Maintains the state of the boot process, once a final state is reached -// (success or failure) it sends the appropriate exit code to the foreground -// launcher process -class CvdBootStateMachine { - public: - CvdBootStateMachine(cvd::SharedFD fg_launcher_pipe) - : fg_launcher_pipe_(fg_launcher_pipe), state_(kBootStarted) {} - - // Returns true if the machine is left in a final state - bool OnBootEvtReceived(cvd::SharedFD boot_events_pipe) { - monitor::BootEvent evt; - auto bytes_read = boot_events_pipe->Read(&evt, sizeof(evt)); - if (bytes_read != sizeof(evt)) { - LOG(ERROR) << "Fail to read a complete event, read " << bytes_read - << " bytes only instead of the expected " << sizeof(evt); - state_ |= kGuestBootFailed; - } else if (evt == monitor::BootEvent::BootCompleted) { - LOG(INFO) << "Virtual device booted successfully"; - state_ |= kGuestBootCompleted; - } else if (evt == monitor::BootEvent::BootFailed) { - LOG(ERROR) << "Virtual device failed to boot"; - state_ |= kGuestBootFailed; - } // Ignore the other signals - - return MaybeWriteToForegroundLauncher(); - } - - bool BootCompleted() const { - return state_ & kGuestBootCompleted; - } - - bool BootFailed() const { - return state_ & kGuestBootFailed; - } - - private: - void SendExitCode(cvd::RunnerExitCodes exit_code) { - fg_launcher_pipe_->Write(&exit_code, sizeof(exit_code)); - // The foreground process will exit after receiving the exit code, if we try - // to write again we'll get a SIGPIPE - fg_launcher_pipe_->Close(); - } - bool MaybeWriteToForegroundLauncher() { - if (fg_launcher_pipe_->IsOpen()) { - if (BootCompleted()) { - SendExitCode(cvd::RunnerExitCodes::kSuccess); - } else if (state_ & kGuestBootFailed) { - SendExitCode(cvd::RunnerExitCodes::kVirtualDeviceBootFailed); - } else { - // No final state was reached - return false; - } - } - // Either we sent the code before or just sent it, in any case the state is - // final - return true; - } - - cvd::SharedFD fg_launcher_pipe_; - int state_; - static const int kBootStarted = 0; - static const int kGuestBootCompleted = 1 << 0; - static const int kGuestBootFailed = 1 << 1; -}; - -// Abuse the process monitor to make it call us back when boot events are ready -void SetUpHandlingOfBootEvents( - cvd::ProcessMonitor* process_monitor, cvd::SharedFD boot_events_pipe, - std::shared_ptr<CvdBootStateMachine> state_machine) { - process_monitor->MonitorExistingSubprocess( - // A dummy command, so logs are desciptive - cvd::Command("boot_events_listener"), - // A dummy subprocess, with the boot events pipe as control socket - cvd::Subprocess(-1, boot_events_pipe), - [boot_events_pipe, state_machine](cvd::MonitorEntry*) { - auto sent_code = state_machine->OnBootEvtReceived(boot_events_pipe); - return !sent_code; - }); -} - -bool WriteCuttlefishEnvironment(const vsoc::CuttlefishConfig& config) { - auto env = cvd::SharedFD::Open(config.cuttlefish_env_path().c_str(), - O_CREAT | O_RDWR, 0755); - if (!env->IsOpen()) { - LOG(ERROR) << "Unable to create cuttlefish.env file"; - return false; - } - std::string config_env = "export CUTTLEFISH_PER_INSTANCE_PATH=\"" + - config.PerInstancePath(".") + "\"\n"; - config_env += "export ANDROID_SERIAL="; - if (config.adb_mode().count(vsoc::AdbMode::Usb) > 0) { - config_env += config.serial_number(); - } else { - config_env += config.adb_ip_and_port(); - } - config_env += "\n"; - env->Write(config_env.c_str(), config_env.size()); - return true; -} - -// Forks and returns the write end of a pipe to the child process. The parent -// process waits for boot events to come through the pipe and exits accordingly. -cvd::SharedFD DaemonizeLauncher(const vsoc::CuttlefishConfig& config) { - cvd::SharedFD read_end, write_end; - if (!cvd::SharedFD::Pipe(&read_end, &write_end)) { - LOG(ERROR) << "Unable to create pipe"; - return cvd::SharedFD(); // a closed FD - } - auto pid = fork(); - if (pid) { - // Explicitly close here, otherwise we may end up reading forever if the - // child process dies. - write_end->Close(); - RunnerExitCodes exit_code; - auto bytes_read = read_end->Read(&exit_code, sizeof(exit_code)); - if (bytes_read != sizeof(exit_code)) { - LOG(ERROR) << "Failed to read a complete exit code, read " << bytes_read - << " bytes only instead of the expected " << sizeof(exit_code); - exit_code = RunnerExitCodes::kPipeIOError; - } else if (exit_code == RunnerExitCodes::kSuccess) { - LOG(INFO) << "Virtual device booted successfully"; - } else if (exit_code == RunnerExitCodes::kVirtualDeviceBootFailed) { - LOG(ERROR) << "Virtual device failed to boot"; - } else { - LOG(ERROR) << "Unexpected exit code: " << exit_code; - } - if (exit_code == RunnerExitCodes::kSuccess) { - LOG(INFO) << vsoc::kBootCompletedMessage; - } else { - LOG(INFO) << vsoc::kBootFailedMessage; - } - std::exit(exit_code); - } else { - // The child returns the write end of the pipe - if (daemon(/*nochdir*/ 1, /*noclose*/ 1) != 0) { - LOG(ERROR) << "Failed to daemonize child process: " << strerror(errno); - std::exit(RunnerExitCodes::kDaemonizationError); - } - // Redirect standard I/O - auto log_path = config.launcher_log_path(); - auto log = - cvd::SharedFD::Open(log_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (!log->IsOpen()) { - LOG(ERROR) << "Failed to create launcher log file: " << log->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - auto dev_null = cvd::SharedFD::Open("/dev/null", O_RDONLY); - if (!dev_null->IsOpen()) { - LOG(ERROR) << "Failed to open /dev/null: " << dev_null->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - if (dev_null->UNMANAGED_Dup2(0) < 0) { - LOG(ERROR) << "Failed dup2 stdin: " << dev_null->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - if (log->UNMANAGED_Dup2(1) < 0) { - LOG(ERROR) << "Failed dup2 stdout: " << log->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - if (log->UNMANAGED_Dup2(2) < 0) { - LOG(ERROR) << "Failed dup2 seterr: " << log->StrError(); - std::exit(RunnerExitCodes::kDaemonizationError); - } - - read_end->Close(); - return write_end; - } -} - -void ServerLoop(cvd::SharedFD server, - cvd::ProcessMonitor* process_monitor) { - while (true) { - // TODO: use select to handle simultaneous connections. - auto client = cvd::SharedFD::Accept(*server); - cvd::LauncherAction action; - while (client->IsOpen() && client->Read(&action, sizeof(action)) > 0) { - switch (action) { - case cvd::LauncherAction::kStop: - if (process_monitor->StopMonitoredProcesses()) { - auto response = cvd::LauncherResponse::kSuccess; - client->Write(&response, sizeof(response)); - std::exit(0); - } else { - auto response = cvd::LauncherResponse::kError; - client->Write(&response, sizeof(response)); - } - break; - case cvd::LauncherAction::kStatus: { - // TODO(schuffelen): Return more information on a side channel - auto response = cvd::LauncherResponse::kSuccess; - client->Write(&response, sizeof(response)); - break; - } - default: - LOG(ERROR) << "Unrecognized launcher action: " - << static_cast<char>(action); - auto response = cvd::LauncherResponse::kError; - client->Write(&response, sizeof(response)); - } - } - } -} - -std::string GetConfigFilePath(const vsoc::CuttlefishConfig& config) { - return config.PerInstancePath("cuttlefish_config.json"); -} - -template<typename T> -void AppendVector(std::vector<T>* destination, const std::vector<T>& source) { - destination->insert(destination->end(), source.begin(), source.end()); -} - -template<typename S, typename T> -static std::string concat(const S& s, const T& t) { - std::ostringstream os; - os << s << t; - return os.str(); -} - -std::vector<std::string> KernelCommandLineFromConfig(const vsoc::CuttlefishConfig& config) { - std::vector<std::string> kernel_cmdline; - - AppendVector(&kernel_cmdline, config.boot_image_kernel_cmdline()); - AppendVector(&kernel_cmdline, - vm_manager::VmManager::ConfigureGpuMode(config.vm_manager(), config.gpu_mode())); - AppendVector(&kernel_cmdline, vm_manager::VmManager::ConfigureBootDevices(config.vm_manager())); - - kernel_cmdline.push_back(concat("androidboot.serialno=", config.serial_number())); - kernel_cmdline.push_back(concat("androidboot.lcd_density=", config.dpi())); - if (config.logcat_mode() == cvd::kLogcatVsockMode) { - kernel_cmdline.push_back(concat("androidboot.vsock_logcat_port=", config.logcat_vsock_port())); - } - if (config.enable_vnc_server()) { - kernel_cmdline.push_back(concat("androidboot.vsock_frames_port=", config.frames_vsock_port())); - } - if (config.enable_tombstone_receiver()) { - kernel_cmdline.push_back("androidboot.tombstone_transmit=1"); - kernel_cmdline.push_back(concat( - "androidboot.vsock_tombstone_port=", - config.tombstone_receiver_port())); - // TODO (b/128842613) populate a cid flag to read the host CID during - // runtime - } else { - kernel_cmdline.push_back("androidboot.tombstone_transmit=0"); - } - kernel_cmdline.push_back(concat( - "androidboot.cuttlefish_config_server_port=", config.config_server_port())); - kernel_cmdline.push_back(concat( - "androidboot.setupwizard_mode=", config.setupwizard_mode())); - if (!config.use_bootloader()) { - std::string slot_suffix; - if (config.boot_slot().empty()) { - slot_suffix = "_a"; - } else { - slot_suffix = "_" + config.boot_slot(); - } - kernel_cmdline.push_back(concat("androidboot.slot_suffix=", slot_suffix)); - } - if (config.vm_manager() == vm_manager::QemuManager::name()) { - kernel_cmdline.push_back(concat("androidboot.vsock_touch_port=", config.touch_socket_port())); - kernel_cmdline.push_back(concat( - "androidboot.vsock_keyboard_port=", config.keyboard_socket_port())); - } - kernel_cmdline.push_back(concat("loop.max_part=", config.loop_max_part())); - if (config.guest_enforce_security()) { - kernel_cmdline.push_back("enforcing=1"); - } else { - kernel_cmdline.push_back("enforcing=0"); - kernel_cmdline.push_back("androidboot.selinux=permissive"); - } - if (config.guest_audit_security()) { - kernel_cmdline.push_back("audit=1"); - } else { - kernel_cmdline.push_back("audit=0"); - } - - AppendVector(&kernel_cmdline, config.extra_kernel_cmdline()); - - return kernel_cmdline; -} - -} // namespace - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, false); - - if (isatty(0)) { - LOG(FATAL) << "stdin was a tty, expected to be passed the output of a previous stage. " - << "Did you mean to run launch_cvd?"; - return cvd::RunnerExitCodes::kInvalidHostConfiguration; - } else { - int error_num = errno; - if (error_num == EBADF) { - LOG(FATAL) << "stdin was not a valid file descriptor, expected to be passed the output " - << "of assemble_cvd. Did you mean to run launch_cvd?"; - return cvd::RunnerExitCodes::kInvalidHostConfiguration; - } - } - - std::string input_files_str; - { - auto input_fd = cvd::SharedFD::Dup(0); - auto bytes_read = cvd::ReadAll(input_fd, &input_files_str); - if (bytes_read < 0) { - LOG(FATAL) << "Failed to read input files. Error was \"" << input_fd->StrError() << "\""; - } - } - std::vector<std::string> input_files = android::base::Split(input_files_str, "\n"); - bool found_config = false; - for (const auto& file : input_files) { - if (file.find("cuttlefish_config.json") != std::string::npos) { - found_config = true; - setenv(vsoc::kCuttlefishConfigEnvVarName, file.c_str(), /* overwrite */ false); - } - } - if (!found_config) { - return RunnerExitCodes::kCuttlefishConfigurationInitError; - } - - auto config = vsoc::CuttlefishConfig::Get(); - - // Change working directory to the instance directory as early as possible to - // ensure all host processes have the same working dir. This helps stop_cvd - // find the running processes when it can't establish a communication with the - // launcher. - auto chdir_ret = chdir(config->instance_dir().c_str()); - if (chdir_ret != 0) { - auto error = errno; - LOG(ERROR) << "Unable to change dir into instance directory (" - << config->instance_dir() << "): " << strerror(error); - return RunnerExitCodes::kInstanceDirCreationError; - } - - auto vm_manager = vm_manager::VmManager::Get(config->vm_manager(), config); - - // Check host configuration - std::vector<std::string> config_commands; - if (!vm_manager->ValidateHostConfiguration(&config_commands)) { - LOG(ERROR) << "Validation of user configuration failed"; - std::cout << "Execute the following to correctly configure:" << std::endl; - for (auto& command : config_commands) { - std::cout << " " << command << std::endl; - } - std::cout << "You may need to logout for the changes to take effect" - << std::endl; - return RunnerExitCodes::kInvalidHostConfiguration; - } - - if (!WriteCuttlefishEnvironment(*config)) { - LOG(ERROR) << "Unable to write cuttlefish environment file"; - } - - LOG(INFO) << "The following files contain useful debugging information:"; - if (config->run_as_daemon()) { - LOG(INFO) << " Launcher log: " << config->launcher_log_path(); - } - LOG(INFO) << " Android's logcat output: " << config->logcat_path(); - LOG(INFO) << " Kernel log: " << config->PerInstancePath("kernel.log"); - LOG(INFO) << " Instance configuration: " << GetConfigFilePath(*config); - LOG(INFO) << " Instance environment: " << config->cuttlefish_env_path(); - LOG(INFO) << "To access the console run: socat file:$(tty),raw,echo=0 " - << config->console_path(); - - auto launcher_monitor_path = config->launcher_monitor_socket_path(); - auto launcher_monitor_socket = cvd::SharedFD::SocketLocalServer( - launcher_monitor_path.c_str(), false, SOCK_STREAM, 0666); - if (!launcher_monitor_socket->IsOpen()) { - LOG(ERROR) << "Error when opening launcher server: " - << launcher_monitor_socket->StrError(); - return cvd::RunnerExitCodes::kMonitorCreationFailed; - } - cvd::SharedFD foreground_launcher_pipe; - if (config->run_as_daemon()) { - foreground_launcher_pipe = DaemonizeLauncher(*config); - if (!foreground_launcher_pipe->IsOpen()) { - return RunnerExitCodes::kDaemonizationError; - } - } else { - // Make sure the launcher runs in its own process group even when running in - // foreground - if (getsid(0) != getpid()) { - int retval = setpgid(0, 0); - if (retval) { - LOG(ERROR) << "Failed to create new process group: " << strerror(errno); - std::exit(RunnerExitCodes::kProcessGroupError); - } - } - } - - auto boot_state_machine = - std::make_shared<CvdBootStateMachine>(foreground_launcher_pipe); - - // Monitor and restart host processes supporting the CVD - cvd::ProcessMonitor process_monitor; - - auto event_pipes = - LaunchKernelLogMonitor(*config, &process_monitor, 2); - cvd::SharedFD boot_events_pipe = event_pipes[0]; - cvd::SharedFD adbd_events_pipe = event_pipes[1]; - event_pipes.clear(); - - SetUpHandlingOfBootEvents(&process_monitor, boot_events_pipe, - boot_state_machine); - - LaunchLogcatReceiverIfEnabled(*config, &process_monitor); - - LaunchConfigServer(*config, &process_monitor); - - LaunchTombstoneReceiverIfEnabled(*config, &process_monitor); - - LaunchUsbServerIfEnabled(*config, &process_monitor); - - // The vnc server needs to be launched after the ivserver because it connects - // to it when using qemu. It needs to launch before the VMM because it serves - // on several sockets (input devices, vsock frame server) when using crosvm. - auto frontend_enabled = LaunchVNCServerIfEnabled( - *config, &process_monitor, GetOnSubprocessExitCallback(*config)); - - // Start the guest VM - vm_manager->WithFrontend(frontend_enabled); - auto kernel_args = KernelCommandLineFromConfig(*config); - vm_manager->WithKernelCommandLine(android::base::Join(kernel_args, " ")); - auto vmm_commands = vm_manager->StartCommands(); - for (auto& vmm_cmd: vmm_commands) { - process_monitor.StartSubprocess(std::move(vmm_cmd), - GetOnSubprocessExitCallback(*config)); - } - - // Start other host processes - LaunchSocketVsockProxyIfEnabled(&process_monitor, *config); - LaunchAdbConnectorIfEnabled(&process_monitor, *config, adbd_events_pipe); - - ServerLoop(launcher_monitor_socket, &process_monitor); // Should not return - LOG(ERROR) << "The server loop returned, it should never happen!!"; - return cvd::RunnerExitCodes::kServerError; -} diff --git a/host/commands/run_cvd/pre_launch_initializers.h b/host/commands/run_cvd/pre_launch_initializers.h deleted file mode 100644 index 79f6eedc..00000000 --- a/host/commands/run_cvd/pre_launch_initializers.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <memory> - -#include <host/libs/config/cuttlefish_config.h> - -// Handles initialization of regions that require it strictly before the virtual -// machine is started. -// To add initializers for more regions declare here, implement in its own -// source file and call from PreLaunchInitializers::Initialize(). -void InitializeScreenRegion(const vsoc::CuttlefishConfig& config); - -class PreLaunchInitializers { - public: - static void Initialize(const vsoc::CuttlefishConfig& config) { - InitializeScreenRegion(config); - } -}; diff --git a/host/commands/run_cvd/process_monitor.cc b/host/commands/run_cvd/process_monitor.cc deleted file mode 100644 index 82433060..00000000 --- a/host/commands/run_cvd/process_monitor.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sys/types.h> -#include <sys/wait.h> - -#include <assert.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> - -#include <map> - -#include <glog/logging.h> - -#include "common/libs/fs/shared_select.h" -#include "host/commands/run_cvd/process_monitor.h" - -namespace cvd { - -namespace { - -void NotifyThread(SharedFD fd) { - // The restarter thread is (likely) blocked on a call to select, to make it - // wake up and do some work we write something (anything, the content is not - // important) into the main side of the socket pair so that the call to select - // returns and the notification fd (restarter side of the socket pair) is - // marked as ready to read. - char buffer = 'a'; - fd->Write(&buffer, sizeof(buffer)); -} - -void ConsumeNotifications(SharedFD fd) { - // Once the starter thread is waken up due to a notification, the calls to - // select will continue to return immediately unless we read what was written - // on the main side of the socket pair. More than one notification can - // accumulate before the restarter thread consumes them, so we attempt to read - // more than it's written to consume them all at once. In the unlikely case of - // more than 8 notifications acummulating we simply read the first 8 and have - // another iteration on the restarter thread loop. - char buffer[8]; - fd->Read(buffer, sizeof(buffer)); -} - -} // namespace - -ProcessMonitor::ProcessMonitor() { - if (!SharedFD::SocketPair(AF_LOCAL, SOCK_STREAM, 0, &thread_comm_main_, - &thread_comm_monitor_)) { - LOG(ERROR) << "Unable to create restarter communication socket pair: " - << strerror(errno); - return; - } - monitor_thread_ = std::thread([this]() { MonitorRoutine(); }); -} - -void ProcessMonitor::StartSubprocess(Command cmd, OnSocketReadyCb callback) { - auto proc = cmd.StartInGroup(true); - if (!proc.Started()) { - LOG(ERROR) << "Failed to start process"; - return; - } - MonitorExistingSubprocess(std::move(cmd), std::move(proc), callback); -} - -void ProcessMonitor::MonitorExistingSubprocess(Command cmd, Subprocess proc, - OnSocketReadyCb callback) { - { - std::lock_guard<std::mutex> lock(processes_mutex_); - monitored_processes_.push_back(MonitorEntry()); - auto& entry = monitored_processes_.back(); - entry.cmd.reset(new Command(std::move(cmd))); - entry.proc.reset(new Subprocess(std::move(proc))); - entry.on_control_socket_ready_cb = callback; - } - // Wake the restarter thread up so that it starts monitoring this subprocess - // Do this after releasing the lock so that the restarter thread is free to - // begin work as soon as select returns. - NotifyThread(thread_comm_main_); -} - -bool ProcessMonitor::StopMonitoredProcesses() { - // Because the mutex is held while this function executes, the restarter - // thread is kept blocked and by the time it resumes execution there are no - // more processes to monitor - std::lock_guard<std::mutex> lock(processes_mutex_); - bool result = true; - // Processes were started in the order they appear in the vector, stop them in - // reverse order for symmetry. - for (auto entry_it = monitored_processes_.rbegin(); - entry_it != monitored_processes_.rend(); ++entry_it) { - auto& entry = *entry_it; - result = result && entry.proc->Stop(); - } - // Wait for all processes to actually exit. - for (auto& entry : monitored_processes_) { - // Most processes are being killed by signals, calling Wait(void) would be - // too verbose on the logs. - int wstatus; - auto ret = entry.proc->Wait(&wstatus, 0); - if (ret < 0) { - LOG(WARNING) << "Failed to wait for process " - << entry.cmd->GetShortName(); - } - } - // Clear the list to ensure they are not started again - monitored_processes_.clear(); - return result; -} - -bool ProcessMonitor::RestartOnExitCb(MonitorEntry* entry) { - // Make sure the process actually exited - char buffer[16]; - auto bytes_read = entry->proc->control_socket()->Read(buffer, sizeof(buffer)); - if (bytes_read > 0) { - LOG(WARNING) << "Subprocess " << entry->cmd->GetShortName() << " wrote " - << bytes_read - << " bytes on the control socket, this is unexpected"; - // The process may not have exited, continue monitoring without restarting - return true; - } - - LOG(INFO) << "Detected exit of monitored subprocess"; - // Make sure the subprocess isn't left in a zombie state, and that the - // pid is logged - int wstatus; - auto wait_ret = TEMP_FAILURE_RETRY(entry->proc->Wait(&wstatus, 0)); - // None of the error conditions specified on waitpid(2) apply - assert(wait_ret > 0); - if (WIFEXITED(wstatus)) { - LOG(INFO) << "Subprocess " << entry->cmd->GetShortName() << " (" << wait_ret - << ") has exited with exit code " << WEXITSTATUS(wstatus); - } else if (WIFSIGNALED(wstatus)) { - LOG(ERROR) << "Subprocess " << entry->cmd->GetShortName() << " (" - << wait_ret - << ") was interrupted by a signal: " << WTERMSIG(wstatus); - } else { - LOG(INFO) << "subprocess " << entry->cmd->GetShortName() << " (" << wait_ret - << ") has exited for unknown reasons"; - } - entry->proc.reset(new Subprocess(entry->cmd->Start(true))); - return true; -} - -bool ProcessMonitor::DoNotMonitorCb(MonitorEntry*) { return false; } - -void ProcessMonitor::MonitorRoutine() { - LOG(INFO) << "Started monitoring subprocesses"; - do { - SharedFDSet read_set; - read_set.Set(thread_comm_monitor_); - { - std::lock_guard<std::mutex> lock(processes_mutex_); - for (auto& monitored_process : monitored_processes_) { - auto control_socket = monitored_process.proc->control_socket(); - if (!control_socket->IsOpen()) { - LOG(ERROR) << "The control socket for " - << monitored_process.cmd->GetShortName() - << " is closed, it's effectively NOT being monitored"; - } - read_set.Set(control_socket); - } - } - // We can't call select while holding the lock as it would lead to a - // deadlock (restarter thread waiting for notifications from main thread, - // main thread waiting for the lock) - int num_fds = cvd::Select(&read_set, nullptr, nullptr, nullptr); - if (num_fds < 0) { - LOG(ERROR) << "Select call returned error on restarter thread: " - << strerror(errno); - } - if (num_fds > 0) { - // Try the communication fd, it's the most likely to be set - if (read_set.IsSet(thread_comm_monitor_)) { - --num_fds; - ConsumeNotifications(thread_comm_monitor_); - } - } - { - std::lock_guard<std::mutex> lock(processes_mutex_); - // Keep track of the number of file descriptors ready for read, chances - // are we don't need to go over the entire list of subprocesses - auto it = monitored_processes_.begin(); - while (it != monitored_processes_.end()) { - auto control_socket = it->proc->control_socket(); - bool keep_monitoring = true; - if (read_set.IsSet(control_socket)) { - --num_fds; - keep_monitoring = it->on_control_socket_ready_cb(&(*it)); - } - if (keep_monitoring) { - ++it; - } else { - it = monitored_processes_.erase(it); - } - } - } - assert(num_fds == 0); - } while (true); -} - -} // namespace cvd diff --git a/host/commands/run_cvd/process_monitor.h b/host/commands/run_cvd/process_monitor.h deleted file mode 100644 index 5683c61b..00000000 --- a/host/commands/run_cvd/process_monitor.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> -#include <mutex> -#include <thread> -#include <vector> - -#include <common/libs/utils/subprocess.h> - -namespace cvd { - -struct MonitorEntry; -using OnSocketReadyCb = std::function<bool(MonitorEntry*)>; - -struct MonitorEntry { - std::unique_ptr<Command> cmd; - std::unique_ptr<Subprocess> proc; - OnSocketReadyCb on_control_socket_ready_cb; -}; - -// Keeps track of launched subprocesses, restarts them if they unexpectedly exit -class ProcessMonitor { - public: - ProcessMonitor(); - // Starts a managed subprocess with a controlling socket. - // The on_control_socket_ready_cb callback will be called when data is ready - // to be read from the socket or the subprocess has ended. No member functions - // of the process monitor object should be called from the callback as it may - // lead to a deadlock. If the callback returns false the subprocess will no - // longer be monitored. - void StartSubprocess(Command cmd, OnSocketReadyCb on_control_socket_ready_cb); - // Monitors an already started subprocess - void MonitorExistingSubprocess(Command cmd, Subprocess sub_process, - OnSocketReadyCb on_control_socket_ready_cb); - // Stops all monitored subprocesses. - bool StopMonitoredProcesses(); - static bool RestartOnExitCb(MonitorEntry* entry); - static bool DoNotMonitorCb(MonitorEntry* entry); - - private: - void MonitorRoutine(); - - std::vector<MonitorEntry> monitored_processes_; - // Used for communication with the restarter thread - cvd::SharedFD thread_comm_main_, thread_comm_monitor_; - std::thread monitor_thread_; - // Protects access to the monitored_processes_ - std::mutex processes_mutex_; -}; -} // namespace cvd diff --git a/host/commands/run_cvd/runner_defs.h b/host/commands/run_cvd/runner_defs.h deleted file mode 100644 index 1486b119..00000000 --- a/host/commands/run_cvd/runner_defs.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -namespace cvd { - -constexpr char kLogcatSerialMode[] = "serial"; -constexpr char kLogcatVsockMode[] = "vsock"; - -enum RunnerExitCodes : int { - kSuccess = 0, - kArgumentParsingError = 1, - kInvalidHostConfiguration = 2, - kCuttlefishConfigurationInitError = 3, - kInstanceDirCreationError = 4, - kPrioFilesCleanupError = 5, - kBootImageUnpackError = 6, - kCuttlefishConfigurationSaveError = 7, - kDaemonizationError = 8, - kVMCreationError = 9, - kPipeIOError = 10, - kVirtualDeviceBootFailed = 11, - kProcessGroupError = 12, - kMonitorCreationFailed = 13, - kServerError = 14, - kUsbV1SocketError = 15, - kE2eTestFailed = 16, - kKernelDecompressError = 17, - kLogcatServerError = 18, - kConfigServerError = 19, - kTombstoneServerError = 20, - kTombstoneDirCreationError = 21, - kInitRamFsConcatError = 22, -}; - -// Actions supported by the launcher server -enum class LauncherAction : char { - kStatus = 'I', - kStop = 'X', -}; - -// Responses from the launcher server -enum class LauncherResponse : char { - kSuccess = 'S', - kError = 'E', - kUnknownAction = 'U', -}; -} // namespace cvd diff --git a/host/commands/stop_cvd/Android.bp b/host/commands/stop_cvd/Android.bp deleted file mode 100644 index ad279bb4..00000000 --- a/host/commands/stop_cvd/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_binary_host { - name: "stop_cvd", - srcs: [ - "main.cc", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libcuttlefish_vm_manager", - "libjsoncpp", - "libgflags", - "libxml2", - ], - defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"], -} diff --git a/host/commands/stop_cvd/main.cc b/host/commands/stop_cvd/main.cc deleted file mode 100644 index e2bb9e1b..00000000 --- a/host/commands/stop_cvd/main.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <inttypes.h> -#include <limits.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <unistd.h> -#include <signal.h> - -#include <algorithm> -#include <cstdlib> -#include <fstream> -#include <iomanip> -#include <memory> -#include <sstream> -#include <string> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "common/libs/utils/environment.h" -#include "host/commands/run_cvd/runner_defs.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/vm_manager/vm_manager.h" - -DEFINE_int32(wait_for_launcher, 5, - "How many seconds to wait for the launcher to respond to the stop " - "command. A value of zero means wait indefinetly"); - -namespace { -// Gets a set of the possible process groups of a previous launch -std::set<pid_t> GetCandidateProcessGroups() { - std::string cmd = "fuser"; - // Add the instance directory - auto instance_dir = cvd::StringFromEnv("HOME", ".") + "/cuttlefish_runtime"; - cmd += " " + instance_dir; - // Add files in instance dir - cmd += " " + instance_dir + "/*"; - // Add files in the tombstone directory - cmd += " " + instance_dir + "/tombstones/*"; - // Add files in the internal directory - cmd += ((" " + instance_dir + "/") + vsoc::kInternalDirName) + "/*"; - // Add the shared memory file - cmd += " " + vsoc::GetPerInstanceDefault("/dev/shm/cvd-"); - std::shared_ptr<FILE> cmd_out(popen(cmd.c_str(), "r"), pclose); - if (!cmd_out) { - LOG(ERROR) << "Unable to execute '" << cmd << "': " << strerror(errno); - return {}; - } - int64_t pid; - std::set<pid_t> ret{}; - while(fscanf(cmd_out.get(), "%" PRId64, &pid) != EOF) { - pid_t pgid = getpgid(static_cast<pid_t>(pid)); - if (pgid < 0) { - LOG(ERROR) << "Unable to get process group of " << pid << ": " - << strerror(errno); - continue; - } - ret.insert(pgid); - } - // The process group of stop_cvd should not be killed - ret.erase(getpgrp()); - return ret; -} - -int FallBackStop() { - auto exit_code = 1; // Having to fallback is an error - - auto process_groups = GetCandidateProcessGroups(); - for (auto pgid: process_groups) { - LOG(INFO) << "Sending SIGKILL to process group " << pgid; - auto retval = killpg(pgid, SIGKILL); - if (retval < 0) { - LOG(ERROR) << "Failed to kill process group " << pgid << ": " - << strerror(errno); - exit_code |= 4; - } - } - - return exit_code; -} -} // anonymous namespace - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Failed to obtain config object"; - return FallBackStop(); - } - - auto monitor_path = config->launcher_monitor_socket_path(); - if (monitor_path.empty()) { - LOG(ERROR) << "No path to launcher monitor found"; - return FallBackStop(); - } - auto monitor_socket = cvd::SharedFD::SocketLocalClient(monitor_path.c_str(), - false, SOCK_STREAM); - if (!monitor_socket->IsOpen()) { - LOG(ERROR) << "Unable to connect to launcher monitor at " << monitor_path - << ": " << monitor_socket->StrError(); - return FallBackStop(); - } - auto request = cvd::LauncherAction::kStop; - auto bytes_sent = monitor_socket->Send(&request, sizeof(request), 0); - if (bytes_sent < 0) { - LOG(ERROR) << "Error sending launcher monitor the stop command: " - << monitor_socket->StrError(); - return FallBackStop(); - } - // Perform a select with a timeout to guard against launcher hanging - cvd::SharedFDSet read_set; - read_set.Set(monitor_socket); - struct timeval timeout = {FLAGS_wait_for_launcher, 0}; - int selected = cvd::Select(&read_set, nullptr, nullptr, - FLAGS_wait_for_launcher <= 0 ? nullptr : &timeout); - if (selected < 0){ - LOG(ERROR) << "Failed communication with the launcher monitor: " - << strerror(errno); - return FallBackStop(); - } - if (selected == 0) { - LOG(ERROR) << "Timeout expired waiting for launcher monitor to respond"; - return FallBackStop(); - } - cvd::LauncherResponse response; - auto bytes_recv = monitor_socket->Recv(&response, sizeof(response), 0); - if (bytes_recv < 0) { - LOG(ERROR) << "Error receiving response from launcher monitor: " - << monitor_socket->StrError(); - return FallBackStop(); - } - if (response != cvd::LauncherResponse::kSuccess) { - LOG(ERROR) << "Received '" << static_cast<char>(response) - << "' response from launcher monitor"; - return FallBackStop(); - } - LOG(INFO) << "Successfully stopped device"; - return 0; -} diff --git a/host/commands/tombstone_receiver/Android.bp b/host/commands/tombstone_receiver/Android.bp deleted file mode 100644 index bd32cae0..00000000 --- a/host/commands/tombstone_receiver/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2019 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. - -cc_binary_host { - name: "tombstone_receiver", - srcs: [ - "main.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "liblog", - "libcuttlefish_utils", - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/tombstone_receiver/main.cpp b/host/commands/tombstone_receiver/main.cpp deleted file mode 100644 index 7bea6701..00000000 --- a/host/commands/tombstone_receiver/main.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include <chrono> -#include <fstream> -#include <iomanip> -#include <sstream> - -#include "common/libs/fs/shared_fd.h" -#include "host/libs/config/cuttlefish_config.h" - -DEFINE_int32( - server_fd, -1, - "File descriptor to an already created vsock server. If negative a new " - "server will be created at the port specified on the config file"); -DEFINE_string(tombstone_dir, "", "directory to write out tombstones in"); - -static uint num_tombstones_in_last_second = 0; -static std::string last_tombstone_name = ""; - -static std::string next_tombstone_path() { - auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - std::stringstream ss; - ss << FLAGS_tombstone_dir << "/tombstone_" << - std::put_time(std::gmtime(&in_time_t), "%Y-%m-%d-%H%M%S"); - auto retval = ss.str(); - - // Gives tombstones unique names - if(retval == last_tombstone_name) { - num_tombstones_in_last_second++; - retval += "_" + std::to_string(num_tombstones_in_last_second); - } else { - last_tombstone_name = retval; - num_tombstones_in_last_second = 0; - } - - LOG(INFO) << "Creating " << retval; - return retval; -} - -#define CHUNK_RECV_MAX_LEN (1024) -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - cvd::SharedFD server_fd; - - if (FLAGS_server_fd < 0) { - unsigned int port = config->tombstone_receiver_port(); - server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM); - } else { - server_fd = cvd::SharedFD::Dup(FLAGS_server_fd); - close(FLAGS_server_fd); - } - - CHECK(server_fd->IsOpen()) << "Error creating/inheriting tombstone server: " - << server_fd->StrError(); - LOG(INFO) << "Host is starting server on port " - << config->tombstone_receiver_port(); - - // Server loop - while (true) { - auto conn = cvd::SharedFD::Accept(*server_fd); - std::ofstream file(next_tombstone_path(), - std::ofstream::out | std::ofstream::binary); - - while (file.is_open()) { - char buff[CHUNK_RECV_MAX_LEN]; - auto bytes_read = conn->Read(buff, sizeof(buff)); - if (bytes_read <= 0) { - // reset the other side if it's still connected - break; - } else { - file.write(buff, bytes_read); - } - } - } - - return 0; -} diff --git a/host/commands/virtual_usb_manager/Android.bp b/host/commands/virtual_usb_manager/Android.bp deleted file mode 100644 index 6669b8c5..00000000 --- a/host/commands/virtual_usb_manager/Android.bp +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_binary_host { - name: "virtual_usb_manager", - srcs: [ - "main.cc", - "vadb/usb_cmd_attach.cpp", - "vadb/usb_cmd_control_transfer.cpp", - "vadb/usb_cmd_data_transfer.cpp", - "vadb/usb_cmd_device_list.cpp", - "vadb/usb_cmd_heartbeat.cpp", - "vadb/virtual_adb_client.cpp", - "vadb/virtual_adb_server.cpp", - "usbip/client.cpp", - "usbip/device_pool.cpp", - "usbip/messages.cpp", - "usbip/server.cpp", - "usbip/vhci_instrument.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - ], - static_libs: [ - "libcuttlefish_host_config", - "libgflags", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/virtual_usb_manager/main.cc b/host/commands/virtual_usb_manager/main.cc deleted file mode 100644 index 39fd5562..00000000 --- a/host/commands/virtual_usb_manager/main.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string> -#include <thread> - -#include <gflags/gflags.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/commands/virtual_usb_manager/usbip/server.h" -#include "host/commands/virtual_usb_manager/vadb/virtual_adb_server.h" - -DEFINE_int32( - usb_v1_fd, -1, - "A file descriptor pointing to the USB v1 open socket or -1 to create it"); - -int main(int argc, char** argv) { - ::android::base::InitLogging(argv, android::base::StderrLogger); - google::ParseCommandLineFlags(&argc, &argv, true); - - auto config = vsoc::CuttlefishConfig::Get(); - if (!config) { - LOG(ERROR) << "Unable to get config object"; - return 1; - } - - cvd::SharedFD usb_v1_server; - - if (FLAGS_usb_v1_fd < 0) { - auto socket_name = config->usb_v1_socket_name(); - LOG(INFO) << "Starting server at " << socket_name; - usb_v1_server = cvd::SharedFD::SocketLocalServer(socket_name.c_str(), false, - SOCK_STREAM, 0666); - } else { - usb_v1_server = cvd::SharedFD::Dup(FLAGS_usb_v1_fd); - } - - if (!usb_v1_server->IsOpen()) { - LOG(ERROR) << "Error openning USB v1 server: " << usb_v1_server->StrError(); - return 2; - } - - vadb::VirtualADBServer adb_{usb_v1_server, config->vhci_port(), - config->usb_ip_socket_name()}; - vadb::usbip::Server usbip_{config->usb_ip_socket_name(), adb_.Pool()}; - - CHECK(usbip_.Init()) << "Could not start USB/IP server"; - - for (;;) { - cvd::SharedFDSet fd_read; - fd_read.Zero(); - - adb_.BeforeSelect(&fd_read); - usbip_.BeforeSelect(&fd_read); - - int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr); - if (ret <= 0) continue; - - adb_.AfterSelect(fd_read); - usbip_.AfterSelect(fd_read); - } - - return 0; -} diff --git a/host/commands/virtual_usb_manager/usbip/Android.bp b/host/commands/virtual_usb_manager/usbip/Android.bp deleted file mode 100644 index 8a52b909..00000000 --- a/host/commands/virtual_usb_manager/usbip/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_library_host_static { - name: "libusbip", - srcs: [ - "client.cpp", - "device_pool.cpp", - "messages.cpp", - "server.cpp", - "vhci_instrument.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libbase", - ], - static_libs: [ - "libgflags", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/commands/virtual_usb_manager/usbip/README.md b/host/commands/virtual_usb_manager/usbip/README.md deleted file mode 100644 index e652352d..00000000 --- a/host/commands/virtual_usb_manager/usbip/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# USB/IP server library - -This folder contains set of classes and structures that constitute basic USB/IP -server. - -Protocol used in this library is defined as part of -[Linux kernel documentation](https://www.kernel.org/doc/Documentation/usb/usbip_protocol.txt). - -## Structure - -### [`vadb::usbip::Device`](./device.h)[](#Device) - -Structure describing individual device accessible over USB/IP protocol. - -### [`vadb::usbip::DevicePool`](./device_pool.h)[](#DevicePool) - -DevicePool holds a set of [Devices](#Device) that can be enumerated and -accessed by clients of this Server. - -### [`vadb::usbip::Server`](./server.h) - -Purpose of this class is to start a new listening socket and accept incoming -USB/IP connections & requests. - -### [`vadb::usbip::Client`](./client.h) - -Client class represents individual USB/IP connection. Client enables remote -USB/IP client to enumerate and access devices registered in -[DevicePool](#DevicePool). - -### [`USB/IP Messages`](./messages.h) - -This file contains structures and enum values defined by the USB/IP protocol. -All definitions found there have been collected from -[Linux kernel documentation](https://www.kernel.org/doc/Documentation/usb/usbip_protocol.txt) -. diff --git a/host/commands/virtual_usb_manager/usbip/client.cpp b/host/commands/virtual_usb_manager/usbip/client.cpp deleted file mode 100644 index 50ea9f8f..00000000 --- a/host/commands/virtual_usb_manager/usbip/client.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "host/commands/virtual_usb_manager/usbip/client.h" - -#include <arpa/inet.h> - -#include <glog/logging.h> -#include <iostream> - -#include "host/commands/virtual_usb_manager/usbip/device.h" -#include "host/commands/virtual_usb_manager/usbip/messages.h" - -namespace vadb { -namespace usbip { - -// NetToHost and HostToNet are used to reduce risk of copy/paste errors and to -// provide uniform method of converting messages between different endian types. -namespace { - -uint32_t NetToHost(uint32_t t) { return ntohl(t); } - -Command NetToHost(Command t) { return static_cast<Command>(ntohl(t)); } - -Direction NetToHost(Direction t) { return static_cast<Direction>(ntohl(t)); } - -uint32_t NetToHost(uint16_t t) { return ntohs(t); } - -CmdHeader NetToHost(const CmdHeader& t) { - CmdHeader rval = t; - rval.command = NetToHost(t.command); - rval.seq_num = NetToHost(t.seq_num); - rval.bus_num = NetToHost(t.bus_num); - rval.dev_num = NetToHost(t.dev_num); - rval.direction = NetToHost(t.direction); - rval.endpoint = NetToHost(t.endpoint); - return rval; -} - -CmdReqSubmit NetToHost(const CmdReqSubmit& t) { - CmdReqSubmit rval = t; - rval.transfer_flags = NetToHost(t.transfer_flags); - rval.transfer_buffer_length = NetToHost(t.transfer_buffer_length); - rval.start_frame = NetToHost(t.start_frame); - rval.number_of_packets = NetToHost(t.number_of_packets); - rval.deadline_interval = NetToHost(t.deadline_interval); - return rval; -} - -CmdReqUnlink NetToHost(const CmdReqUnlink& t) { - CmdReqUnlink rval = t; - rval.seq_num = NetToHost(t.seq_num); - return rval; -} - -uint32_t HostToNet(uint32_t t) { return htonl(t); } - -Command HostToNet(const Command t) { return static_cast<Command>(htonl(t)); } - -Direction HostToNet(Direction t) { return static_cast<Direction>(htonl(t)); } - -uint16_t HostToNet(uint16_t t) { return htons(t); } - -CmdHeader HostToNet(const CmdHeader& t) { - CmdHeader rval = t; - rval.command = HostToNet(t.command); - rval.seq_num = HostToNet(t.seq_num); - rval.bus_num = HostToNet(t.bus_num); - rval.dev_num = HostToNet(t.dev_num); - rval.direction = HostToNet(t.direction); - rval.endpoint = HostToNet(t.endpoint); - return rval; -} - -CmdRepSubmit HostToNet(const CmdRepSubmit& t) { - CmdRepSubmit rval = t; - rval.status = HostToNet(t.status); - rval.actual_length = HostToNet(t.actual_length); - rval.start_frame = HostToNet(t.start_frame); - rval.number_of_packets = HostToNet(t.number_of_packets); - rval.error_count = HostToNet(t.error_count); - return rval; -} - -CmdRepUnlink HostToNet(const CmdRepUnlink& t) { - CmdRepUnlink rval = t; - rval.status = HostToNet(t.status); - return rval; -} - -// Converts data to network order and sends it to the USB/IP client. -// Returns true, if message was sent successfully. -template <typename T> -bool SendUSBIPMsg(const cvd::SharedFD& fd, const T& data) { - T net = HostToNet(data); - return fd->Send(&net, sizeof(T), MSG_NOSIGNAL) == sizeof(T); -} - -// Receive message from USB/IP client. -// After message is received, it's updated to match host endian. -// Returns true, if message was received successfully. -template <typename T> -bool RecvUSBIPMsg(const cvd::SharedFD& fd, T* data) { - T net; - bool res = fd->Recv(&net, sizeof(T), MSG_NOSIGNAL) == sizeof(T); - if (res) { - *data = NetToHost(net); - } - return res; -} - -} // namespace - -void Client::BeforeSelect(cvd::SharedFDSet* fd_read) const { - fd_read->Set(fd_); -} - -bool Client::AfterSelect(const cvd::SharedFDSet& fd_read) { - if (fd_read.IsSet(fd_)) return HandleIncomingMessage(); - return true; -} - -// Handle incoming COMMAND. -// -// Read next CMD from client channel. -// Returns false, if connection should be dropped. -bool Client::HandleIncomingMessage() { - CmdHeader hdr; - if (!RecvUSBIPMsg(fd_, &hdr)) { - LOG(ERROR) << "Could not read command header: " << fd_->StrError(); - return false; - } - - // And the protocol, again. - switch (hdr.command) { - case kUsbIpCmdReqSubmit: - return HandleSubmitCmd(hdr); - - case kUsbIpCmdReqUnlink: - return HandleUnlinkCmd(hdr); - - default: - LOG(ERROR) << "Unsupported command requested: " << hdr.command; - return false; - } -} - -// Handle incoming SUBMIT COMMAND. -// -// Execute command on specified USB device. -// Returns false, if connection should be dropped. -bool Client::HandleSubmitCmd(const CmdHeader& cmd) { - CmdReqSubmit req; - if (!RecvUSBIPMsg(fd_, &req)) { - LOG(ERROR) << "Could not read submit command: " << fd_->StrError(); - return false; - } - - uint32_t seq_num = cmd.seq_num; - - // Reserve buffer for data in or out. - std::vector<uint8_t> payload; - int payload_length = req.transfer_buffer_length; - payload.resize(payload_length); - - bool is_host_to_device = cmd.direction == kUsbIpDirectionOut; - // Control requests are quite easy to detect; if setup is all '0's, then we're - // doing a data transfer, otherwise it's a control transfer. - // We only check for cmd and type fields here, as combination 0/0 of these - // fields is already invalid (cmd == GET_STATUS, type = WRITE). - bool is_control_request = !(req.setup.cmd == 0 && req.setup.type == 0); - - // Find requested device and execute command. - auto device = pool_.GetDevice({cmd.bus_num, cmd.dev_num}); - if (device) { - // Read data to be sent to device, if specified. - if (is_host_to_device && payload_length) { - size_t got = 0; - // Make sure we read everything. - while (got < payload.size()) { - auto read = - fd_->Recv(&payload[got], payload.size() - got, MSG_NOSIGNAL); - if (fd_->GetErrno() != 0) { - LOG(ERROR) << "Client disconnected: " << fd_->StrError(); - return false; - } else if (!read) { - LOG(ERROR) << "Short read; client likely disconnected."; - return false; - } - got += read; - } - } - - // If setup structure of request is initialized then we need to execute - // control transfer. Otherwise, this is a plain data exchange. - bool send_success = false; - if (is_control_request) { - send_success = device->handle_control_transfer( - req.setup, req.deadline_interval, std::move(payload), - [this, seq_num, is_host_to_device](bool is_success, - std::vector<uint8_t> data) { - HandleAsyncDataReady(seq_num, is_success, is_host_to_device, - std::move(data)); - }); - } else { - send_success = device->handle_data_transfer( - cmd.endpoint, is_host_to_device, req.deadline_interval, - std::move(payload), - [this, seq_num, is_host_to_device](bool is_success, - std::vector<uint8_t> data) { - HandleAsyncDataReady(seq_num, is_success, is_host_to_device, - std::move(data)); - }); - } - - // Simply fail if couldn't execute command. - if (!send_success) { - HandleAsyncDataReady(seq_num, false, is_host_to_device, - std::vector<uint8_t>()); - } - } - return true; -} - -void Client::HandleAsyncDataReady(uint32_t seq_num, bool is_success, - bool is_host_to_device, - std::vector<uint8_t> data) { - // Response template. - // - in header, host doesn't care about anything else except for command type - // and sequence number. - // - in body, report status == !OK unless we completed everything - // successfully. - CmdHeader rephdr{}; - rephdr.command = kUsbIpCmdRepSubmit; - rephdr.seq_num = seq_num; - - CmdRepSubmit rep{}; - rep.status = is_success ? 0 : 1; - rep.actual_length = data.size(); - - // Data out. - if (!SendUSBIPMsg(fd_, rephdr)) { - LOG(ERROR) << "Failed to send response header: " << fd_->StrError(); - return; - } - - if (!SendUSBIPMsg(fd_, rep)) { - LOG(ERROR) << "Failed to send response body: " << fd_->StrError(); - return; - } - - if (!is_host_to_device && data.size() > 0) { - if (static_cast<size_t>( - fd_->Send(data.data(), data.size(), MSG_NOSIGNAL)) != data.size()) { - LOG(ERROR) << "Failed to send response payload: " << fd_->StrError(); - return; - } - } -} - -// Handle incoming UNLINK COMMAND. -// -// Unlink removes command specified via seq_num from a list of commands to be -// executed. -// We don't schedule commands for execution, so technically every UNLINK will -// come in late. -// Returns false, if connection should be dropped. -bool Client::HandleUnlinkCmd(const CmdHeader& cmd) { - CmdReqUnlink req; - if (!RecvUSBIPMsg(fd_, &req)) { - LOG(ERROR) << "Could not read unlink command: " << fd_->StrError(); - return false; - } - LOG(INFO) << "Client requested to unlink previously submitted command: " - << req.seq_num; - - CmdHeader rephdr{}; - rephdr.command = kUsbIpCmdRepUnlink; - rephdr.seq_num = cmd.seq_num; - - // Technically we do not schedule commands for execution, so we cannot - // de-queue commands, either. Indicate this by sending status != ok. - CmdRepUnlink rep; - rep.status = 1; - - if (!SendUSBIPMsg(fd_, rephdr)) { - LOG(ERROR) << "Could not send unlink command header: " << fd_->StrError(); - return false; - } - - if (!SendUSBIPMsg(fd_, rep)) { - LOG(ERROR) << "Could not send unlink command data: " << fd_->StrError(); - return false; - } - return true; -} - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/client.h b/host/commands/virtual_usb_manager/usbip/client.h deleted file mode 100644 index 5e48f217..00000000 --- a/host/commands/virtual_usb_manager/usbip/client.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "host/commands/virtual_usb_manager/usbip/device_pool.h" -#include "host/commands/virtual_usb_manager/usbip/messages.h" - -namespace vadb { -namespace usbip { - -// Represents USB/IP client, or individual connection to our USB/IP server. -// Multiple clients are allowed, even if practically we anticipate only one -// connection at the time. -class Client final { - public: - Client(const DevicePool& pool, const cvd::SharedFD& fd) - : pool_(pool), fd_(fd) {} - - ~Client() {} - - // BeforeSelect is Called right before Select() to populate interesting - // SharedFDs. - void BeforeSelect(cvd::SharedFDSet* fd_read) const; - - // AfterSelect is Called right after Select() to detect and respond to changes - // on affected SharedFDs. - // Return value indicates whether this client is still valid. - bool AfterSelect(const cvd::SharedFDSet& fd_read); - - private: - // Respond to message from remote client. - // Returns false, if client violated protocol or disconnected, indicating, - // that this instance should no longer be used. - bool HandleIncomingMessage(); - - // Execute command on USB device. - // Returns false, if connection should be dropped. - bool HandleSubmitCmd(const CmdHeader& hdr); - - // HandleAsyncDataReady is called asynchronously once previously submitted - // data transfer (control or bulk) has completed (or failed). - void HandleAsyncDataReady(uint32_t seq_num, bool is_success, - bool is_host_to_device, std::vector<uint8_t> data); - - // Unlink previously submitted message from device queue. - // Returns false, if connection should be dropped. - bool HandleUnlinkCmd(const CmdHeader& hdr); - - const DevicePool& pool_; - cvd::SharedFD fd_; - - Client(const Client&) = delete; - Client& operator=(const Client&) = delete; -}; - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/device.h b/host/commands/virtual_usb_manager/usbip/device.h deleted file mode 100644 index 7af1cccb..00000000 --- a/host/commands/virtual_usb_manager/usbip/device.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <cstdint> -#include <functional> -#include <map> -#include <memory> -#include <vector> - -#include "host/commands/virtual_usb_manager/usbip/messages.h" - -namespace vadb { -namespace usbip { - -// The device descriptor of a USB device represents a USB device that is -// available for import. -class Device { - public: - // AsyncTransferReadyCB specifies a signature of a function that will be - // called upon transfer completion (whether successful or failed). Parameters - // supplied to the function are: - // - operation status, indicated by boolean flag (true = success), - // - vector containing transferred data (and actual size). - using AsyncTransferReadyCB = std::function<void(bool, std::vector<uint8_t>)>; - - // Interface provides minimal description of device's interface. - struct Interface { - uint8_t iface_class; - uint8_t iface_subclass; - uint8_t iface_protocol; - }; - - // vendor_id and product_id identify device manufacturer and type. - // dev_version describes device version (as BCD). - uint16_t vendor_id; - uint16_t product_id; - uint16_t dev_version; - - // Class, Subclass and Protocol define device type. - uint8_t dev_class; - uint8_t dev_subclass; - uint8_t dev_protocol; - - // Speed indicates device speed (see libusb_speed). - uint8_t speed; - - // ConfigurationsCount and ConfigurationNumber describe total number of device - // configurations and currently activated device configuration. - size_t configurations_count; - size_t configuration_number; - - // Interfaces returns a collection of device interfaces. - std::vector<Interface> interfaces; - - // Attach request handler. - std::function<bool()> handle_attach; - - // Device control request dispatcher. - std::function<bool(const CmdRequest& request, uint32_t deadline, - std::vector<uint8_t> data, AsyncTransferReadyCB callback)> - handle_control_transfer; - - // Device data request dispatcher. - std::function<bool(uint8_t endpoint, bool is_host_to_device, - uint32_t deadline, std::vector<uint8_t> data, - AsyncTransferReadyCB callback)> - handle_data_transfer; -}; - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/device_pool.cpp b/host/commands/virtual_usb_manager/usbip/device_pool.cpp deleted file mode 100644 index ecd3e8ea..00000000 --- a/host/commands/virtual_usb_manager/usbip/device_pool.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/virtual_usb_manager/usbip/device_pool.h" - -#include <glog/logging.h> - -namespace vadb { -namespace usbip { - -void DevicePool::AddDevice(BusDevNumber bdn, std::unique_ptr<Device> device) { - devices_[bdn] = std::move(device); -} - -Device* DevicePool::GetDevice(BusDevNumber bus_id) const { - auto iter = devices_.find(bus_id); - if (iter == devices_.end()) return nullptr; - return iter->second.get(); -} - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/device_pool.h b/host/commands/virtual_usb_manager/usbip/device_pool.h deleted file mode 100644 index f6988c4c..00000000 --- a/host/commands/virtual_usb_manager/usbip/device_pool.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <map> -#include <string> - -#include "host/commands/virtual_usb_manager/usbip/device.h" - -namespace vadb { -namespace usbip { -// Container for all virtual USB/IP devices. -// Stores devices by virtual BUS ID. -class DevicePool { - public: - // BusDevNumber is a pair uniquely identifying bus and device. - struct BusDevNumber { - uint16_t bus_number; - uint16_t dev_number; - - bool operator<(BusDevNumber other) const { - return (bus_number << 16 | dev_number) < - (other.bus_number << 16 | other.dev_number); - } - }; - - // Internal container type. - using MapType = std::map<BusDevNumber, std::unique_ptr<Device>>; - - DevicePool() = default; - virtual ~DevicePool() = default; - - // Add new device associated with virtual BUS ID. - void AddDevice(BusDevNumber bus_id, std::unique_ptr<Device> device); - - // Get device associated with supplied virtual bus/device number. - Device* GetDevice(BusDevNumber bus_dev_num) const; - - // Get total number of USB/IP devices. - size_t Size() const { return devices_.size(); } - - MapType::const_iterator begin() const { return devices_.cbegin(); } - MapType::const_iterator end() const { return devices_.cend(); } - - private: - MapType devices_; - - DevicePool(const DevicePool&) = delete; - DevicePool& operator=(const DevicePool&) = delete; -}; - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/messages.cpp b/host/commands/virtual_usb_manager/usbip/messages.cpp deleted file mode 100644 index 9de7c260..00000000 --- a/host/commands/virtual_usb_manager/usbip/messages.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "host/commands/virtual_usb_manager/usbip/messages.h" - -#include <netinet/in.h> -#include <iostream> - -#include <glog/logging.h> - -namespace vadb { -namespace usbip { -namespace { -// Basic sanity checking. -// We're using CmdHeader + CmdReq/Rep in case any of the fields is moved between -// structures. -constexpr int kUsbIpCmdLength = 48; - -static_assert(sizeof(CmdHeader) + sizeof(CmdReqSubmit) == kUsbIpCmdLength, - "USB/IP command + header must be exactly 48 bytes."); -static_assert(sizeof(CmdHeader) + sizeof(CmdRepSubmit) == kUsbIpCmdLength, - "USB/IP command + header must be exactly 48 bytes."); -static_assert(sizeof(CmdHeader) + sizeof(CmdReqUnlink) == kUsbIpCmdLength, - "USB/IP command + header must be exactly 48 bytes."); -static_assert(sizeof(CmdHeader) + sizeof(CmdRepUnlink) == kUsbIpCmdLength, - "USB/IP command + header must be exactly 48 bytes."); -} // namespace - -std::ostream& operator<<(std::ostream& out, const CmdHeader& header) { - out << "CmdHeader\n"; - out << "\t\tcmd:\t" << header.command << '\n'; - out << "\t\tseq#:\t" << header.seq_num << '\n'; - out << "\t\tbus#:\t0x" << header.bus_num << '\n'; - out << "\t\tdev#:\t0x" << header.dev_num << '\n'; - out << "\t\tdir:\t" << (header.direction ? "in" : "out") << '\n'; - out << "\t\tendpt:\t" << header.endpoint << "\n"; - return out; -} - -std::ostream& operator<<(std::ostream& out, const CmdRequest& setup) { - out << "Request\n"; - out << "\t\t\ttype:\t" << std::hex << int(setup.type) << '\n'; - out << "\t\t\treq:\t" << int(setup.cmd) << std::dec << '\n'; - out << "\t\t\tval:\t" << setup.value << '\n'; - out << "\t\t\tidx:\t" << setup.index << '\n'; - out << "\t\t\tlen:\t" << setup.length << '\n'; - return out; -} - -std::ostream& operator<<(std::ostream& out, const CmdReqSubmit& submit) { - out << "CmdReqSubmit\n"; - out << "\t\ttr_flg:\t" << std::hex << submit.transfer_flags << std::dec - << '\n'; - out << "\t\ttr_len:\t" << submit.transfer_buffer_length << '\n'; - out << "\t\tstart:\t" << submit.start_frame << '\n'; - out << "\t\tpktcnt:\t" << submit.number_of_packets << '\n'; - out << "\t\tttl:\t" << submit.deadline_interval << '\n'; - out << "\t\tsetup:\t" << submit.setup << '\n'; - return out; -} - -std::ostream& operator<<(std::ostream& out, const CmdRepSubmit& submit) { - out << "CmdRepSubmit\n"; - out << "\t\tstatus:\t" << submit.status << '\n'; - out << "\t\tlen:\t" << submit.actual_length << '\n'; - out << "\t\tstart:\t" << submit.start_frame << '\n'; - out << "\t\tpktcnt:\t" << submit.number_of_packets << '\n'; - out << "\t\terrors:\t" << submit.error_count << '\n'; - out << "\t\tsetup:\t" << submit.setup << '\n'; - return out; -} - -std::ostream& operator<<(std::ostream& out, const CmdReqUnlink& unlink) { - out << "CmdReqUnlink\n"; - out << "\t\tseq#:\t" << unlink.seq_num << '\n'; - return out; -} - -std::ostream& operator<<(std::ostream& out, const CmdRepUnlink& unlink) { - out << "CmdRepUnlink\n"; - out << "\t\tstatus:\t" << unlink.status << '\n'; - return out; -} - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/messages.h b/host/commands/virtual_usb_manager/usbip/messages.h deleted file mode 100644 index 8594465f..00000000 --- a/host/commands/virtual_usb_manager/usbip/messages.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <glog/logging.h> -#include <stdint.h> - -#include "common/libs/fs/shared_fd.h" - -// Requests and constants below are defined in kernel documentation file: -// https://www.kernel.org/doc/Documentation/usb/usbip_protocol.txt -namespace vadb { -namespace usbip { - -//////////////////////////////////////////////////////////////////////////////// -// COMMANDS -//////////////////////////////////////////////////////////////////////////////// - -// Command numbers. Commands are valid only once USB device is attached. -enum Command : uint32_t { - kUsbIpCmdReqSubmit = 1, // Submit request - kUsbIpCmdReqUnlink = 2, // Unlink request - kUsbIpCmdRepSubmit = 3, // Submit response - kUsbIpCmdRepUnlink = 4, // Unlink response -}; - -// Direction of data flow. -enum Direction : uint32_t { - kUsbIpDirectionOut = 0, - kUsbIpDirectionIn = 1, -}; - -// Setup structure is explained in great detail here: -// - http://www.beyondlogic.org/usbnutshell/usb6.shtml -// - http://www.usbmadesimple.co.uk/ums_4.htm -struct CmdRequest { - uint8_t type; - uint8_t cmd; - uint16_t value; - uint16_t index; - uint16_t length; -} __attribute__((packed)); - -// CmdHeader precedes any command request or response body. -struct CmdHeader { - Command command; - uint32_t seq_num; - uint16_t bus_num; - uint16_t dev_num; - Direction direction; - uint32_t endpoint; // valid values: 0-15 -} __attribute__((packed)); - -// Command data for submitting an USB request. -struct CmdReqSubmit { - uint32_t transfer_flags; - uint32_t transfer_buffer_length; - uint32_t start_frame; - uint32_t number_of_packets; - uint32_t deadline_interval; - CmdRequest setup; -} __attribute__((packed)); - -// Command response for submitting an USB request. -struct CmdRepSubmit { - uint32_t status; // 0 = success. - uint32_t actual_length; - uint32_t start_frame; - uint32_t number_of_packets; - uint32_t error_count; - CmdRequest setup; -} __attribute__((packed)); - -// Unlink USB request. -struct CmdReqUnlink { - uint32_t seq_num; - uint32_t reserved[6]; -} __attribute__((packed)); - -// Unlink USB response. -struct CmdRepUnlink { - uint32_t status; - uint32_t reserved[6]; -} __attribute__((packed)); - -// Diagnostics. -std::ostream& operator<<(std::ostream& out, const CmdHeader& header); -std::ostream& operator<<(std::ostream& out, const CmdReqSubmit& data); -std::ostream& operator<<(std::ostream& out, const CmdRepSubmit& data); -std::ostream& operator<<(std::ostream& out, const CmdReqUnlink& data); -std::ostream& operator<<(std::ostream& out, const CmdRepUnlink& data); - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/server.cpp b/host/commands/virtual_usb_manager/usbip/server.cpp deleted file mode 100644 index ef71b72a..00000000 --- a/host/commands/virtual_usb_manager/usbip/server.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/virtual_usb_manager/usbip/server.h" - -#include <glog/logging.h> -#include <netinet/in.h> -#include "common/libs/fs/shared_select.h" - -using cvd::SharedFD; - -namespace vadb { -namespace usbip { -Server::Server(const std::string& name, const DevicePool& devices) - : name_{name}, device_pool_{devices} {} - -bool Server::Init() { return CreateServerSocket(); } - -// Open new listening server socket. -// Returns false, if listening socket could not be created. -bool Server::CreateServerSocket() { - LOG(INFO) << "Starting server socket: " << name_; - - server_ = SharedFD::SocketLocalServer(name_.c_str(), true, SOCK_STREAM, 0700); - if (!server_->IsOpen()) { - LOG(ERROR) << "Could not create socket: " << server_->StrError(); - return false; - } - return true; -} - -void Server::BeforeSelect(cvd::SharedFDSet* fd_read) const { - fd_read->Set(server_); - for (const auto& client : clients_) client.BeforeSelect(fd_read); -} - -void Server::AfterSelect(const cvd::SharedFDSet& fd_read) { - if (fd_read.IsSet(server_)) HandleIncomingConnection(); - - for (auto iter = clients_.begin(); iter != clients_.end();) { - if (!iter->AfterSelect(fd_read)) { - // If client conversation failed, hang up. - iter = clients_.erase(iter); - continue; - } - ++iter; - } -} - -// Accept new USB/IP connection. Add it to client pool. -void Server::HandleIncomingConnection() { - SharedFD client = SharedFD::Accept(*server_, nullptr, nullptr); - if (!client->IsOpen()) { - LOG(ERROR) << "Client connection failed: " << client->StrError(); - return; - } - - clients_.emplace_back(device_pool_, client); -} -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/server.h b/host/commands/virtual_usb_manager/usbip/server.h deleted file mode 100644 index 5c574f7c..00000000 --- a/host/commands/virtual_usb_manager/usbip/server.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <list> -#include <string> - -#include "common/libs/fs/shared_fd.h" -#include "host/commands/virtual_usb_manager/usbip/client.h" -#include "host/commands/virtual_usb_manager/usbip/device_pool.h" - -namespace vadb { -namespace usbip { - -class Server final { - public: - Server(const std::string& name, const DevicePool& device_pool); - ~Server() = default; - - // Initialize this instance of Server. - // Returns true, if initialization was successful. - bool Init(); - - // BeforeSelect is Called right before Select() to populate interesting - // SharedFDs. - void BeforeSelect(cvd::SharedFDSet* fd_read) const; - - // AfterSelect is Called right after Select() to detect and respond to changes - // on affected SharedFDs. - void AfterSelect(const cvd::SharedFDSet& fd_read); - - private: - // Create USBIP server socket. - // Returns true, if socket was successfully created. - bool CreateServerSocket(); - - // Handle new client connection. - // New clients will be appended to clients_ list. - void HandleIncomingConnection(); - - std::string name_; - cvd::SharedFD server_; - std::list<Client> clients_; - - const DevicePool& device_pool_; - - Server(const Server&) = delete; - Server& operator=(const Server&) = delete; -}; - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/vhci_instrument.cpp b/host/commands/virtual_usb_manager/usbip/vhci_instrument.cpp deleted file mode 100644 index 9df09adb..00000000 --- a/host/commands/virtual_usb_manager/usbip/vhci_instrument.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> -#include <string.h> - -#include <arpa/inet.h> -#include <netdb.h> -#include <sys/socket.h> - -#include <glog/logging.h> -#include <fstream> -#include <limits> -#include <sstream> -#include "common/libs/fs/shared_select.h" - -#include "common/libs/fs/shared_fd.h" -#include "host/commands/virtual_usb_manager/usbip/vhci_instrument.h" - -namespace vadb { -namespace usbip { -namespace { -// Device ID is specified as a concatenated pair of BUS and DEVICE id. -// Since we only export one device and our server doesn't care much about -// its number, we use the default value of BUS=1 and DEVICE=1. -// This can be set to something else and should still work, as long as -// numbers are valid in USB sense. -constexpr uint32_t kDefaultDeviceID = (1 << 16) | 1; - -// Request Highspeed configuration. Superspeed isn't supported by vhci. -// Supported configurations are: -// 4 -> wireless -// 3 -> highspeed -// 2 -> full speed -// 1 -> low speed -// Please refer to the Kernel source tree in the following locations: -// include/uapi/linux/usb/ch9.h -// drivers/usb/usbip/vhci_sysfs.c -constexpr uint32_t kDefaultDeviceSpeed = 3; - -// Subsystem and device type where VHCI driver is located. -const char* const kVHCIPlatformPaths[] = { - "/sys/devices/platform/vhci_hcd", - "/sys/devices/platform/vhci_hcd.1", -}; - -// Control messages. -// Attach tells thread to attach remote device. -// Detach tells thread to detach remote device. -using ControlMsgType = uint8_t; -constexpr ControlMsgType kControlAttach = 'A'; -constexpr ControlMsgType kControlDetach = 'D'; -constexpr ControlMsgType kControlExit = 'E'; - -// Used with EPOLL as epoll_data to determine event type. -enum EpollEventType { - kControlEvent, - kVHCIEvent, -}; - -} // anonymous namespace - -VHCIInstrument::VHCIInstrument(int port, const std::string& name) - : name_(name), port_{port} {} - -VHCIInstrument::~VHCIInstrument() { - control_write_end_->Write(&kControlExit, sizeof(kControlExit)); - attach_thread_.join(); -} - -bool VHCIInstrument::Init() { - cvd::SharedFD::Pipe(&control_read_end_, &control_write_end_); - - struct stat buf; - for (const auto* path : kVHCIPlatformPaths) { - if (stat(path, &buf) == 0) { - syspath_ = path; - break; - } - } - - if (syspath_.empty()) { - LOG(ERROR) << "VHCI not available. Is the driver loaded?"; - LOG(ERROR) << "Try: sudo modprobe vhci_hcd"; - LOG(ERROR) << "The driver is part of linux-image-extra-`uname -r` package"; - return false; - } - - if (!VerifyPortIsFree()) { - LOG(ERROR) << "Trying to use VHCI port " << port_ << " but it is already in" - << " use."; - return false; - } - - LOG(INFO) << "Using VHCI port " << port_; - attach_thread_ = std::thread([this] { AttachThread(); }); - return true; -} - -bool VHCIInstrument::VerifyPortIsFree() const { - std::ifstream status_file(syspath_ + "/status"); - - if (!status_file.good()) { - LOG(ERROR) << "Could not open usb-ip status file."; - return false; - } - - // Skip past the header line. - status_file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); - - while (true) { - // Port status values deducted from /sys/devices/platform/vhci_hcd/status - // kVHCIPortFree indicates the port is not currently in use. - constexpr static int kVHCIStatusPortFree = 4; - - int port{}; - int status{}; - status_file >> port >> status; - if (!status_file.good()) { - break; - } - - status_file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); - if (port_ == port) { - return status == kVHCIStatusPortFree; - } - } - LOG(ERROR) << "Couldn't find status for VHCI port " << port_; - return false; -} - -void VHCIInstrument::TriggerAttach() { - control_write_end_->Write(&kControlAttach, sizeof(kControlAttach)); -} - -void VHCIInstrument::TriggerDetach() { - control_write_end_->Write(&kControlDetach, sizeof(kControlDetach)); -} - -void VHCIInstrument::AttachThread() { - cvd::SharedFD epoll = cvd::SharedFD::Epoll(); - // Trigger attach upon start. - bool want_attach = true; - // Operation is pending on read. - bool is_pending = false; - - epoll_event control_event; - control_event.events = EPOLLIN; - control_event.data.u64 = kControlEvent; - epoll_event vhci_event; - vhci_event.events = EPOLLRDHUP | EPOLLONESHOT; - vhci_event.data.u64 = kVHCIEvent; - - epoll->EpollCtl(EPOLL_CTL_ADD, control_read_end_, &control_event); - while (true) { - if (vhci_socket_->IsOpen()) { - epoll->EpollCtl(EPOLL_CTL_ADD, vhci_socket_, &vhci_event); - } - - epoll_event found_event{}; - ControlMsgType request_type; - - if (epoll->EpollWait(&found_event, 1, 1000)) { - switch (found_event.data.u64) { - case kControlEvent: - control_read_end_->Read(&request_type, sizeof(request_type)); - is_pending = true; - want_attach = request_type == kControlAttach; - LOG(INFO) << (want_attach ? "Attach" : "Detach") << " triggered."; - break; - case kVHCIEvent: - vhci_socket_ = cvd::SharedFD(); - // Only re-establish VHCI if it was already established before. - is_pending = want_attach; - // Do not immediately fall into attach cycle. It will likely complete - // before VHCI finishes deregistering this callback. - continue; - } - } - - // Make an attempt to re-attach. If successful, clear pending attach flag. - if (is_pending) { - if (want_attach && Attach()) { - is_pending = false; - } else if (!want_attach && Detach()) { - is_pending = false; - } else { - LOG(INFO) << (want_attach ? "Attach" : "Detach") << " unsuccessful. " - << "Will re-try."; - sleep(1); - } - } - } -} - -bool VHCIInstrument::Detach() { - std::stringstream result; - result << port_; - std::ofstream detach(syspath_ + "/detach"); - - if (!detach.is_open()) { - LOG(WARNING) << "Could not open VHCI detach file."; - return false; - } - detach << result.str(); - return detach.rdstate() == std::ios_base::goodbit; -} - -bool VHCIInstrument::Attach() { - if (!vhci_socket_->IsOpen()) { - vhci_socket_ = - cvd::SharedFD::SocketLocalClient(name_.c_str(), true, SOCK_STREAM); - if (!vhci_socket_->IsOpen()) return false; - } - - int sys_fd = vhci_socket_->UNMANAGED_Dup(); - bool success = false; - - { - std::stringstream result; - result << port_ << ' ' << sys_fd << ' ' << kDefaultDeviceID << ' ' - << kDefaultDeviceSpeed; - std::string path = syspath_ + "/attach"; - std::ofstream attach(path); - - if (!attach.is_open()) { - LOG(WARNING) << "Could not open VHCI attach file " << path << " (" - << strerror(errno) << ")"; - close(sys_fd); - return false; - } - attach << result.str(); - - // It is unclear whether duplicate FD should remain open or not. There are - // cases supporting both assumptions, likely related to kernel version. - // Kernel 4.10 is having problems communicating with USB/IP server if the - // socket is closed after it's passed to kernel. It is a clear indication - // that the kernel requires the socket to be kept open. - success = attach.rdstate() == std::ios_base::goodbit; - // Make sure everything was written and flushed. This happens when we close - // the ofstream attach. - } - - close(sys_fd); - return success; -} - -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/usbip/vhci_instrument.h b/host/commands/virtual_usb_manager/usbip/vhci_instrument.h deleted file mode 100644 index aa2f5d44..00000000 --- a/host/commands/virtual_usb_manager/usbip/vhci_instrument.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> -#include <string> -#include <thread> - -#include "common/libs/fs/shared_fd.h" - -namespace vadb { -namespace usbip { -// VHCIInstrument class configures VHCI-HCD on local kernel. -class VHCIInstrument { - public: - VHCIInstrument(int port, const std::string& name); - virtual ~VHCIInstrument(); - - // Init opens vhci-hcd driver and allocates port to which remote USB device - // will be attached. - // Returns false, if vhci-hcd driver could not be opened, or if no free port - // was found. - bool Init(); - - // TriggerAttach tells underlying thread to make attempt to re-attach USB - // device. - void TriggerAttach(); - - // TriggerDetach tells underlying thread to disconnect remote USB device. - void TriggerDetach(); - - private: - // Attach makes an attempt to configure VHCI to enable virtual USB device. - // Returns true, if configuration attempt was successful. - bool Attach(); - - // Detach disconnects virtual USB device. - // Returns true, if attempt was successful. - bool Detach(); - - // AttachThread is a background thread that responds to configuration - // requests. - void AttachThread(); - bool VerifyPortIsFree() const; - - private: - std::string name_; - std::thread attach_thread_; - std::string syspath_; - cvd::SharedFD control_write_end_; - cvd::SharedFD control_read_end_; - cvd::SharedFD vhci_socket_; - int port_{}; - - VHCIInstrument(const VHCIInstrument& other) = delete; - VHCIInstrument& operator=(const VHCIInstrument& other) = delete; -}; -} // namespace usbip -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd.h b/host/commands/virtual_usb_manager/vadb/usb_cmd.h deleted file mode 100644 index 7039fbea..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/usbforward/protocol.h" - -namespace vadb { -// USBCommand is an abstraction of a proxied USB command. -// Instances of this object all share the following life cycle: -// 1) A specific instance (COMMAND) is being created. -// 2) Instance owner (OWNER) sends RequestHeader. -// 3) OWNER calls COMMAND.OnRequest() to send any relevant, additional -// information. -// 4) OWNER queues COMMAND until response arrives. -// -// At this point instance owner can process next command in queue. Then, -// eventually: -// -// 5) OWNER receives matching ResponseHeader. -// 6) OWNER calls COMMAND.OnResponse(), supplying FD that carries additional -// data. -// 7) OWNER dequeues and deletes COMMAND. -class USBCommand { - public: - USBCommand() = default; - virtual ~USBCommand() = default; - - // Command returns a specific usbforward command ID associated with this - // request. - virtual usb_forward::Command Command() = 0; - - // OnRequest is called whenever additional data relevant to this command - // (other than RequestHeader) should be sent. - // Returns false, if communication with remote host failed (and should be - // terminated). - virtual bool OnRequest(const cvd::SharedFD& data) = 0; - - // OnResponse is called whenever additional data relevant to this command - // (other than ResponseHeader) should be received. - // Returns false, if communication with remote host failed (and should be - // terminated). - virtual bool OnResponse(bool is_success, const cvd::SharedFD& data) = 0; - - private: - USBCommand(const USBCommand& other) = delete; - USBCommand& operator=(const USBCommand& other) = delete; -}; - -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.cpp b/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.cpp deleted file mode 100644 index 8418236c..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <glog/logging.h> - -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_attach.h" - -namespace vadb { -bool USBCmdAttach::OnRequest(const cvd::SharedFD& fd) { - if (fd->Write(&req_, sizeof(req_)) != sizeof(req_)) { - LOG(ERROR) << "Short write: " << fd->StrError(); - return false; - } - return true; -} - -bool USBCmdAttach::OnResponse(bool is_success, const cvd::SharedFD& /*data*/) { - if (!is_success) return false; - LOG(INFO) << "Attach successful."; - return true; -} - -USBCmdAttach::USBCmdAttach(uint8_t bus_id, uint8_t dev_id) { - req_.bus_id = bus_id; - req_.dev_id = dev_id; -} -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.h b/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.h deleted file mode 100644 index 368deca0..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_attach.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" - -namespace vadb { -// Request remote device attach (~open). -class USBCmdAttach : public USBCommand { - public: - USBCmdAttach(uint8_t bus_id, uint8_t dev_id); - ~USBCmdAttach() override = default; - - // Return usbforward command this instance is executing. - usb_forward::Command Command() override { return usb_forward::CmdAttach; } - - // Send request body to the server. - // Return false, if communication failed. - bool OnRequest(const cvd::SharedFD& data) override; - - // Receive response data from the server. - // Return false, if communication failed. - bool OnResponse(bool is_success, const cvd::SharedFD& data) override; - - private: - usb_forward::AttachRequest req_; - - USBCmdAttach(const USBCmdAttach& other) = delete; - USBCmdAttach& operator=(const USBCmdAttach& other) = delete; -}; -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.cpp b/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.cpp deleted file mode 100644 index 16fec69a..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <glog/logging.h> - -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h" - -namespace vadb { -USBCmdControlTransfer::USBCmdControlTransfer( - uint8_t bus_id, uint8_t dev_id, uint8_t type, uint8_t request, - uint16_t value, uint16_t index, uint32_t timeout, std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) - : data_(std::move(data)), callback_(std::move(callback)) { - req_.bus_id = bus_id; - req_.dev_id = dev_id; - req_.type = type; - req_.cmd = request; - req_.value = value; - req_.index = index; - req_.length = data_.size(); - req_.timeout = timeout; -} - -bool USBCmdControlTransfer::OnRequest(const cvd::SharedFD& fd) { - if (fd->Write(&req_, sizeof(req_)) != sizeof(req_)) { - LOG(ERROR) << "Short write: " << fd->StrError(); - return false; - } - - if ((req_.type & 0x80) == 0) { - if (data_.size() > 0) { - if (static_cast<size_t>(fd->Write(data_.data(), data_.size())) != - data_.size()) { - LOG(ERROR) << "Short write: " << fd->StrError(); - return false; - } - } - } - - return true; -} - -bool USBCmdControlTransfer::OnResponse(bool is_success, - const cvd::SharedFD& fd) { - if (!is_success) { - callback_(false, std::move(data_)); - return true; - } - - if (req_.type & 0x80) { - int32_t len; - if (fd->Read(&len, sizeof(len)) != sizeof(len)) { - LOG(ERROR) << "Short read: " << fd->StrError(); - callback_(false, std::move(data_)); - return false; - } - - if (len > 0) { - data_.resize(len); - if (fd->Read(data_.data(), len) != len) { - LOG(ERROR) << "Short read: " << fd->StrError(); - callback_(false, std::move(data_)); - return false; - } - } - } - - callback_(true, std::move(data_)); - return true; -} -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h b/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h deleted file mode 100644 index 08aa159f..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> - -#include <stdint.h> - -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" -#include "host/commands/virtual_usb_manager/usbip/device.h" - -namespace vadb { -// Execute control transfer. -class USBCmdControlTransfer : public USBCommand { - public: - USBCmdControlTransfer(uint8_t bus_id, uint8_t dev_id, uint8_t type, - uint8_t request, uint16_t value, uint16_t index, - uint32_t timeout, std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback); - - ~USBCmdControlTransfer() override = default; - - // Return usbforward command this instance is executing. - usb_forward::Command Command() override { - return usb_forward::CmdControlTransfer; - } - - // Send request body to the server. - // Return false, if communication failed. - bool OnRequest(const cvd::SharedFD& data) override; - - // Receive response data from the server. - // Return false, if communication failed. - bool OnResponse(bool is_success, const cvd::SharedFD& data) override; - - private: - usb_forward::ControlTransfer req_; - std::vector<uint8_t> data_; - usbip::Device::AsyncTransferReadyCB callback_; - - USBCmdControlTransfer(const USBCmdControlTransfer& other) = delete; - USBCmdControlTransfer& operator=(const USBCmdControlTransfer& other) = delete; -}; -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.cpp b/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.cpp deleted file mode 100644 index 8de468fc..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <glog/logging.h> - -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.h" - -namespace vadb { -USBCmdDataTransfer::USBCmdDataTransfer( - uint8_t bus_id, uint8_t dev_id, uint8_t endpoint, bool is_host_to_device, - uint32_t deadline, std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) - : data_(std::move(data)), callback_(std::move(callback)) { - req_.bus_id = bus_id; - req_.dev_id = dev_id; - req_.endpoint_id = endpoint; - req_.is_host_to_device = is_host_to_device; - req_.length = data_.size(); - req_.timeout = deadline; -} - -bool USBCmdDataTransfer::OnRequest(const cvd::SharedFD& fd) { - if (fd->Write(&req_, sizeof(req_)) != sizeof(req_)) { - LOG(ERROR) << "Short write: " << fd->StrError(); - return false; - } - - if (req_.is_host_to_device && data_.size() > 0) { - if (static_cast<size_t>(fd->Write(data_.data(), data_.size())) != - data_.size()) { - LOG(ERROR) << "Short write: " << fd->StrError(); - return false; - } - } - - return true; -} - -bool USBCmdDataTransfer::OnResponse(bool is_success, const cvd::SharedFD& fd) { - if (!is_success) { - callback_(false, std::move(data_)); - return true; - } - - if (!req_.is_host_to_device) { - int32_t len; - if (fd->Read(&len, sizeof(len)) != sizeof(len)) { - LOG(ERROR) << "Short read: " << fd->StrError(); - callback_(false, std::move(data_)); - return false; - } - - if (len > 0) { - data_.resize(len); - int32_t got = 0; - // Virtio sends data in 32k packets. We may have to do a few reads. - while (got < len) { - auto packetsize = fd->Read(&data_[got], len - got); - got += packetsize; - - if (fd->GetErrno() != 0) { - // This could, technically, also be a disconnect. - LOG(ERROR) << "Read failed: " << fd->StrError(); - return false; - } else if (packetsize == 0) { - LOG(ERROR) << "Short read; remote end disconnected."; - return false; - } - } - } - } - - callback_(true, std::move(data_)); - return true; -} -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.h b/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.h deleted file mode 100644 index 3c4b64f6..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> -#include <stdint.h> - -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" -#include "host/commands/virtual_usb_manager/usbip/device.h" - -namespace vadb { -// Execute control transfer. -class USBCmdDataTransfer : public USBCommand { - public: - USBCmdDataTransfer(uint8_t bus_id, uint8_t dev_id, uint8_t endpoint, - bool is_host_to_device, uint32_t timeout, - std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback); - - ~USBCmdDataTransfer() override = default; - - // Return usbforward command this instance is executing. - usb_forward::Command Command() override { - return usb_forward::CmdDataTransfer; - } - - // Send request body to the server. - // Return false, if communication failed. - bool OnRequest(const cvd::SharedFD& data) override; - - // Receive response data from the server. - // Return false, if communication failed. - bool OnResponse(bool is_success, const cvd::SharedFD& data) override; - - private: - usb_forward::DataTransfer req_; - std::vector<uint8_t> data_; - usbip::Device::AsyncTransferReadyCB callback_; - - USBCmdDataTransfer(const USBCmdDataTransfer& other) = delete; - USBCmdDataTransfer& operator=(const USBCmdDataTransfer& other) = delete; -}; -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.cpp b/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.cpp deleted file mode 100644 index b74efdd0..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <glog/logging.h> - -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.h" - -namespace vadb { -bool USBCmdDeviceList::OnRequest(const cvd::SharedFD& /*data*/) { - LOG(INFO) << "Requesting device list from Cuttlefish..."; - // No action required. - return true; -} - -bool USBCmdDeviceList::OnResponse(bool is_success, const cvd::SharedFD& fd) { - // This should never happen. If this command fails, something is very wrong. - if (!is_success) return false; - - int32_t count; - if (fd->Read(&count, sizeof(count)) != sizeof(count)) { - LOG(ERROR) << "Short read: " << fd->StrError(); - return false; - } - - LOG(INFO) << "Device list completed with " << count << " devices."; - - while (count-- > 0) { - usb_forward::DeviceInfo dev; - std::vector<usb_forward::InterfaceInfo> ifaces; - - if (fd->Read(&dev, sizeof(dev)) != sizeof(dev)) { - LOG(ERROR) << "Short read: " << fd->StrError(); - return false; - } - - ifaces.resize(dev.num_interfaces); - if (static_cast<size_t>( - fd->Read(ifaces.data(), - ifaces.size() * sizeof(usb_forward::InterfaceInfo))) != - ifaces.size() * sizeof(usb_forward::InterfaceInfo)) { - LOG(ERROR) << "Short read: " << fd->StrError(); - return false; - } - - LOG(INFO) << "Found remote device 0x" << std::hex << dev.vendor_id << ":" - << dev.product_id; - - on_device_discovered_(dev, ifaces); - } - - return true; -} -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.h b/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.h deleted file mode 100644 index 4d9ebbc9..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <functional> -#include <vector> -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" - -namespace vadb { -// Request device list from remote host. -class USBCmdDeviceList : public USBCommand { - public: - // DeviceDiscoveredCB is a callback function invoked for every new discovered - // device. - using DeviceDiscoveredCB = - std::function<void(const usb_forward::DeviceInfo&, - const std::vector<usb_forward::InterfaceInfo>&)>; - - USBCmdDeviceList(DeviceDiscoveredCB cb) - : on_device_discovered_(std::move(cb)) {} - - ~USBCmdDeviceList() override = default; - - // Return usbforward command this instance is executing. - usb_forward::Command Command() override { return usb_forward::CmdDeviceList; } - - // Send request body to the server. - // Return false, if communication failed. - bool OnRequest(const cvd::SharedFD& data) override; - - // Receive response data from the server. - // Return false, if communication failed. - bool OnResponse(bool is_success, const cvd::SharedFD& data) override; - - private: - DeviceDiscoveredCB on_device_discovered_; - USBCmdDeviceList(const USBCmdDeviceList& other) = delete; - USBCmdDeviceList& operator=(const USBCmdDeviceList& other) = delete; -}; -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.cpp b/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.cpp deleted file mode 100644 index cc80caa1..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <glog/logging.h> - -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.h" - -namespace vadb { -bool USBCmdHeartbeat::OnRequest(const cvd::SharedFD& /*fd*/) { return true; } - -bool USBCmdHeartbeat::OnResponse(bool is_success, - const cvd::SharedFD& /*data*/) { - callback_(is_success); - return true; -} - -USBCmdHeartbeat::USBCmdHeartbeat(USBCmdHeartbeat::HeartbeatResultCB callback) - : callback_(callback) {} -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.h b/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.h deleted file mode 100644 index 552165b1..00000000 --- a/host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" - -namespace vadb { -// Request remote device attach (~open). -class USBCmdHeartbeat : public USBCommand { - public: - // Heartbeat result callback receives a boolean argument indicating whether - // remote device is ready to be attached. - using HeartbeatResultCB = std::function<void(bool)>; - - USBCmdHeartbeat(HeartbeatResultCB callback); - ~USBCmdHeartbeat() override = default; - - // Return usbforward command this instance is executing. - usb_forward::Command Command() override { return usb_forward::CmdHeartbeat; } - - // Send request body to the server. - // Return false, if communication failed. - bool OnRequest(const cvd::SharedFD& data) override; - - // Receive response data from the server. - // Return false, if communication failed. - bool OnResponse(bool is_success, const cvd::SharedFD& data) override; - - private: - HeartbeatResultCB callback_; - - USBCmdHeartbeat(const USBCmdHeartbeat& other) = delete; - USBCmdHeartbeat& operator=(const USBCmdHeartbeat& other) = delete; -}; -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/virtual_adb_client.cpp b/host/commands/virtual_usb_manager/vadb/virtual_adb_client.cpp deleted file mode 100644 index 34ee5b44..00000000 --- a/host/commands/virtual_usb_manager/vadb/virtual_adb_client.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <algorithm> -#include <memory> -#include <gflags/gflags.h> - -#include "common/libs/fs/shared_select.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_attach.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_control_transfer.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_data_transfer.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_device_list.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd_heartbeat.h" -#include "host/commands/virtual_usb_manager/vadb/virtual_adb_client.h" - -DEFINE_bool(debug_adb_client, false, "Turn on verbose logging in the virtual_adb_client.cpp"); - -#define VLOG(X) if (FLAGS_debug_adb_client) LOG(VERBOSE) - -namespace vadb { -namespace { -constexpr int kHeartbeatTimeoutSeconds = 3; -} // namespace - -VirtualADBClient::VirtualADBClient(usbip::DevicePool* pool, cvd::SharedFD fd, - int vhci_port, - const std::string& usbip_socket_name) - : pool_{pool}, fd_{fd}, vhci_{vhci_port, usbip_socket_name} { - CHECK(vhci_.Init()); - timer_ = cvd::SharedFD::TimerFD(CLOCK_MONOTONIC, 0); - SendHeartbeat(); -} - -void VirtualADBClient::RegisterDevice( - const usb_forward::DeviceInfo& dev, - const std::vector<usb_forward::InterfaceInfo>& ifaces) { - auto d = std::unique_ptr<usbip::Device>(new usbip::Device); - d->vendor_id = dev.vendor_id; - d->product_id = dev.product_id; - d->dev_version = dev.dev_version; - d->dev_class = dev.dev_class; - d->dev_subclass = dev.dev_subclass; - d->dev_protocol = dev.dev_protocol; - d->speed = dev.speed; - d->configurations_count = dev.num_configurations; - d->configuration_number = dev.cur_configuration; - - for (const auto& iface : ifaces) { - d->interfaces.push_back(usbip::Device::Interface{ - iface.if_class, iface.if_subclass, iface.if_protocol}); - } - - uint8_t bus_id = dev.bus_id; - uint8_t dev_id = dev.dev_id; - - d->handle_attach = [this, bus_id, dev_id]() -> bool { - return HandleAttach(bus_id, dev_id); - }; - - d->handle_control_transfer = - [this, bus_id, dev_id]( - const usbip::CmdRequest& r, uint32_t deadline, - std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) -> bool { - return HandleDeviceControlRequest(bus_id, dev_id, r, deadline, - std::move(data), std::move(callback)); - }; - - d->handle_data_transfer = - [this, bus_id, dev_id]( - uint8_t endpoint, bool is_host_to_device, uint32_t deadline, - std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) -> bool { - return HandleDeviceDataRequest(bus_id, dev_id, endpoint, is_host_to_device, - deadline, std::move(data), - std::move(callback)); - }; - - pool_->AddDevice(usbip::DevicePool::BusDevNumber{bus_id, dev_id}, - std::move(d)); - - // Attach this device. - HandleAttach(bus_id, dev_id); -} - -bool VirtualADBClient::PopulateRemoteDevices() { - return ExecuteCommand(std::unique_ptr<USBCommand>(new USBCmdDeviceList( - [this](const usb_forward::DeviceInfo& info, - const std::vector<usb_forward::InterfaceInfo>& ifaces) { - RegisterDevice(info, ifaces); - }))); -} - -bool VirtualADBClient::HandleDeviceControlRequest( - uint8_t bus_id, uint8_t dev_id, const usbip::CmdRequest& r, - uint32_t timeout, std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) { - return ExecuteCommand(std::unique_ptr<USBCommand>(new USBCmdControlTransfer( - bus_id, dev_id, r.type, r.cmd, r.value, r.index, timeout, std::move(data), - std::move(callback)))); -} - -bool VirtualADBClient::HandleDeviceDataRequest( - uint8_t bus_id, uint8_t dev_id, uint8_t endpoint, bool is_host_to_device, - uint32_t deadline, std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback) { - return ExecuteCommand(std::unique_ptr<USBCommand>( - new USBCmdDataTransfer(bus_id, dev_id, endpoint, is_host_to_device, - deadline, std::move(data), std::move(callback)))); -} - -bool VirtualADBClient::HandleAttach(uint8_t bus_id, uint8_t dev_id) { - return ExecuteCommand( - std::unique_ptr<USBCommand>(new USBCmdAttach(bus_id, dev_id))); -} - -bool VirtualADBClient::SendHeartbeat() { - VLOG(1) << "Sending heartbeat..."; - struct itimerspec spec {}; - spec.it_value.tv_sec = kHeartbeatTimeoutSeconds; - timer_->TimerSet(0, &spec, nullptr); - - heartbeat_tag_ = tag_; - - return ExecuteCommand(std::unique_ptr<USBCommand>( - new USBCmdHeartbeat([this](bool success) { HandleHeartbeat(success); }))); -} - -void VirtualADBClient::HandleHeartbeat(bool is_ready) { - VLOG(1) << "Remote server status: " << is_ready; - if (is_ready && !is_remote_server_ready_) { - LOG(INFO) << "Remote server is now ready."; - PopulateRemoteDevices(); - vhci_.TriggerAttach(); - } else if (is_remote_server_ready_ && !is_ready) { - vhci_.TriggerDetach(); - LOG(WARNING) << "Remote server connection lost."; - // It makes perfect sense to cancel all outstanding USB requests, as device - // is not going to answer any of these anyway. - for (const auto& pair : commands_) { - pair.second->OnResponse(false, fd_); - } - commands_.clear(); - } - is_remote_server_ready_ = is_ready; -} - -bool VirtualADBClient::HandleHeartbeatTimeout() { - uint64_t timer_result; - timer_->Read(&timer_result, sizeof(timer_result)); - - auto iter = commands_.find(heartbeat_tag_); - if (iter != commands_.end()) { - // Make sure to erase the value from list of commands prior to running - // callback. Particularly important for heartbeat, which cancels all - // outstanding USB commands (including self, if found), if device goes - // away (eg. reboots). - auto command = std::move(iter->second); - commands_.erase(iter); - command->OnResponse(false, fd_); - } - - return SendHeartbeat(); -} - -bool VirtualADBClient::ExecuteCommand(std::unique_ptr<USBCommand> cmd) { - uint32_t this_tag = tag_; - tag_++; - usb_forward::RequestHeader hdr{cmd->Command(), this_tag}; - if (fd_->Write(&hdr, sizeof(hdr)) != sizeof(hdr)) { - LOG(ERROR) << "Could not contact USB Forwarder: " << fd_->StrError(); - return false; - } - - if (!cmd->OnRequest(fd_)) return false; - - commands_[this_tag] = std::move(cmd); - return true; -} - -// BeforeSelect is Called right before Select() to populate interesting -// SharedFDs. -void VirtualADBClient::BeforeSelect(cvd::SharedFDSet* fd_read) const { - fd_read->Set(fd_); - fd_read->Set(timer_); -} - -// AfterSelect is Called right after Select() to detect and respond to changes -// on affected SharedFDs. -// Return value indicates whether this client is still valid. -bool VirtualADBClient::AfterSelect(const cvd::SharedFDSet& fd_read) { - if (fd_read.IsSet(timer_)) { - HandleHeartbeatTimeout(); - } - if (fd_read.IsSet(fd_)) { - usb_forward::ResponseHeader rhdr; - if (fd_->Read(&rhdr, sizeof(rhdr)) != sizeof(rhdr)) { - LOG(ERROR) << "Could not read from USB Forwarder: " << fd_->StrError(); - // TODO(ender): it is very likely the connection has been dropped by QEmu. - // Should we cancel all pending commands now? - return false; - } - - auto iter = commands_.find(rhdr.tag); - if (iter == commands_.end()) { - // This is likely a late heartbeat response, but could very well be any of - // the remaining commands. - LOG(INFO) << "Received response for discarded tag " << rhdr.tag; - } else { - // Make sure to erase the value from list of commands prior to running - // callback. Particularly important for heartbeat, which cancels all - // outstanding USB commands (including self, if found), if device goes - // away (eg. reboots). - auto command = std::move(iter->second); - commands_.erase(iter); - command->OnResponse(rhdr.status == usb_forward::StatusSuccess, fd_); - } - } - - return true; -} - -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/virtual_adb_client.h b/host/commands/virtual_usb_manager/vadb/virtual_adb_client.h deleted file mode 100644 index 9c503ab5..00000000 --- a/host/commands/virtual_usb_manager/vadb/virtual_adb_client.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/fs/shared_select.h" -#include "common/libs/usbforward/protocol.h" -#include "host/commands/virtual_usb_manager/vadb/usb_cmd.h" -#include "host/commands/virtual_usb_manager/usbip/device.h" -#include "host/commands/virtual_usb_manager/usbip/device_pool.h" -#include "host/commands/virtual_usb_manager/usbip/messages.h" -#include "host/commands/virtual_usb_manager/usbip/vhci_instrument.h" - -namespace vadb { -// VirtualADBClient is a companion class for USBForwarder, running on -// Cuttlefish. VirtualADBClient collects list of available USB devices from -// Cuttlefish and makes them available to USB/IP. -// -// Purpose of this class is to connect to USBForwarder and make access to -// remote USB devices possible with help of USB/IP protocol. -class VirtualADBClient { - public: - VirtualADBClient(usbip::DevicePool* pool, cvd::SharedFD fd, int vhci_port, - const std::string& usbip_socket_name); - - virtual ~VirtualADBClient() = default; - - // Query remote server; populate available USB devices. - bool PopulateRemoteDevices(); - - // BeforeSelect is Called right before Select() to populate interesting - // SharedFDs. - void BeforeSelect(cvd::SharedFDSet* fd_read) const; - - // AfterSelect is Called right after Select() to detect and respond to changes - // on affected SharedFDs. - // Return value indicates whether this client is still valid. - bool AfterSelect(const cvd::SharedFDSet& fd_read); - - private: - // Register new device in a device pool. - void RegisterDevice(const usb_forward::DeviceInfo& dev, - const std::vector<usb_forward::InterfaceInfo>& ifaces); - - // Request attach remote USB device. - bool HandleAttach(uint8_t bus_id, uint8_t dev_id); - - // Execute control request on remote device. - bool HandleDeviceControlRequest(uint8_t bus_id, uint8_t dev_id, - const usbip::CmdRequest& r, uint32_t deadline, - std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback); - - // Execute data request on remote device. - bool HandleDeviceDataRequest(uint8_t bus_id, uint8_t dev_id, uint8_t endpoint, - bool is_host_to_device, uint32_t deadline, - std::vector<uint8_t> data, - usbip::Device::AsyncTransferReadyCB callback); - - // Send new heartbeat request and arm the heartbeat timer. - bool SendHeartbeat(); - - // Heartbeat handler receives response to heartbeat request. - // Supplied argument indicates, whether remote server is ready to export USB - // gadget. - void HandleHeartbeat(bool is_ready); - - // Heartbeat timeout detects situation where heartbeat did not receive - // matching response. This could be a direct result of device reset. - bool HandleHeartbeatTimeout(); - - // ExecuteCommand creates command header and executes supplied USBCommand. - // If execution was successful, command will be stored internally until - // response arrives. - bool ExecuteCommand(std::unique_ptr<USBCommand> cmd); - - usbip::DevicePool* pool_; - cvd::SharedFD fd_; - cvd::SharedFD timer_; - usbip::VHCIInstrument vhci_; - bool is_remote_server_ready_ = false; - - uint32_t tag_ = 0; - // Assign an 'invalid' tag as previously sent heartbeat command. This will - // prevent heartbeat timeout handler from finding a command if none was sent. - uint32_t heartbeat_tag_ = ~0; - std::map<uint32_t, std::unique_ptr<USBCommand>> commands_; - - VirtualADBClient(const VirtualADBClient& other) = delete; - VirtualADBClient& operator=(const VirtualADBClient& other) = delete; -}; - -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/virtual_adb_server.cpp b/host/commands/virtual_usb_manager/vadb/virtual_adb_server.cpp deleted file mode 100644 index 43dae759..00000000 --- a/host/commands/virtual_usb_manager/vadb/virtual_adb_server.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/commands/virtual_usb_manager/vadb/virtual_adb_server.h" - -namespace vadb { - -void VirtualADBServer::BeforeSelect(cvd::SharedFDSet* fd_read) const { - fd_read->Set(server_); - for (const auto& client : clients_) { - client.BeforeSelect(fd_read); - } -} - -void VirtualADBServer::AfterSelect(const cvd::SharedFDSet& fd_read) { - if (fd_read.IsSet(server_)) HandleIncomingConnection(); - - for (auto iter = clients_.begin(); iter != clients_.end();) { - if (!iter->AfterSelect(fd_read)) { - // If client conversation failed, hang up. - iter = clients_.erase(iter); - continue; - } - ++iter; - } -} - -// Accept new QEmu connection. Add it to client pool. -// Typically we will have no more than one QEmu connection, but the nature -// of server requires proper handling nonetheless. -void VirtualADBServer::HandleIncomingConnection() { - cvd::SharedFD client = cvd::SharedFD::Accept(*server_, nullptr, nullptr); - if (!client->IsOpen()) { - LOG(ERROR) << "Client connection failed: " << client->StrError(); - return; - } - - clients_.emplace_back(&pool_, client, vhci_port_, usbip_name_); -} - -} // namespace vadb diff --git a/host/commands/virtual_usb_manager/vadb/virtual_adb_server.h b/host/commands/virtual_usb_manager/vadb/virtual_adb_server.h deleted file mode 100644 index d4aaf792..00000000 --- a/host/commands/virtual_usb_manager/vadb/virtual_adb_server.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <list> -#include <string> - -#include "common/libs/fs/shared_fd.h" -#include "host/commands/virtual_usb_manager/usbip/device_pool.h" -#include "host/commands/virtual_usb_manager/vadb/virtual_adb_client.h" - -namespace vadb { -// VirtualADBServer manages incoming VirtualUSB/ADB connections from QEmu. -class VirtualADBServer { - public: - VirtualADBServer(cvd::SharedFD usb_v1_socket, int vhci_port, - const std::string& usbip_socket_name) - : vhci_port_{vhci_port}, - usbip_name_(usbip_socket_name), - server_(usb_v1_socket) {} - - ~VirtualADBServer() = default; - - // Pool of USB devices available to export. - const usbip::DevicePool& Pool() const { return pool_; }; - - // BeforeSelect is Called right before Select() to populate interesting - // SharedFDs. - void BeforeSelect(cvd::SharedFDSet* fd_read) const; - - // AfterSelect is Called right after Select() to detect and respond to changes - // on affected SharedFDs. - void AfterSelect(const cvd::SharedFDSet& fd_read); - - private: - void HandleIncomingConnection(); - - usbip::DevicePool pool_; - int vhci_port_{}; - std::string usbip_name_; - cvd::SharedFD server_; - std::list<VirtualADBClient> clients_; - - VirtualADBServer(const VirtualADBServer&) = delete; - VirtualADBServer& operator=(const VirtualADBServer&) = delete; -}; - -} // namespace vadb diff --git a/host/frontend/Android.bp b/host/frontend/Android.bp deleted file mode 100644 index 8d78a9f2..00000000 --- a/host/frontend/Android.bp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "vnc_server", - "adb_connector", -] diff --git a/host/frontend/adb_connector/Android.bp b/host/frontend/adb_connector/Android.bp deleted file mode 100644 index 41fa1f65..00000000 --- a/host/frontend/adb_connector/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_binary_host { - name: "adb_connector", - srcs: [ - "main.cpp" - ], - header_libs: [ - "cuttlefish_glog", - ], - static_libs: [ - "libadb_connection_maintainer", - "libgflags", - ], - shared_libs: [ - "libbase", - "libcuttlefish_fs", - "liblog", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/frontend/adb_connector/main.cpp b/host/frontend/adb_connector/main.cpp deleted file mode 100644 index 3d3d824f..00000000 --- a/host/frontend/adb_connector/main.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> -#include <iterator> -#include <limits> -#include <sstream> -#include <thread> -#include <vector> - -#include <glog/logging.h> -#include <gflags/gflags.h> - -#include <unistd.h> -#include <host/commands/kernel_log_monitor/kernel_log_server.h> - -#include "common/libs/fs/shared_fd.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h" - -DEFINE_string(addresses, "", "Comma-separated list of addresses to " - "'adb connect' to"); -DEFINE_int32(adbd_events_fd, -1, "A file descriptor. If set it will wait for " - "AdbdStarted boot event from the kernel log " - "monitor before trying to connect adb"); - -namespace { -void LaunchConnectionMaintainerThread(const std::string& address) { - std::thread(cvd::EstablishAndMaintainConnection, address).detach(); -} - -std::vector<std::string> ParseAddressList(std::string ports) { - std::replace(ports.begin(), ports.end(), ',', ' '); - std::istringstream port_stream{ports}; - return {std::istream_iterator<std::string>{port_stream}, - std::istream_iterator<std::string>{}}; -} - -[[noreturn]] void SleepForever() { - while (true) { - sleep(std::numeric_limits<unsigned int>::max()); - } -} - -void WaitForAdbdToBeStarted(int events_fd) { - auto evt_shared_fd = cvd::SharedFD::Dup(events_fd); - close(events_fd); - while (evt_shared_fd->IsOpen()) { - monitor::BootEvent event; - auto bytes_read = evt_shared_fd->Read(&event, sizeof(event)); - if (bytes_read != sizeof(event)) { - LOG(ERROR) << "Fail to read a complete event, read " << bytes_read - << " bytes only instead of the expected " << sizeof(event); - // The file descriptor can't be trusted anymore, stop waiting and try to - // connect - return; - } - if (event == monitor::BootEvent::AdbdStarted) { - LOG(INFO) << "Adbd has started in the guest, connecting adb"; - return; - } - } -} -} // namespace - -int main(int argc, char* argv[]) { - gflags::ParseCommandLineFlags(&argc, &argv, true); - CHECK(!FLAGS_addresses.empty()) << "Must specify --addresses flag"; - - if (FLAGS_adbd_events_fd >= 0) { - WaitForAdbdToBeStarted(FLAGS_adbd_events_fd); - } - - for (auto address : ParseAddressList(FLAGS_addresses)) { - LaunchConnectionMaintainerThread(address); - } - - SleepForever(); -} diff --git a/host/frontend/vnc_server/Android.bp b/host/frontend/vnc_server/Android.bp deleted file mode 100644 index 0e82b2f0..00000000 --- a/host/frontend/vnc_server/Android.bp +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_binary_host { - name: "vnc_server", - srcs: [ - "blackboard.cpp", - "frame_buffer_watcher.cpp", - "jpeg_compressor.cpp", - "main.cpp", - "screen_connector.cpp", - "simulated_hw_composer.cpp", - "virtual_inputs.cpp", - "vnc_client_connection.cpp", - "vnc_server.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "cuttlefish_tcp_socket", - "libbase", - ], - static_libs: [ - "libcuttlefish_host_config", - "libjsoncpp", - "libjpeg", - "libgflags", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/frontend/vnc_server/blackboard.cpp b/host/frontend/vnc_server/blackboard.cpp deleted file mode 100644 index b8426486..00000000 --- a/host/frontend/vnc_server/blackboard.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/blackboard.h" - -#include <algorithm> -#include <utility> - -#include <gflags/gflags.h> -#include <glog/logging.h> -#include "host/frontend/vnc_server/frame_buffer_watcher.h" - -DEFINE_bool(debug_blackboard, false, - "Turn on detailed logging for the blackboard"); - -#define DLOG(LEVEL) \ - if (FLAGS_debug_blackboard) LOG(LEVEL) - -using cvd::vnc::BlackBoard; -using cvd::vnc::Stripe; - -cvd::vnc::SeqNumberVec cvd::vnc::MakeSeqNumberVec() { - return SeqNumberVec(FrameBufferWatcher::StripesPerFrame()); -} - -void BlackBoard::NewStripeReady(int index, StripeSeqNumber seq_num) { - std::lock_guard<std::mutex> guard(m_); - DLOG(INFO) << "new stripe arrived from frame watcher"; - auto& current_seq_num = most_recent_stripe_seq_nums_[index]; - current_seq_num = std::max(current_seq_num, seq_num); - for (auto& client : clients_) { - if (client.second.ready_to_receive) { - client.second.new_frame_cv.notify_one(); - } - } -} - -void BlackBoard::Register(const VncClientConnection* conn) { - { - std::lock_guard<std::mutex> guard(m_); - CHECK(!clients_.count(conn)); - clients_[conn]; // constructs new state in place - } - new_client_cv_.notify_one(); -} - -void BlackBoard::Unregister(const VncClientConnection* conn) { - std::lock_guard<std::mutex> guard(m_); - CHECK(clients_.count(conn)); - clients_.erase(clients_.find(conn)); -} - -bool BlackBoard::NoNewStripesFor(const SeqNumberVec& seq_nums) const { - CHECK(seq_nums.size() == most_recent_stripe_seq_nums_.size()); - for (auto state_seq_num = seq_nums.begin(), - held_seq_num = most_recent_stripe_seq_nums_.begin(); - state_seq_num != seq_nums.end(); ++state_seq_num, ++held_seq_num) { - if (*state_seq_num < *held_seq_num) { - return false; - } - } - return true; -} - -cvd::vnc::StripePtrVec BlackBoard::WaitForSenderWork( - const VncClientConnection* conn) { - std::unique_lock<std::mutex> guard(m_); - auto& state = GetStateForClient(conn); - DLOG(INFO) << "Waiting for stripe..."; - while (!state.closed && - (!state.ready_to_receive || NoNewStripesFor(state.stripe_seq_nums))) { - state.new_frame_cv.wait(guard); - } - DLOG(INFO) << "At least one new stripe is available, should unblock " << conn; - state.ready_to_receive = false; - auto new_stripes = frame_buffer_watcher_->StripesNewerThan( - state.orientation, state.stripe_seq_nums); - for (auto& s : new_stripes) { - state.stripe_seq_nums[s->index] = s->seq_number; - } - return new_stripes; -} - -void BlackBoard::WaitForAtLeastOneClientConnection() { - std::unique_lock<std::mutex> guard(m_); - while (clients_.empty()) { - new_client_cv_.wait(guard); - } -} - -void BlackBoard::SetOrientation(const VncClientConnection* conn, - ScreenOrientation orientation) { - std::lock_guard<std::mutex> guard(m_); - auto& state = GetStateForClient(conn); - state.orientation = orientation; - // After an orientation change the vnc client will need all stripes from - // the new orientation, regardless of age. - ResetToZero(&state.stripe_seq_nums); -} - -void BlackBoard::SignalClientNeedsEntireScreen( - const VncClientConnection* conn) { - std::lock_guard<std::mutex> guard(m_); - ResetToZero(&GetStateForClient(conn).stripe_seq_nums); -} - -void BlackBoard::ResetToZero(SeqNumberVec* seq_nums) { - seq_nums->assign(FrameBufferWatcher::StripesPerFrame(), StripeSeqNumber{}); -} - -void BlackBoard::FrameBufferUpdateRequestReceived( - const VncClientConnection* conn) { - std::lock_guard<std::mutex> guard(m_); - DLOG(INFO) << "Received frame buffer update request"; - auto& state = GetStateForClient(conn); - state.ready_to_receive = true; - state.new_frame_cv.notify_one(); -} - -void BlackBoard::StopWaiting(const VncClientConnection* conn) { - std::lock_guard<std::mutex> guard(m_); - auto& state = GetStateForClient(conn); - state.closed = true; - // Wake up the thread that might be in WaitForSenderWork() - state.new_frame_cv.notify_one(); -} - -void BlackBoard::set_frame_buffer_watcher( - cvd::vnc::FrameBufferWatcher* frame_buffer_watcher) { - std::lock_guard<std::mutex> guard(m_); - frame_buffer_watcher_ = frame_buffer_watcher; -} - -void BlackBoard::set_jpeg_quality_level(int quality_level) { - // NOTE all vnc clients share a common jpeg quality level because the - // server doesn't compress per-client. The quality level for all clients - // will be whatever the most recent set was by any client. - std::lock_guard<std::mutex> guard(m_); - if (quality_level < kJpegMinQualityEncoding || - quality_level > kJpegMaxQualityEncoding) { - LOG(WARNING) << "Bogus jpeg quality level: " << quality_level - << ". Quality must be in range [" << kJpegMinQualityEncoding - << ", " << kJpegMaxQualityEncoding << "]"; - return; - } - jpeg_quality_level_ = 55 + (5 * (quality_level + 32)); - DLOG(INFO) << "jpeg quality level set to " << jpeg_quality_level_ << "%"; -} - -BlackBoard::ClientFBUState& BlackBoard::GetStateForClient( - const VncClientConnection* conn) { - CHECK(clients_.count(conn)); - return clients_[conn]; -} diff --git a/host/frontend/vnc_server/blackboard.h b/host/frontend/vnc_server/blackboard.h deleted file mode 100644 index 1119dd3c..00000000 --- a/host/frontend/vnc_server/blackboard.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include <condition_variable> -#include <memory> -#include <mutex> -#include <unordered_map> - -#include "common/libs/threads/thread_annotations.h" -#include "host/frontend/vnc_server/vnc_utils.h" - -namespace cvd { -namespace vnc { - -class VncClientConnection; -class FrameBufferWatcher; -using StripePtrVec = std::vector<std::shared_ptr<const Stripe>>; -using SeqNumberVec = std::vector<StripeSeqNumber>; - -SeqNumberVec MakeSeqNumberVec(); - -class BlackBoard { - private: - struct ClientFBUState { - bool ready_to_receive{}; - ScreenOrientation orientation{}; - std::condition_variable new_frame_cv; - SeqNumberVec stripe_seq_nums = MakeSeqNumberVec(); - bool closed{}; - }; - - public: - class Registerer { - public: - Registerer(BlackBoard* bb, const VncClientConnection* conn) - : bb_{bb}, conn_{conn} { - bb->Register(conn); - } - ~Registerer() { bb_->Unregister(conn_); } - Registerer(const Registerer&) = delete; - Registerer& operator=(const Registerer&) = delete; - - private: - BlackBoard* bb_{}; - const VncClientConnection* conn_{}; - }; - - BlackBoard() = default; - BlackBoard(const BlackBoard&) = delete; - BlackBoard& operator=(const BlackBoard&) = delete; - - bool NoNewStripesFor(const SeqNumberVec& seq_nums) const REQUIRES(m_); - void NewStripeReady(int index, StripeSeqNumber seq_num); - void Register(const VncClientConnection* conn); - void Unregister(const VncClientConnection* conn); - - StripePtrVec WaitForSenderWork(const VncClientConnection* conn); - - void WaitForAtLeastOneClientConnection(); - - void FrameBufferUpdateRequestReceived(const VncClientConnection* conn); - // Setting orientation implies needing the entire screen - void SetOrientation(const VncClientConnection* conn, - ScreenOrientation orientation); - void SignalClientNeedsEntireScreen(const VncClientConnection* conn); - - void StopWaiting(const VncClientConnection* conn); - - void set_frame_buffer_watcher(FrameBufferWatcher* frame_buffer_watcher); - - // quality_level must be the value received from the client, in the range - // [kJpegMinQualityEncoding, kJpegMaxQualityEncoding], else it is ignored. - void set_jpeg_quality_level(int quality_level); - - int jpeg_quality_level() const { - std::lock_guard<std::mutex> guard(m_); - return jpeg_quality_level_; - } - - private: - ClientFBUState& GetStateForClient(const VncClientConnection* conn) - REQUIRES(m_); - static void ResetToZero(SeqNumberVec* seq_nums); - - mutable std::mutex m_; - SeqNumberVec most_recent_stripe_seq_nums_ GUARDED_BY(m_) = MakeSeqNumberVec(); - std::unordered_map<const VncClientConnection*, ClientFBUState> clients_ - GUARDED_BY(m_); - int jpeg_quality_level_ GUARDED_BY(m_) = 100; - std::condition_variable new_client_cv_; - // NOTE the FrameBufferWatcher pointer itself should be - // guarded, but not the pointee. - FrameBufferWatcher* frame_buffer_watcher_ GUARDED_BY(m_){}; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/frame_buffer_watcher.cpp b/host/frontend/vnc_server/frame_buffer_watcher.cpp deleted file mode 100644 index 592b88e0..00000000 --- a/host/frontend/vnc_server/frame_buffer_watcher.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/frame_buffer_watcher.h" - -#include <algorithm> -#include <cstdint> -#include <cstring> -#include <iterator> -#include <memory> -#include <mutex> -#include <thread> -#include <utility> - -#include <glog/logging.h> -#include "host/frontend/vnc_server/vnc_utils.h" - -using cvd::vnc::FrameBufferWatcher; - -FrameBufferWatcher::FrameBufferWatcher(BlackBoard* bb) - : bb_{bb}, hwcomposer{bb_} { - for (auto& stripes_vec : stripes_) { - std::generate_n(std::back_inserter(stripes_vec), - SimulatedHWComposer::NumberOfStripes(), - std::make_shared<Stripe>); - } - bb_->set_frame_buffer_watcher(this); - auto num_workers = std::max(std::thread::hardware_concurrency(), 1u); - std::generate_n(std::back_inserter(workers_), num_workers, [this] { - return std::thread{&FrameBufferWatcher::Worker, this}; - }); -} - -FrameBufferWatcher::~FrameBufferWatcher() { - { - std::lock_guard<std::mutex> guard(m_); - closed_ = true; - } - for (auto& tid : workers_) { - tid.join(); - } -} - -bool FrameBufferWatcher::closed() const { - std::lock_guard<std::mutex> guard(m_); - return closed_; -} - -cvd::vnc::Stripe FrameBufferWatcher::Rotated(Stripe stripe) { - if (stripe.orientation == ScreenOrientation::Landscape) { - LOG(FATAL) << "Rotating a landscape stripe, this is a mistake"; - } - auto w = stripe.width; - auto s = stripe.stride; - auto h = stripe.height; - const auto& raw = stripe.raw_data; - Message rotated(raw.size(), 0xAA); - for (std::uint16_t i = 0; i < w; ++i) { - for (std::uint16_t j = 0; j < h; ++j) { - size_t to = (i * h + j) * BytesPerPixel(); - size_t from = (w - (i + 1)) * BytesPerPixel() + s * j; - CHECK(from < raw.size()); - CHECK(to < rotated.size()); - std::memcpy(&rotated[to], &raw[from], BytesPerPixel()); - } - } - std::swap(stripe.x, stripe.y); - std::swap(stripe.width, stripe.height); - // The new stride after rotating is the height, as it is not aligned again. - stripe.stride = stripe.width * BytesPerPixel(); - stripe.raw_data = std::move(rotated); - stripe.orientation = ScreenOrientation::Landscape; - return stripe; -} - -bool FrameBufferWatcher::StripeIsDifferentFromPrevious( - const Stripe& stripe) const { - return Stripes(stripe.orientation)[stripe.index]->raw_data != stripe.raw_data; -} - -cvd::vnc::StripePtrVec FrameBufferWatcher::StripesNewerThan( - ScreenOrientation orientation, const SeqNumberVec& seq_numbers) const { - std::lock_guard<std::mutex> guard(stripes_lock_); - const auto& stripes = Stripes(orientation); - CHECK(seq_numbers.size() == stripes.size()); - StripePtrVec new_stripes; - auto seq_number_it = seq_numbers.begin(); - std::copy_if(stripes.begin(), stripes.end(), std::back_inserter(new_stripes), - [seq_number_it](const StripePtrVec::value_type& s) mutable { - return *(seq_number_it++) < s->seq_number; - }); - return new_stripes; -} - -cvd::vnc::StripePtrVec& FrameBufferWatcher::Stripes( - ScreenOrientation orientation) { - return stripes_[static_cast<int>(orientation)]; -} - -const cvd::vnc::StripePtrVec& FrameBufferWatcher::Stripes( - ScreenOrientation orientation) const { - return stripes_[static_cast<int>(orientation)]; -} - -bool FrameBufferWatcher::UpdateMostRecentSeqNumIfStripeIsNew( - const Stripe& stripe) { - if (most_recent_identical_stripe_seq_nums_[stripe.index] <= - stripe.seq_number) { - most_recent_identical_stripe_seq_nums_[stripe.index] = stripe.seq_number; - return true; - } - return false; -} - -bool FrameBufferWatcher::UpdateStripeIfStripeIsNew( - const std::shared_ptr<const Stripe>& stripe) { - std::lock_guard<std::mutex> guard(stripes_lock_); - if (UpdateMostRecentSeqNumIfStripeIsNew(*stripe)) { - Stripes(stripe->orientation)[stripe->index] = stripe; - return true; - } - return false; -} - -void FrameBufferWatcher::CompressStripe(JpegCompressor* jpeg_compressor, - Stripe* stripe) { - stripe->jpeg_data = jpeg_compressor->Compress( - stripe->raw_data, bb_->jpeg_quality_level(), 0, 0, stripe->width, - stripe->height, stripe->stride); -} - -void FrameBufferWatcher::Worker() { - JpegCompressor jpeg_compressor; -#ifdef FUZZ_TEST_VNC - std::default_random_engine e{std::random_device{}()}; - std::uniform_int_distribution<int> random{0, 2}; -#endif - while (!closed()) { - auto portrait_stripe = hwcomposer.GetNewStripe(); - if (closed()) { - break; - } - { - // TODO(haining) use if (with init) and else for c++17 instead of extra - // scope and continue - // if (std::lock_guard guard(stripes_lock_); /*condition*/) { } - std::lock_guard<std::mutex> guard(stripes_lock_); - if (!StripeIsDifferentFromPrevious(portrait_stripe)) { - UpdateMostRecentSeqNumIfStripeIsNew(portrait_stripe); - continue; - } - } - auto seq_num = portrait_stripe.seq_number; - auto index = portrait_stripe.index; - auto landscape_stripe = Rotated(portrait_stripe); - auto stripes = {std::make_shared<Stripe>(std::move(portrait_stripe)), - std::make_shared<Stripe>(std::move(landscape_stripe))}; - for (auto& stripe : stripes) { -#ifdef FUZZ_TEST_VNC - if (random(e)) { - usleep(10000); - } -#endif - CompressStripe(&jpeg_compressor, stripe.get()); - } - bool any_new_stripes = false; - for (auto& stripe : stripes) { - any_new_stripes = UpdateStripeIfStripeIsNew(stripe) || any_new_stripes; - } - if (any_new_stripes) { - bb_->NewStripeReady(index, seq_num); - } - } -} - -int FrameBufferWatcher::StripesPerFrame() { - return SimulatedHWComposer::NumberOfStripes(); -} diff --git a/host/frontend/vnc_server/frame_buffer_watcher.h b/host/frontend/vnc_server/frame_buffer_watcher.h deleted file mode 100644 index 40ab2705..00000000 --- a/host/frontend/vnc_server/frame_buffer_watcher.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <memory> -#include <mutex> -#include <thread> -#include <utility> -#include <vector> - -#include "common/libs/threads/thread_annotations.h" -#include "host/frontend/vnc_server/blackboard.h" -#include "host/frontend/vnc_server/jpeg_compressor.h" -#include "host/frontend/vnc_server/simulated_hw_composer.h" - -namespace cvd { -namespace vnc { -class FrameBufferWatcher { - public: - explicit FrameBufferWatcher(BlackBoard* bb); - FrameBufferWatcher(const FrameBufferWatcher&) = delete; - FrameBufferWatcher& operator=(const FrameBufferWatcher&) = delete; - ~FrameBufferWatcher(); - - StripePtrVec StripesNewerThan(ScreenOrientation orientation, - const SeqNumberVec& seq_num) const; - static int StripesPerFrame(); - - private: - static Stripe Rotated(Stripe stripe); - - bool closed() const; - bool StripeIsDifferentFromPrevious(const Stripe& stripe) const - REQUIRES(stripes_lock_); - // returns true if stripe is still considered new and seq number was updated - bool UpdateMostRecentSeqNumIfStripeIsNew(const Stripe& stripe) - REQUIRES(stripes_lock_); - // returns true if stripe is still considered new and was updated - bool UpdateStripeIfStripeIsNew(const std::shared_ptr<const Stripe>& stripe) - EXCLUDES(stripes_lock_); - // Compresses stripe->raw_data to stripe->jpeg_data - void CompressStripe(JpegCompressor* jpeg_compressor, Stripe* stripe); - void Worker(); - void Updater(); - - StripePtrVec& Stripes(ScreenOrientation orientation) REQUIRES(stripes_lock_); - const StripePtrVec& Stripes(ScreenOrientation orientation) const - REQUIRES(stripes_lock_); - - std::vector<std::thread> workers_; - mutable std::mutex stripes_lock_; - std::array<StripePtrVec, kNumOrientations> stripes_ GUARDED_BY(stripes_lock_); - SeqNumberVec most_recent_identical_stripe_seq_nums_ - GUARDED_BY(stripes_lock_) = MakeSeqNumberVec(); - mutable std::mutex m_; - bool closed_ GUARDED_BY(m_){}; - BlackBoard* bb_{}; - SimulatedHWComposer hwcomposer{bb_}; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/jpeg_compressor.cpp b/host/frontend/vnc_server/jpeg_compressor.cpp deleted file mode 100644 index 2d577073..00000000 --- a/host/frontend/vnc_server/jpeg_compressor.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> // stdio.h must appear before jpeglib.h -#include <jpeglib.h> - -#include <glog/logging.h> -#include "host/frontend/vnc_server/jpeg_compressor.h" -#include "host/frontend/vnc_server/vnc_utils.h" - -using cvd::vnc::JpegCompressor; - -namespace { -void InitCinfo(jpeg_compress_struct* cinfo, jpeg_error_mgr* err, - std::uint16_t width, std::uint16_t height, int jpeg_quality) { - cinfo->err = jpeg_std_error(err); - jpeg_create_compress(cinfo); - - cinfo->image_width = width; - cinfo->image_height = height; - cinfo->input_components = cvd::vnc::BytesPerPixel(); - cinfo->in_color_space = JCS_EXT_RGBX; - - jpeg_set_defaults(cinfo); - jpeg_set_quality(cinfo, jpeg_quality, true); -} -} // namespace - -cvd::Message JpegCompressor::Compress(const Message& frame, - int jpeg_quality, std::uint16_t x, - std::uint16_t y, std::uint16_t width, - std::uint16_t height, - int stride) { - jpeg_compress_struct cinfo{}; - jpeg_error_mgr err{}; - InitCinfo(&cinfo, &err, width, height, jpeg_quality); - - auto* compression_buffer = buffer_.get(); - auto compression_buffer_size = buffer_capacity_; - jpeg_mem_dest(&cinfo, &compression_buffer, &compression_buffer_size); - jpeg_start_compress(&cinfo, true); - - while (cinfo.next_scanline < cinfo.image_height) { - auto row = static_cast<JSAMPROW>(const_cast<std::uint8_t*>( - &frame[(y * stride) + - (cinfo.next_scanline * stride) + - (x * BytesPerPixel())])); - jpeg_write_scanlines(&cinfo, &row, 1); - } - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - - UpdateBuffer(compression_buffer, compression_buffer_size); - return {compression_buffer, compression_buffer + compression_buffer_size}; -} - -void JpegCompressor::UpdateBuffer(std::uint8_t* compression_buffer, - unsigned long compression_buffer_size) { - if (buffer_.get() != compression_buffer) { - buffer_capacity_ = compression_buffer_size; - buffer_.reset(compression_buffer); - } -} diff --git a/host/frontend/vnc_server/jpeg_compressor.h b/host/frontend/vnc_server/jpeg_compressor.h deleted file mode 100644 index ae3af18a..00000000 --- a/host/frontend/vnc_server/jpeg_compressor.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cstdint> -#include <cstdlib> -#include <memory> - -#include "host/frontend/vnc_server/vnc_utils.h" - -namespace cvd { -namespace vnc { - -// libjpeg-turbo with jpeg_mem_dest (using memory as a destination) is funky. -// If you give it a buffer that is big enough it will use it. -// If you give it a buffer that is too small, it will allocate a new buffer -// but will NOT free the buffer you gave it. -// This class keeps track of the capacity of the working buffer, and frees the -// old buffer if libjpeg-turbo silently discards it. -class JpegCompressor { - public: - Message Compress(const Message& frame, int jpeg_quality, std::uint16_t x, - std::uint16_t y, std::uint16_t width, std::uint16_t height, - int screen_width); - - private: - void UpdateBuffer(std::uint8_t* compression_buffer, - unsigned long compression_buffer_size); - struct Freer { - void operator()(void* p) const { std::free(p); } - }; - - std::unique_ptr<std::uint8_t, Freer> buffer_; - unsigned long buffer_capacity_{}; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/keysyms.h b/host/frontend/vnc_server/keysyms.h deleted file mode 100644 index 41ff7c76..00000000 --- a/host/frontend/vnc_server/keysyms.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cstdint> - -namespace cvd { -namespace xk { - -constexpr uint32_t BackSpace = 0xff08, Tab = 0xff09, Return = 0xff0d, - Enter = Return, Escape = 0xff1b, MultiKey = 0xff20, - Insert = 0xff63, Delete = 0xffff, Pause = 0xff13, - Home = 0xff50, End = 0xff57, PageUp = 0xff55, - PageDown = 0xff56, Left = 0xff51, Up = 0xff52, - Right = 0xff53, Down = 0xff54, F1 = 0xffbe, F2 = 0xffbf, - F3 = 0xffc0, F4 = 0xffc1, F5 = 0xffc2, F6 = 0xffc3, - F7 = 0xffc4, F8 = 0xffc5, F9 = 0xffc6, F10 = 0xffc7, - F11 = 0xffc8, F12 = 0xffc9, F13 = 0xffca, F14 = 0xffcb, - F15 = 0xffcc, F16 = 0xffcd, F17 = 0xffce, F18 = 0xffcf, - F19 = 0xffd0, F20 = 0xffd1, F21 = 0xffd2, F22 = 0xffd3, - F23 = 0xffd4, F24 = 0xffd5, ShiftLeft = 0xffe1, - ShiftRight = 0xffe2, ControlLeft = 0xffe3, - ControlRight = 0xffe4, MetaLeft = 0xffe7, MetaRight = 0xffe8, - AltLeft = 0xffe9, AltRight = 0xffea, CapsLock = 0xffe5, - NumLock = 0xff7f, ScrollLock = 0xff14, Keypad0 = 0xffb0, - Keypad1 = 0xffb1, Keypad2 = 0xffb2, Keypad3 = 0xffb3, - Keypad4 = 0xffb4, Keypad5 = 0xffb5, Keypad6 = 0xffb6, - Keypad7 = 0xffb7, Keypad8 = 0xffb8, Keypad9 = 0xffb9, - KeypadMultiply = 0xffaa, KeypadSubtract = 0xffad, - KeypadAdd = 0xffab, KeypadDecimal = 0xffae, - KeypadEnter = 0xff8d, KeypadDivide = 0xffaf, - KeypadEqual = 0xffbd, PlusMinus = 0xb1, SysReq = 0xff15, - LineFeed = 0xff0a, KeypadSeparator = 0xffac, Yen = 0xa5, - Cancel = 0xff69, Undo = 0xff65, Redo = 0xff66, Find = 0xff68, - Print = 0xff61, VolumeDown = 0x1008ff11, Mute = 0x1008ff12, - VolumeUp = 0x1008ff13, Menu = 0xff67, - VNCMenu = 0xffed; // VNC seems to translate MENU to this - -} // namespace xk -} // namespace cvd diff --git a/host/frontend/vnc_server/main.cpp b/host/frontend/vnc_server/main.cpp deleted file mode 100644 index eab7011d..00000000 --- a/host/frontend/vnc_server/main.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> -#include <string> - -#include <gflags/gflags.h> - -#include "common/libs/glog/logging.h" -#include "host/frontend/vnc_server/vnc_server.h" -#include "host/frontend/vnc_server/vnc_utils.h" -#include "host/libs/config/cuttlefish_config.h" - -DEFINE_bool(agressive, false, "Whether to use agressive server"); -DEFINE_int32(port, 6444, "Port where to listen for connections"); - -int main(int argc, char* argv[]) { - using ::android::base::ERROR; - ::android::base::InitLogging(argv, android::base::StderrLogger); - ::gflags::ParseCommandLineFlags(&argc, &argv, true); - cvd::vnc::VncServer vnc_server(FLAGS_port, FLAGS_agressive); - vnc_server.MainLoop(); -} diff --git a/host/frontend/vnc_server/mocks.h b/host/frontend/vnc_server/mocks.h deleted file mode 100644 index e69eb43d..00000000 --- a/host/frontend/vnc_server/mocks.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 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. - */ - -struct GceFrameBuffer { - typedef uint32_t Pixel; - - static const int kRedShift = 0; - static const int kRedBits = 8; - static const int kGreenShift = 8; - static const int kGreenBits = 8; - static const int kBlueShift = 16; - static const int kBlueBits = 8; - static const int kAlphaShift = 24; - static const int kAlphaBits = 8; -}; - -// Sensors -struct gce_sensors_message { - static constexpr const char* const kSensorsHALSocketName = ""; -}; diff --git a/host/frontend/vnc_server/screen_connector.cpp b/host/frontend/vnc_server/screen_connector.cpp deleted file mode 100644 index 35cf22f1..00000000 --- a/host/frontend/vnc_server/screen_connector.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/screen_connector.h" - -#include <atomic> -#include <condition_variable> -#include <thread> - -#include <glog/logging.h> -#include <gflags/gflags.h> - -#include "host/frontend/vnc_server/vnc_utils.h" - -DEFINE_int32(frame_server_fd, -1, ""); - -namespace cvd { -namespace vnc { - -namespace { -// TODO(b/128852363): Substitute with one based on memory shared with the -// wayland mock -class SocketBasedScreenConnector : public ScreenConnector { - public: - SocketBasedScreenConnector() { - screen_server_thread_ = std::thread([this]() { ServerLoop(); }); - } - - int WaitForNewFrameSince(std::uint32_t* seq_num) override { - std::unique_lock<std::mutex> lock(new_frame_mtx_); - while (seq_num_ == *seq_num) { - new_frame_cond_var_.wait(lock); - } - *seq_num = seq_num_; - return newest_buffer_; - } - - void* GetBuffer(int buffer_idx) override { - if (buffer_idx < 0) return nullptr; - buffer_idx %= NUM_BUFFERS_; - return &buffer_[buffer_idx * ScreenSizeInBytes()]; - } - - private: - static constexpr int NUM_BUFFERS_ = 4; - - void ServerLoop() { - if (FLAGS_frame_server_fd < 0) { - LOG(FATAL) << "Invalid file descriptor: " << FLAGS_frame_server_fd; - return; - } - auto server = SharedFD::Dup(FLAGS_frame_server_fd); - close(FLAGS_frame_server_fd); - if (!server->IsOpen()) { - LOG(FATAL) << "Unable to dup screen server: " << server->StrError(); - return; - } - - int current_buffer = 0; - - while (1) { - LOG(INFO) << "Screen Connector accepting connections..."; - auto conn = SharedFD::Accept(*server); - if (!conn->IsOpen()) { - LOG(ERROR) << "Disconnected fd returned from accept"; - continue; - } - while (conn->IsOpen()) { - int32_t size = 0; - if (conn->Read(&size, sizeof(size)) < 0) { - LOG(ERROR) << "Failed to read from hwcomposer: " - << conn->StrError(); - break; - } - auto buff = reinterpret_cast<uint8_t*>(GetBuffer(current_buffer)); - while (size > 0) { - auto read = conn->Read(buff, size); - if (read < 0) { - LOG(ERROR) << "Failed to read from hwcomposer: " - << conn->StrError(); - conn->Close(); - break; - } - size -= read; - buff += read; - } - BroadcastNewFrame(current_buffer); - current_buffer = (current_buffer + 1) % NUM_BUFFERS_; - } - } - } - - void BroadcastNewFrame(int buffer_idx) { - { - std::lock_guard<std::mutex> lock(new_frame_mtx_); - seq_num_++; - newest_buffer_ = buffer_idx; - } - new_frame_cond_var_.notify_all(); - } - - std::vector<std::uint8_t> buffer_ = - std::vector<std::uint8_t>(NUM_BUFFERS_ * ScreenSizeInBytes()); - std::uint32_t seq_num_{0}; - int newest_buffer_ = 0; - std::condition_variable new_frame_cond_var_; - std::mutex new_frame_mtx_; - std::thread screen_server_thread_; -}; -} // namespace - -ScreenConnector* ScreenConnector::Get() { - return new SocketBasedScreenConnector(); -} - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/screen_connector.h b/host/frontend/vnc_server/screen_connector.h deleted file mode 100644 index 9c7b9e01..00000000 --- a/host/frontend/vnc_server/screen_connector.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <cstdint> - -namespace cvd { -namespace vnc { - -class ScreenConnector { - public: - static ScreenConnector* Get(); - - virtual ~ScreenConnector() = default; - - virtual int WaitForNewFrameSince(std::uint32_t* seq_num) = 0; - virtual void* GetBuffer(int buffer_idx) = 0; - - protected: - ScreenConnector() = default; -}; - -} // namespace vnc -} // namespace cvd
\ No newline at end of file diff --git a/host/frontend/vnc_server/simulated_hw_composer.cpp b/host/frontend/vnc_server/simulated_hw_composer.cpp deleted file mode 100644 index 96702e87..00000000 --- a/host/frontend/vnc_server/simulated_hw_composer.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/simulated_hw_composer.h" - -#include "host/frontend/vnc_server/vnc_utils.h" -#include "host/libs/config/cuttlefish_config.h" - -using cvd::vnc::SimulatedHWComposer; - -SimulatedHWComposer::SimulatedHWComposer(BlackBoard* bb) - : -#ifdef FUZZ_TEST_VNC - engine_{std::random_device{}()}, -#endif - bb_{bb}, - stripes_(kMaxQueueElements, &SimulatedHWComposer::EraseHalfOfElements) { - stripe_maker_ = std::thread(&SimulatedHWComposer::MakeStripes, this); -} - -SimulatedHWComposer::~SimulatedHWComposer() { - close(); - stripe_maker_.join(); -} - -cvd::vnc::Stripe SimulatedHWComposer::GetNewStripe() { - auto s = stripes_.Pop(); -#ifdef FUZZ_TEST_VNC - if (random_(engine_)) { - usleep(7000); - stripes_.Push(std::move(s)); - s = stripes_.Pop(); - } -#endif - return s; -} - -bool SimulatedHWComposer::closed() { - std::lock_guard<std::mutex> guard(m_); - return closed_; -} - -void SimulatedHWComposer::close() { - std::lock_guard<std::mutex> guard(m_); - closed_ = true; -} - -// Assuming the number of stripes is less than half the size of the queue -// this will be safe as the newest stripes won't be lost. In the real -// hwcomposer, where stripes are coming in a different order, the full -// queue case would probably need a different approach to be safe. -void SimulatedHWComposer::EraseHalfOfElements( - ThreadSafeQueue<Stripe>::QueueImpl* q) { - q->erase(q->begin(), std::next(q->begin(), kMaxQueueElements / 2)); -} - -void SimulatedHWComposer::MakeStripes() { - std::uint32_t previous_seq_num{}; - auto screen_height = ActualScreenHeight(); - Message raw_screen; - std::uint64_t stripe_seq_num = 1; - while (!closed()) { - bb_->WaitForAtLeastOneClientConnection(); - int buffer_idx = screen_connector_->WaitForNewFrameSince(&previous_seq_num); - const char* frame_start = - static_cast<char*>(screen_connector_->GetBuffer(buffer_idx)); - raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes()); - - for (int i = 0; i < kNumStripes; ++i) { - ++stripe_seq_num; - std::uint16_t y = (screen_height / kNumStripes) * i; - - // Last frames on the right and/or bottom handle extra pixels - // when a screen dimension is not evenly divisible by Frame::kNumSlots. - std::uint16_t height = - screen_height / kNumStripes + - (i + 1 == kNumStripes ? screen_height % kNumStripes : 0); - const auto* raw_start = - &raw_screen[y * ActualScreenWidth() * BytesPerPixel()]; - const auto* raw_end = - raw_start + (height * ActualScreenWidth() * BytesPerPixel()); - // creating a named object and setting individual data members in order - // to make klp happy - // TODO (haining) construct this inside the call when not compiling - // on klp - Stripe s{}; - s.index = i; - s.frame_id = previous_seq_num; - s.x = 0; - s.y = y; - s.width = ActualScreenWidth(); - s.stride = ActualScreenStride(); - s.height = height; - s.raw_data.assign(raw_start, raw_end); - s.seq_number = StripeSeqNumber{stripe_seq_num}; - s.orientation = ScreenOrientation::Portrait; - stripes_.Push(std::move(s)); - } - } -} - -int SimulatedHWComposer::NumberOfStripes() { return kNumStripes; } diff --git a/host/frontend/vnc_server/simulated_hw_composer.h b/host/frontend/vnc_server/simulated_hw_composer.h deleted file mode 100644 index 802cc7f2..00000000 --- a/host/frontend/vnc_server/simulated_hw_composer.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <condition_variable> -#include <mutex> -#ifdef FUZZ_TEST_VNC -#include <random> -#endif -#include <thread> - -#include "common/libs/thread_safe_queue/thread_safe_queue.h" -#include "common/libs/threads/thread_annotations.h" -#include "host/frontend/vnc_server/blackboard.h" -#include "host/frontend/vnc_server/screen_connector.h" - -namespace cvd { -namespace vnc { -class SimulatedHWComposer { - public: - SimulatedHWComposer(BlackBoard* bb); - SimulatedHWComposer(const SimulatedHWComposer&) = delete; - SimulatedHWComposer& operator=(const SimulatedHWComposer&) = delete; - ~SimulatedHWComposer(); - - Stripe GetNewStripe(); - - // NOTE not constexpr on purpose - static int NumberOfStripes(); - - private: - bool closed(); - void close(); - static void EraseHalfOfElements(ThreadSafeQueue<Stripe>::QueueImpl* q); - void MakeStripes(); - -#ifdef FUZZ_TEST_VNC - std::default_random_engine engine_; - std::uniform_int_distribution<int> random_ = - std::uniform_int_distribution<int>{0, 2}; -#endif - static constexpr int kNumStripes = 8; - constexpr static std::size_t kMaxQueueElements = 64; - bool closed_ GUARDED_BY(m_){}; - std::mutex m_; - BlackBoard* bb_{}; - ThreadSafeQueue<Stripe> stripes_; - std::thread stripe_maker_; - std::shared_ptr<ScreenConnector> screen_connector_{ScreenConnector::Get()}; -}; -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/virtual_inputs.cpp b/host/frontend/vnc_server/virtual_inputs.cpp deleted file mode 100644 index fb91409a..00000000 --- a/host/frontend/vnc_server/virtual_inputs.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/virtual_inputs.h" -#include <gflags/gflags.h> -#include <glog/logging.h> -#include <linux/input.h> -#include <linux/uinput.h> - -#include <cstdint> -#include <mutex> -#include <thread> -#include "keysyms.h" - -#include <common/libs/fs/shared_select.h> -#include <host/libs/config/cuttlefish_config.h> - -using cvd::vnc::VirtualInputs; - -DEFINE_int32(touch_fd, -1, - "A fd for a socket where to accept touch connections"); - -DEFINE_int32(keyboard_fd, -1, - "A fd for a socket where to accept keyboard connections"); - -DEFINE_bool(write_virtio_input, false, - "Whether to write the virtio_input struct over the socket"); - -namespace { -// Necessary to define here as the virtio_input.h header is not available -// in the host glibc. -struct virtio_input_event { - std::uint16_t type; - std::uint16_t code; - std::int32_t value; -}; - -void AddKeyMappings(std::map<uint32_t, uint16_t>* key_mapping) { - (*key_mapping)[cvd::xk::AltLeft] = KEY_LEFTALT; - (*key_mapping)[cvd::xk::ControlLeft] = KEY_LEFTCTRL; - (*key_mapping)[cvd::xk::ShiftLeft] = KEY_LEFTSHIFT; - (*key_mapping)[cvd::xk::AltRight] = KEY_RIGHTALT; - (*key_mapping)[cvd::xk::ControlRight] = KEY_RIGHTCTRL; - (*key_mapping)[cvd::xk::ShiftRight] = KEY_RIGHTSHIFT; - (*key_mapping)[cvd::xk::MetaLeft] = KEY_LEFTMETA; - (*key_mapping)[cvd::xk::MetaRight] = KEY_RIGHTMETA; - (*key_mapping)[cvd::xk::MultiKey] = KEY_COMPOSE; - - (*key_mapping)[cvd::xk::CapsLock] = KEY_CAPSLOCK; - (*key_mapping)[cvd::xk::NumLock] = KEY_NUMLOCK; - (*key_mapping)[cvd::xk::ScrollLock] = KEY_SCROLLLOCK; - - (*key_mapping)[cvd::xk::BackSpace] = KEY_BACKSPACE; - (*key_mapping)[cvd::xk::Tab] = KEY_TAB; - (*key_mapping)[cvd::xk::Return] = KEY_ENTER; - (*key_mapping)[cvd::xk::Escape] = KEY_ESC; - - (*key_mapping)[' '] = KEY_SPACE; - (*key_mapping)['!'] = KEY_1; - (*key_mapping)['"'] = KEY_APOSTROPHE; - (*key_mapping)['#'] = KEY_3; - (*key_mapping)['$'] = KEY_4; - (*key_mapping)['%'] = KEY_5; - (*key_mapping)['^'] = KEY_6; - (*key_mapping)['&'] = KEY_7; - (*key_mapping)['\''] = KEY_APOSTROPHE; - (*key_mapping)['('] = KEY_9; - (*key_mapping)[')'] = KEY_0; - (*key_mapping)['*'] = KEY_8; - (*key_mapping)['+'] = KEY_EQUAL; - (*key_mapping)[','] = KEY_COMMA; - (*key_mapping)['-'] = KEY_MINUS; - (*key_mapping)['.'] = KEY_DOT; - (*key_mapping)['/'] = KEY_SLASH; - (*key_mapping)['0'] = KEY_0; - (*key_mapping)['1'] = KEY_1; - (*key_mapping)['2'] = KEY_2; - (*key_mapping)['3'] = KEY_3; - (*key_mapping)['4'] = KEY_4; - (*key_mapping)['5'] = KEY_5; - (*key_mapping)['6'] = KEY_6; - (*key_mapping)['7'] = KEY_7; - (*key_mapping)['8'] = KEY_8; - (*key_mapping)['9'] = KEY_9; - (*key_mapping)[':'] = KEY_SEMICOLON; - (*key_mapping)[';'] = KEY_SEMICOLON; - (*key_mapping)['<'] = KEY_COMMA; - (*key_mapping)['='] = KEY_EQUAL; - (*key_mapping)['>'] = KEY_DOT; - (*key_mapping)['?'] = KEY_SLASH; - (*key_mapping)['@'] = KEY_2; - (*key_mapping)['A'] = KEY_A; - (*key_mapping)['B'] = KEY_B; - (*key_mapping)['C'] = KEY_C; - (*key_mapping)['D'] = KEY_D; - (*key_mapping)['E'] = KEY_E; - (*key_mapping)['F'] = KEY_F; - (*key_mapping)['G'] = KEY_G; - (*key_mapping)['H'] = KEY_H; - (*key_mapping)['I'] = KEY_I; - (*key_mapping)['J'] = KEY_J; - (*key_mapping)['K'] = KEY_K; - (*key_mapping)['L'] = KEY_L; - (*key_mapping)['M'] = KEY_M; - (*key_mapping)['N'] = KEY_N; - (*key_mapping)['O'] = KEY_O; - (*key_mapping)['P'] = KEY_P; - (*key_mapping)['Q'] = KEY_Q; - (*key_mapping)['R'] = KEY_R; - (*key_mapping)['S'] = KEY_S; - (*key_mapping)['T'] = KEY_T; - (*key_mapping)['U'] = KEY_U; - (*key_mapping)['V'] = KEY_V; - (*key_mapping)['W'] = KEY_W; - (*key_mapping)['X'] = KEY_X; - (*key_mapping)['Y'] = KEY_Y; - (*key_mapping)['Z'] = KEY_Z; - (*key_mapping)['['] = KEY_LEFTBRACE; - (*key_mapping)['\\'] = KEY_BACKSLASH; - (*key_mapping)[']'] = KEY_RIGHTBRACE; - (*key_mapping)['-'] = KEY_MINUS; - (*key_mapping)['_'] = KEY_MINUS; - (*key_mapping)['`'] = KEY_GRAVE; - (*key_mapping)['a'] = KEY_A; - (*key_mapping)['b'] = KEY_B; - (*key_mapping)['c'] = KEY_C; - (*key_mapping)['d'] = KEY_D; - (*key_mapping)['e'] = KEY_E; - (*key_mapping)['f'] = KEY_F; - (*key_mapping)['g'] = KEY_G; - (*key_mapping)['h'] = KEY_H; - (*key_mapping)['i'] = KEY_I; - (*key_mapping)['j'] = KEY_J; - (*key_mapping)['k'] = KEY_K; - (*key_mapping)['l'] = KEY_L; - (*key_mapping)['m'] = KEY_M; - (*key_mapping)['n'] = KEY_N; - (*key_mapping)['o'] = KEY_O; - (*key_mapping)['p'] = KEY_P; - (*key_mapping)['q'] = KEY_Q; - (*key_mapping)['r'] = KEY_R; - (*key_mapping)['s'] = KEY_S; - (*key_mapping)['t'] = KEY_T; - (*key_mapping)['u'] = KEY_U; - (*key_mapping)['v'] = KEY_V; - (*key_mapping)['w'] = KEY_W; - (*key_mapping)['x'] = KEY_X; - (*key_mapping)['y'] = KEY_Y; - (*key_mapping)['z'] = KEY_Z; - (*key_mapping)['{'] = KEY_LEFTBRACE; - (*key_mapping)['\\'] = KEY_BACKSLASH; - (*key_mapping)['|'] = KEY_BACKSLASH; - (*key_mapping)['}'] = KEY_RIGHTBRACE; - (*key_mapping)['~'] = KEY_GRAVE; - - (*key_mapping)[cvd::xk::F1] = KEY_F1; - (*key_mapping)[cvd::xk::F2] = KEY_F2; - (*key_mapping)[cvd::xk::F3] = KEY_F3; - (*key_mapping)[cvd::xk::F4] = KEY_F4; - (*key_mapping)[cvd::xk::F5] = KEY_F5; - (*key_mapping)[cvd::xk::F6] = KEY_F6; - (*key_mapping)[cvd::xk::F7] = KEY_F7; - (*key_mapping)[cvd::xk::F8] = KEY_F8; - (*key_mapping)[cvd::xk::F9] = KEY_F9; - (*key_mapping)[cvd::xk::F10] = KEY_F10; - (*key_mapping)[cvd::xk::F11] = KEY_F11; - (*key_mapping)[cvd::xk::F12] = KEY_F12; - (*key_mapping)[cvd::xk::F13] = KEY_F13; - (*key_mapping)[cvd::xk::F14] = KEY_F14; - (*key_mapping)[cvd::xk::F15] = KEY_F15; - (*key_mapping)[cvd::xk::F16] = KEY_F16; - (*key_mapping)[cvd::xk::F17] = KEY_F17; - (*key_mapping)[cvd::xk::F18] = KEY_F18; - (*key_mapping)[cvd::xk::F19] = KEY_F19; - (*key_mapping)[cvd::xk::F20] = KEY_F20; - (*key_mapping)[cvd::xk::F21] = KEY_F21; - (*key_mapping)[cvd::xk::F22] = KEY_F22; - (*key_mapping)[cvd::xk::F23] = KEY_F23; - (*key_mapping)[cvd::xk::F24] = KEY_F24; - - (*key_mapping)[cvd::xk::Keypad0] = KEY_KP0; - (*key_mapping)[cvd::xk::Keypad1] = KEY_KP1; - (*key_mapping)[cvd::xk::Keypad2] = KEY_KP2; - (*key_mapping)[cvd::xk::Keypad3] = KEY_KP3; - (*key_mapping)[cvd::xk::Keypad4] = KEY_KP4; - (*key_mapping)[cvd::xk::Keypad5] = KEY_KP5; - (*key_mapping)[cvd::xk::Keypad6] = KEY_KP6; - (*key_mapping)[cvd::xk::Keypad7] = KEY_KP7; - (*key_mapping)[cvd::xk::Keypad8] = KEY_KP8; - (*key_mapping)[cvd::xk::Keypad9] = KEY_KP9; - (*key_mapping)[cvd::xk::KeypadMultiply] = KEY_KPASTERISK; - (*key_mapping)[cvd::xk::KeypadSubtract] = KEY_KPMINUS; - (*key_mapping)[cvd::xk::KeypadAdd] = KEY_KPPLUS; - (*key_mapping)[cvd::xk::KeypadDecimal] = KEY_KPDOT; - (*key_mapping)[cvd::xk::KeypadEnter] = KEY_KPENTER; - (*key_mapping)[cvd::xk::KeypadDivide] = KEY_KPSLASH; - (*key_mapping)[cvd::xk::KeypadEqual] = KEY_KPEQUAL; - (*key_mapping)[cvd::xk::PlusMinus] = KEY_KPPLUSMINUS; - - (*key_mapping)[cvd::xk::SysReq] = KEY_SYSRQ; - (*key_mapping)[cvd::xk::LineFeed] = KEY_LINEFEED; - (*key_mapping)[cvd::xk::Home] = KEY_HOME; - (*key_mapping)[cvd::xk::Up] = KEY_UP; - (*key_mapping)[cvd::xk::PageUp] = KEY_PAGEUP; - (*key_mapping)[cvd::xk::Left] = KEY_LEFT; - (*key_mapping)[cvd::xk::Right] = KEY_RIGHT; - (*key_mapping)[cvd::xk::End] = KEY_END; - (*key_mapping)[cvd::xk::Down] = KEY_DOWN; - (*key_mapping)[cvd::xk::PageDown] = KEY_PAGEDOWN; - (*key_mapping)[cvd::xk::Insert] = KEY_INSERT; - (*key_mapping)[cvd::xk::Delete] = KEY_DELETE; - (*key_mapping)[cvd::xk::Pause] = KEY_PAUSE; - (*key_mapping)[cvd::xk::KeypadSeparator] = KEY_KPCOMMA; - (*key_mapping)[cvd::xk::Yen] = KEY_YEN; - (*key_mapping)[cvd::xk::Cancel] = KEY_STOP; - (*key_mapping)[cvd::xk::Redo] = KEY_AGAIN; - (*key_mapping)[cvd::xk::Undo] = KEY_UNDO; - (*key_mapping)[cvd::xk::Find] = KEY_FIND; - (*key_mapping)[cvd::xk::Print] = KEY_PRINT; - (*key_mapping)[cvd::xk::VolumeDown] = KEY_VOLUMEDOWN; - (*key_mapping)[cvd::xk::Mute] = KEY_MUTE; - (*key_mapping)[cvd::xk::VolumeUp] = KEY_VOLUMEUP; - (*key_mapping)[cvd::xk::Menu] = KEY_MENU; - (*key_mapping)[cvd::xk::VNCMenu] = KEY_MENU; -} - -void InitInputEvent(struct input_event* evt, uint16_t type, uint16_t code, - int32_t value) { - evt->type = type; - evt->code = code; - evt->value = value; -} - -} // namespace - -class SocketVirtualInputs : public VirtualInputs { - public: - SocketVirtualInputs() - : client_connector_([this]() { ClientConnectorLoop(); }) {} - - void GenerateKeyPressEvent(int key_code, bool down) override { - struct input_event events[2]; - InitInputEvent(&events[0], EV_KEY, keymapping_[key_code], down); - InitInputEvent(&events[1], EV_SYN, 0, 0); - - SendEvents(keyboard_socket_, events); - } - - void PressPowerButton(bool down) override { - struct input_event events[2]; - InitInputEvent(&events[0], EV_KEY, KEY_POWER, down); - InitInputEvent(&events[1], EV_SYN, 0, 0); - - SendEvents(keyboard_socket_, events); - } - - void HandlePointerEvent(bool touch_down, int x, int y) override { - // TODO(b/124121375): Use multitouch when available - struct input_event events[4]; - InitInputEvent(&events[0], EV_ABS, ABS_X, x); - InitInputEvent(&events[1], EV_ABS, ABS_Y, y); - InitInputEvent(&events[2], EV_KEY, BTN_TOUCH, touch_down); - InitInputEvent(&events[3], EV_SYN, 0, 0); - - SendEvents(touch_socket_, events); - } - - private: - template<size_t num_events> - void SendEvents(cvd::SharedFD socket, struct input_event (&event_buffer)[num_events]) { - std::lock_guard<std::mutex> lock(socket_mutex_); - if (!socket->IsOpen()) { - // This is unlikely as it would only happen between the start of the vnc - // server and the connection of the VMM to the socket. - // If it happens, just drop the events as the VM is not yet ready to - // handle it. - return; - } - - if (FLAGS_write_virtio_input) { - struct virtio_input_event virtio_events[num_events]; - for (size_t i = 0; i < num_events; i++) { - virtio_events[i] = (struct virtio_input_event) { - .type = event_buffer[i].type, - .code = event_buffer[i].code, - .value = event_buffer[i].value, - }; - } - auto ret = socket->Write(virtio_events, sizeof(virtio_events)); - if (ret < 0) { - LOG(ERROR) << "Error sending input events: " << socket->StrError(); - } - } else { - auto ret = socket->Write(event_buffer, sizeof(event_buffer)); - if (ret < 0) { - LOG(ERROR) << "Error sending input events: " << socket->StrError(); - } - } - } - - void ClientConnectorLoop() { - auto touch_server = cvd::SharedFD::Dup(FLAGS_touch_fd); - close(FLAGS_touch_fd); - FLAGS_touch_fd = -1; - - auto keyboard_server = cvd::SharedFD::Dup(FLAGS_keyboard_fd); - close(FLAGS_keyboard_fd); - FLAGS_keyboard_fd = -1; - LOG(INFO) << "Input socket host accepting connections..."; - - while (1) { - cvd::SharedFDSet read_set; - read_set.Set(touch_server); - read_set.Set(keyboard_server); - cvd::Select(&read_set, nullptr, nullptr, nullptr); - { - std::lock_guard<std::mutex> lock(socket_mutex_); - if (read_set.IsSet(touch_server)) { - touch_socket_ = cvd::SharedFD::Accept(*touch_server); - LOG(INFO) << "connected to touch"; - } - if (read_set.IsSet(keyboard_server)) { - keyboard_socket_ = cvd::SharedFD::Accept(*keyboard_server); - LOG(INFO) << "connected to keyboard"; - } - } - } - } - cvd::SharedFD touch_socket_; - cvd::SharedFD keyboard_socket_; - std::thread client_connector_; - std::mutex socket_mutex_; -}; - -VirtualInputs::VirtualInputs() { AddKeyMappings(&keymapping_); } - -VirtualInputs* VirtualInputs::Get() { - return new SocketVirtualInputs(); -} diff --git a/host/frontend/vnc_server/virtual_inputs.h b/host/frontend/vnc_server/virtual_inputs.h deleted file mode 100644 index 7aca3eb3..00000000 --- a/host/frontend/vnc_server/virtual_inputs.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "vnc_utils.h" - -#include <map> -#include <mutex> - -namespace cvd { -namespace vnc { - -class VirtualInputs { - public: - static VirtualInputs* Get(); - - virtual ~VirtualInputs() = default; - - virtual void GenerateKeyPressEvent(int code, bool down) = 0; - virtual void PressPowerButton(bool down) = 0; - virtual void HandlePointerEvent(bool touch_down, int x, int y) = 0; - - protected: - VirtualInputs(); - - std::map<uint32_t, uint16_t> keymapping_; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp deleted file mode 100644 index b81bb88b..00000000 --- a/host/frontend/vnc_server/vnc_client_connection.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/vnc_client_connection.h" - -#include <netinet/in.h> -#include <sys/time.h> - -#include <algorithm> -#include <cmath> -#include <cstdint> -#include <cstring> -#include <memory> -#include <mutex> -#include <string> -#include <thread> -#include <utility> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> -#include "common/libs/tcp_socket/tcp_socket.h" -#include "host/frontend/vnc_server/keysyms.h" -#include "host/frontend/vnc_server/mocks.h" -#include "host/frontend/vnc_server/vnc_utils.h" -#include "host/libs/config/cuttlefish_config.h" - -using cvd::Message; -using cvd::vnc::Stripe; -using cvd::vnc::StripePtrVec; -using cvd::vnc::VncClientConnection; - -struct ScreenRegionView { - using Pixel = uint32_t; - static constexpr int kSwiftShaderPadding = 4; - static constexpr int kRedShift = 0; - static constexpr int kGreenShift = 8; - static constexpr int kBlueShift = 16; - static constexpr int kRedBits = 8; - static constexpr int kGreenBits = 8; - static constexpr int kBlueBits = 8; -}; - -DEFINE_bool(debug_client, false, "Turn on detailed logging for the client"); - -#define DLOG(LEVEL) \ - if (FLAGS_debug_client) LOG(LEVEL) - -namespace { -class BigEndianChecker { - public: - BigEndianChecker() { - uint32_t u = 1; - is_big_endian_ = *reinterpret_cast<const char*>(&u) == 0; - } - bool operator()() const { return is_big_endian_; } - - private: - bool is_big_endian_{}; -}; - -const BigEndianChecker ImBigEndian; - -constexpr int32_t kDesktopSizeEncoding = -223; -constexpr int32_t kTightEncoding = 7; - -// These are the lengths not counting the first byte. The first byte -// indicates the message type. -constexpr size_t kSetPixelFormatLength = 19; -constexpr size_t kFramebufferUpdateRequestLength = 9; -constexpr size_t kSetEncodingsLength = 3; // more bytes follow -constexpr size_t kKeyEventLength = 7; -constexpr size_t kPointerEventLength = 5; -constexpr size_t kClientCutTextLength = 7; // more bytes follow - -std::string HostName() { - auto config = vsoc::CuttlefishConfig::Get(); - return !config || config->device_title().empty() ? std::string{"localhost"} - : config->device_title(); -} - -std::uint16_t uint16_tAt(const void* p) { - std::uint16_t u{}; - std::memcpy(&u, p, sizeof u); - return ntohs(u); -} - -std::uint32_t uint32_tAt(const void* p) { - std::uint32_t u{}; - std::memcpy(&u, p, sizeof u); - return ntohl(u); -} - -std::int32_t int32_tAt(const void* p) { - std::uint32_t u{}; - std::memcpy(&u, p, sizeof u); - u = ntohl(u); - std::int32_t s{}; - std::memcpy(&s, &u, sizeof s); - return s; -} - -std::uint32_t RedVal(std::uint32_t pixel) { - return (pixel >> ScreenRegionView::kRedShift) & - ((0x1 << ScreenRegionView::kRedBits) - 1); -} - -std::uint32_t BlueVal(std::uint32_t pixel) { - return (pixel >> ScreenRegionView::kBlueShift) & - ((0x1 << ScreenRegionView::kBlueBits) - 1); -} - -std::uint32_t GreenVal(std::uint32_t pixel) { - return (pixel >> ScreenRegionView::kGreenShift) & - ((0x1 << ScreenRegionView::kGreenBits) - 1); -} -} // namespace -namespace cvd { -namespace vnc { -bool operator==(const VncClientConnection::FrameBufferUpdateRequest& lhs, - const VncClientConnection::FrameBufferUpdateRequest& rhs) { - return lhs.x_pos == rhs.x_pos && lhs.y_pos == rhs.y_pos && - lhs.width == rhs.width && lhs.height == rhs.height; -} - -bool operator!=(const VncClientConnection::FrameBufferUpdateRequest& lhs, - const VncClientConnection::FrameBufferUpdateRequest& rhs) { - return !(lhs == rhs); -} -} // namespace vnc -} // namespace cvd - -VncClientConnection::VncClientConnection( - ClientSocket client, std::shared_ptr<VirtualInputs> virtual_inputs, - BlackBoard* bb, bool aggressive) - : client_{std::move(client)}, virtual_inputs_{virtual_inputs}, bb_{bb} { - frame_buffer_request_handler_tid_ = std::thread( - &VncClientConnection::FrameBufferUpdateRequestHandler, this, aggressive); -} - -VncClientConnection::~VncClientConnection() { - { - std::lock_guard<std::mutex> guard(m_); - closed_ = true; - } - bb_->StopWaiting(this); - frame_buffer_request_handler_tid_.join(); -} - -void VncClientConnection::StartSession() { - LOG(INFO) << "Starting session"; - SetupProtocol(); - LOG(INFO) << "Protocol set up"; - if (client_.closed()) { - return; - } - SetupSecurityType(); - LOG(INFO) << "Security type set"; - if (client_.closed()) { - return; - } - GetClientInit(); - LOG(INFO) << "Gotten client init"; - if (client_.closed()) { - return; - } - SendServerInit(); - LOG(INFO) << "Sent server init"; - if (client_.closed()) { - return; - } - NormalSession(); - LOG(INFO) << "vnc session terminated"; -} - -bool VncClientConnection::closed() { - std::lock_guard<std::mutex> guard(m_); - return closed_; -} - -void VncClientConnection::SetupProtocol() { - static constexpr char kRFBVersion[] = "RFB 003.008\n"; - static constexpr auto kVersionLen = (sizeof kRFBVersion) - 1; - client_.SendNoSignal(reinterpret_cast<const std::uint8_t*>(kRFBVersion), - kVersionLen); - auto client_protocol = client_.Recv(kVersionLen); - if (std::memcmp(&client_protocol[0], kRFBVersion, - std::min(kVersionLen, client_protocol.size())) != 0) { - client_protocol.push_back('\0'); - LOG(ERROR) << "vnc client wants a different protocol: " - << reinterpret_cast<const char*>(&client_protocol[0]); - } -} - -void VncClientConnection::SetupSecurityType() { - static constexpr std::uint8_t kNoneSecurity = 0x1; - // The first '0x1' indicates the number of items that follow - static constexpr std::uint8_t kOnlyNoneSecurity[] = {0x01, kNoneSecurity}; - client_.SendNoSignal(kOnlyNoneSecurity); - auto client_security = client_.Recv(1); - if (client_.closed()) { - return; - } - if (client_security.front() != kNoneSecurity) { - LOG(ERROR) << "vnc client is asking for security type " - << static_cast<int>(client_security.front()); - } - static constexpr std::uint8_t kZero[4] = {}; - client_.SendNoSignal(kZero); -} - -void VncClientConnection::GetClientInit() { - auto client_shared = client_.Recv(1); -} - -void VncClientConnection::SendServerInit() { - const std::string server_name = HostName(); - std::lock_guard<std::mutex> guard(m_); - auto server_init = cvd::CreateMessage( - static_cast<std::uint16_t>(ScreenWidth()), - static_cast<std::uint16_t>(ScreenHeight()), pixel_format_.bits_per_pixel, - pixel_format_.depth, pixel_format_.big_endian, pixel_format_.true_color, - pixel_format_.red_max, pixel_format_.green_max, pixel_format_.blue_max, - pixel_format_.red_shift, pixel_format_.green_shift, - pixel_format_.blue_shift, std::uint16_t{}, // padding - std::uint8_t{}, // padding - static_cast<std::uint32_t>(server_name.size()), server_name); - client_.SendNoSignal(server_init); -} - -Message VncClientConnection::MakeFrameBufferUpdateHeader( - std::uint16_t num_stripes) { - return cvd::CreateMessage(std::uint8_t{0}, // message-type - std::uint8_t{}, // padding - std::uint16_t{num_stripes}); -} - -void VncClientConnection::AppendRawStripeHeader(Message* frame_buffer_update, - const Stripe& stripe) { - static constexpr int32_t kRawEncoding = 0; - cvd::AppendToMessage(frame_buffer_update, std::uint16_t{stripe.x}, - std::uint16_t{stripe.y}, std::uint16_t{stripe.width}, - std::uint16_t{stripe.height}, kRawEncoding); -} - -void VncClientConnection::AppendJpegSize(Message* frame_buffer_update, - size_t jpeg_size) { - constexpr size_t kJpegSizeOneByteMax = 127; - constexpr size_t kJpegSizeTwoByteMax = 16383; - constexpr size_t kJpegSizeThreeByteMax = 4194303; - - if (jpeg_size <= kJpegSizeOneByteMax) { - cvd::AppendToMessage(frame_buffer_update, - static_cast<std::uint8_t>(jpeg_size)); - } else if (jpeg_size <= kJpegSizeTwoByteMax) { - auto sz = static_cast<std::uint32_t>(jpeg_size); - cvd::AppendToMessage(frame_buffer_update, - static_cast<std::uint8_t>((sz & 0x7F) | 0x80), - static_cast<std::uint8_t>((sz >> 7) & 0xFF)); - } else { - if (jpeg_size > kJpegSizeThreeByteMax) { - LOG(FATAL) << "jpeg size is too big: " << jpeg_size << " must be under " - << kJpegSizeThreeByteMax; - } - const auto sz = static_cast<std::uint32_t>(jpeg_size); - cvd::AppendToMessage(frame_buffer_update, - static_cast<std::uint8_t>((sz & 0x7F) | 0x80), - static_cast<std::uint8_t>(((sz >> 7) & 0x7F) | 0x80), - static_cast<std::uint8_t>((sz >> 14) & 0xFF)); - } -} - -void VncClientConnection::AppendRawStripe(Message* frame_buffer_update, - const Stripe& stripe) const { - using Pixel = ScreenRegionView::Pixel; - auto& fbu = *frame_buffer_update; - AppendRawStripeHeader(&fbu, stripe); - auto init_size = fbu.size(); - fbu.insert(fbu.end(), stripe.raw_data.begin(), stripe.raw_data.end()); - for (size_t i = init_size; i < fbu.size(); i += sizeof(Pixel)) { - CHECK_LE(i + sizeof(Pixel), fbu.size()); - Pixel raw_pixel{}; - std::memcpy(&raw_pixel, &fbu[i], sizeof raw_pixel); - auto red = RedVal(raw_pixel); - auto green = GreenVal(raw_pixel); - auto blue = BlueVal(raw_pixel); - Pixel pixel = Pixel{red} << pixel_format_.red_shift | - Pixel{blue} << pixel_format_.blue_shift | - Pixel{green} << pixel_format_.green_shift; - - if (bool(pixel_format_.big_endian) != ImBigEndian()) { - // flip them bits (refactor into function) - auto p = reinterpret_cast<char*>(&pixel); - std::swap(p[0], p[3]); - std::swap(p[1], p[2]); - } - std::memcpy(&fbu[i], &pixel, sizeof pixel); - } -} - -Message VncClientConnection::MakeRawFrameBufferUpdate( - const StripePtrVec& stripes) const { - auto fbu = - MakeFrameBufferUpdateHeader(static_cast<std::uint16_t>(stripes.size())); - for (auto& stripe : stripes) { - AppendRawStripe(&fbu, *stripe); - } - return fbu; -} - -void VncClientConnection::AppendJpegStripeHeader(Message* frame_buffer_update, - const Stripe& stripe) { - static constexpr std::uint8_t kJpegEncoding = 0x90; - cvd::AppendToMessage(frame_buffer_update, stripe.x, stripe.y, stripe.width, - stripe.height, kTightEncoding, kJpegEncoding); - AppendJpegSize(frame_buffer_update, stripe.jpeg_data.size()); -} - -void VncClientConnection::AppendJpegStripe(Message* frame_buffer_update, - const Stripe& stripe) { - AppendJpegStripeHeader(frame_buffer_update, stripe); - frame_buffer_update->insert(frame_buffer_update->end(), - stripe.jpeg_data.begin(), stripe.jpeg_data.end()); -} - -Message VncClientConnection::MakeJpegFrameBufferUpdate( - const StripePtrVec& stripes) { - auto fbu = - MakeFrameBufferUpdateHeader(static_cast<std::uint16_t>(stripes.size())); - for (auto& stripe : stripes) { - AppendJpegStripe(&fbu, *stripe); - } - return fbu; -} - -Message VncClientConnection::MakeFrameBufferUpdate( - const StripePtrVec& stripes) { - return use_jpeg_compression_ ? MakeJpegFrameBufferUpdate(stripes) - : MakeRawFrameBufferUpdate(stripes); -} - -void VncClientConnection::FrameBufferUpdateRequestHandler(bool aggressive) { - BlackBoard::Registerer reg(bb_, this); - - while (!closed()) { - auto stripes = bb_->WaitForSenderWork(this); - if (closed()) { - break; - } - if (stripes.empty()) { - LOG(FATAL) << "Got 0 stripes"; - } - { - // lock here so a portrait frame can't be sent after a landscape - // DesktopSize update, or vice versa. - std::lock_guard<std::mutex> guard(m_); - DLOG(INFO) << "Sending update in " - << (current_orientation_ == ScreenOrientation::Portrait - ? "portrait" - : "landscape") - << " mode"; - client_.SendNoSignal(MakeFrameBufferUpdate(stripes)); - } - if (aggressive) { - bb_->FrameBufferUpdateRequestReceived(this); - } - } -} - -void VncClientConnection::SendDesktopSizeUpdate() { - static constexpr int32_t kDesktopSizeEncoding = -223; - client_.SendNoSignal(cvd::CreateMessage( - std::uint8_t{0}, // message-type, - std::uint8_t{}, // padding - std::uint16_t{1}, // one pseudo rectangle - std::uint16_t{0}, std::uint16_t{0}, - static_cast<std::uint16_t>(ScreenWidth()), - static_cast<std::uint16_t>(ScreenHeight()), kDesktopSizeEncoding)); -} - -bool VncClientConnection::IsUrgent( - const FrameBufferUpdateRequest& update_request) const { - return !update_request.incremental || - update_request != previous_update_request_; -} - -void VncClientConnection::HandleFramebufferUpdateRequest() { - auto msg = client_.Recv(kFramebufferUpdateRequestLength); - if (msg.size() != kFramebufferUpdateRequestLength) { - return; - } - FrameBufferUpdateRequest fbur{msg[1] == 0, uint16_tAt(&msg[1]), - uint16_tAt(&msg[3]), uint16_tAt(&msg[5]), - uint16_tAt(&msg[7])}; - if (IsUrgent(fbur)) { - bb_->SignalClientNeedsEntireScreen(this); - } - bb_->FrameBufferUpdateRequestReceived(this); - previous_update_request_ = fbur; -} - -void VncClientConnection::HandleSetEncodings() { - auto msg = client_.Recv(kSetEncodingsLength); - if (msg.size() != kSetEncodingsLength) { - return; - } - auto count = uint16_tAt(&msg[1]); - auto encodings = client_.Recv(count * sizeof(int32_t)); - if (encodings.size() % sizeof(int32_t) != 0) { - return; - } - { - std::lock_guard<std::mutex> guard(m_); - use_jpeg_compression_ = false; - } - for (size_t i = 0; i < encodings.size(); i += sizeof(int32_t)) { - auto enc = int32_tAt(&encodings[i]); - DLOG(INFO) << "client requesting encoding: " << enc; - if (enc == kTightEncoding) { - // This is a deviation from the spec which says that if a jpeg quality - // level is not specified, tight encoding won't use jpeg. - std::lock_guard<std::mutex> guard(m_); - use_jpeg_compression_ = true; - } - if (kJpegMinQualityEncoding <= enc && enc <= kJpegMaxQualityEncoding) { - DLOG(INFO) << "jpeg compression level: " << enc; - bb_->set_jpeg_quality_level(enc); - } - if (enc == kDesktopSizeEncoding) { - supports_desktop_size_encoding_ = true; - } - } -} - -void VncClientConnection::HandleSetPixelFormat() { - std::lock_guard<std::mutex> guard(m_); - auto msg = client_.Recv(kSetPixelFormatLength); - if (msg.size() != kSetPixelFormatLength) { - return; - } - pixel_format_.bits_per_pixel = msg[3]; - pixel_format_.depth = msg[4]; - pixel_format_.big_endian = msg[5]; - pixel_format_.true_color = msg[7]; - pixel_format_.red_max = uint16_tAt(&msg[8]); - pixel_format_.green_max = uint16_tAt(&msg[10]); - pixel_format_.blue_max = uint16_tAt(&msg[12]); - pixel_format_.red_shift = msg[13]; - pixel_format_.green_shift = msg[14]; - pixel_format_.blue_shift = msg[15]; -} - -void VncClientConnection::HandlePointerEvent() { - auto msg = client_.Recv(kPointerEventLength); - if (msg.size() != kPointerEventLength) { - return; - } - std::uint8_t button_mask = msg[0]; - auto x_pos = uint16_tAt(&msg[1]); - auto y_pos = uint16_tAt(&msg[3]); - { - std::lock_guard<std::mutex> guard(m_); - if (current_orientation_ == ScreenOrientation::Landscape) { - std::tie(x_pos, y_pos) = - std::make_pair(ActualScreenWidth() - y_pos, x_pos); - } - } - virtual_inputs_->HandlePointerEvent(button_mask, x_pos, y_pos); -} - -void VncClientConnection::UpdateAccelerometer(float /*x*/, float /*y*/, - float /*z*/) { - // TODO(jemoreira): Implement when vsoc sensor hal is updated -} - -VncClientConnection::Coordinates VncClientConnection::CoordinatesForOrientation( - ScreenOrientation orientation) const { - // Compute the acceleration vector that we need to send to mimic - // this change. - constexpr float g = 9.81; - constexpr float angle = 20.0; - const float cos_angle = std::cos(angle / M_PI); - const float sin_angle = std::sin(angle / M_PI); - const float z = g * sin_angle; - switch (orientation) { - case ScreenOrientation::Portrait: - return {0, g * cos_angle, z}; - case ScreenOrientation::Landscape: - return {g * cos_angle, 0, z}; - } -} - -int VncClientConnection::ScreenWidth() const { - return current_orientation_ == ScreenOrientation::Portrait - ? ActualScreenWidth() - : ActualScreenHeight(); -} - -int VncClientConnection::ScreenHeight() const { - return current_orientation_ == ScreenOrientation::Portrait - ? ActualScreenHeight() - : ActualScreenWidth(); -} - -void VncClientConnection::SetScreenOrientation(ScreenOrientation orientation) { - std::lock_guard<std::mutex> guard(m_); - auto coords = CoordinatesForOrientation(orientation); - UpdateAccelerometer(coords.x, coords.y, coords.z); - if (supports_desktop_size_encoding_) { - auto previous_orientation = current_orientation_; - current_orientation_ = orientation; - if (current_orientation_ != previous_orientation && - supports_desktop_size_encoding_) { - SendDesktopSizeUpdate(); - bb_->SetOrientation(this, current_orientation_); - // TODO not sure if I should be sending a frame update along with this, - // or just letting the next FBUR handle it. This seems to me like it's - // sending one more frame buffer update than was requested, which is - // maybe a violation of the spec? - } - } -} - -bool VncClientConnection::RotateIfIsRotationCommand(std::uint32_t key) { - // Due to different configurations on different platforms we're supporting - // a set of options for rotating the screen. These are similar to what - // the emulator supports and has supported. - // ctrl+left and ctrl+right work on windows and linux - // command+left and command+right work on Mac - // ctrl+fn+F11 and ctrl+fn+F12 work when chromoting to ubuntu from a Mac - if (!control_key_down_ && !meta_key_down_) { - return false; - } - switch (key) { - case cvd::xk::Right: - case cvd::xk::F12: - DLOG(INFO) << "switching to portrait"; - SetScreenOrientation(ScreenOrientation::Portrait); - break; - case cvd::xk::Left: - case cvd::xk::F11: - DLOG(INFO) << "switching to landscape"; - SetScreenOrientation(ScreenOrientation::Landscape); - break; - default: - return false; - } - return true; -} - -void VncClientConnection::HandleKeyEvent() { - auto msg = client_.Recv(kKeyEventLength); - if (msg.size() != kKeyEventLength) { - return; - } - - auto key = uint32_tAt(&msg[3]); - bool key_down = msg[0]; - switch (key) { - case cvd::xk::ControlLeft: - case cvd::xk::ControlRight: - control_key_down_ = key_down; - break; - case cvd::xk::MetaLeft: - case cvd::xk::MetaRight: - meta_key_down_ = key_down; - break; - case cvd::xk::F5: - key = cvd::xk::Menu; - break; - case cvd::xk::F7: - virtual_inputs_->PressPowerButton(key_down); - return; - default: - break; - } - - if (RotateIfIsRotationCommand(key)) { - return; - } - - virtual_inputs_->GenerateKeyPressEvent(key, key_down); -} - -void VncClientConnection::HandleClientCutText() { - auto msg = client_.Recv(kClientCutTextLength); - if (msg.size() != kClientCutTextLength) { - return; - } - auto len = uint32_tAt(&msg[3]); - client_.Recv(len); -} - -void VncClientConnection::NormalSession() { - static constexpr std::uint8_t kSetPixelFormatMessage{0}; - static constexpr std::uint8_t kSetEncodingsMessage{2}; - static constexpr std::uint8_t kFramebufferUpdateRequestMessage{3}; - static constexpr std::uint8_t kKeyEventMessage{4}; - static constexpr std::uint8_t kPointerEventMessage{5}; - static constexpr std::uint8_t kClientCutTextMessage{6}; - while (true) { - if (client_.closed()) { - return; - } - auto msg = client_.Recv(1); - if (client_.closed()) { - return; - } - auto msg_type = msg.front(); - DLOG(INFO) << "Received message type " << msg_type; - - switch (msg_type) { - case kSetPixelFormatMessage: - HandleSetPixelFormat(); - break; - - case kSetEncodingsMessage: - HandleSetEncodings(); - break; - - case kFramebufferUpdateRequestMessage: - HandleFramebufferUpdateRequest(); - break; - - case kKeyEventMessage: - HandleKeyEvent(); - break; - - case kPointerEventMessage: - HandlePointerEvent(); - break; - - case kClientCutTextMessage: - HandleClientCutText(); - break; - - default: - LOG(WARNING) << "message type not handled: " - << static_cast<int>(msg_type); - break; - } - } -} diff --git a/host/frontend/vnc_server/vnc_client_connection.h b/host/frontend/vnc_server/vnc_client_connection.h deleted file mode 100644 index 73beae1a..00000000 --- a/host/frontend/vnc_server/vnc_client_connection.h +++ /dev/null @@ -1,171 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/threads/thread_annotations.h" - -#include <cstdint> -#include <memory> -#include <mutex> -#include <thread> -#include <vector> - -#include "common/libs/tcp_socket/tcp_socket.h" -#include "host/frontend/vnc_server/blackboard.h" -#include "host/frontend/vnc_server/virtual_inputs.h" -#include "host/frontend/vnc_server/vnc_utils.h" - -namespace cvd { -namespace vnc { - -class VncClientConnection { - public: - VncClientConnection(ClientSocket client, - std::shared_ptr<VirtualInputs> virtual_inputs, - BlackBoard* bb, bool aggressive); - VncClientConnection(const VncClientConnection&) = delete; - VncClientConnection& operator=(const VncClientConnection&) = delete; - ~VncClientConnection(); - - void StartSession(); - - private: - struct PixelFormat { - std::uint8_t bits_per_pixel; - std::uint8_t depth; - std::uint8_t big_endian; - std::uint8_t true_color; - std::uint16_t red_max; - std::uint16_t green_max; - std::uint16_t blue_max; - std::uint8_t red_shift; - std::uint8_t green_shift; - std::uint8_t blue_shift; - }; - - struct FrameBufferUpdateRequest { - bool incremental; - std::uint16_t x_pos; - std::uint16_t y_pos; - std::uint16_t width; - std::uint16_t height; - }; - - friend bool operator==(const FrameBufferUpdateRequest&, - const FrameBufferUpdateRequest&); - friend bool operator!=(const FrameBufferUpdateRequest&, - const FrameBufferUpdateRequest&); - - bool closed(); - void SetupProtocol(); - void SetupSecurityType(); - - void GetClientInit(); - - void SendServerInit() EXCLUDES(m_); - static Message MakeFrameBufferUpdateHeader(std::uint16_t num_stripes); - - static void AppendRawStripeHeader(Message* frame_buffer_update, - const Stripe& stripe); - void AppendRawStripe(Message* frame_buffer_update, const Stripe& stripe) const - REQUIRES(m_); - Message MakeRawFrameBufferUpdate(const StripePtrVec& stripes) const - REQUIRES(m_); - - static void AppendJpegSize(Message* frame_buffer_update, size_t jpeg_size); - static void AppendJpegStripeHeader(Message* frame_buffer_update, - const Stripe& stripe); - static void AppendJpegStripe(Message* frame_buffer_update, - const Stripe& stripe); - static Message MakeJpegFrameBufferUpdate(const StripePtrVec& stripes); - - Message MakeFrameBufferUpdate(const StripePtrVec& frame) REQUIRES(m_); - - void FrameBufferUpdateRequestHandler(bool aggressive) EXCLUDES(m_); - - void SendDesktopSizeUpdate() REQUIRES(m_); - - bool IsUrgent(const FrameBufferUpdateRequest& update_request) const; - static StripeSeqNumber MostRecentStripeSeqNumber(const StripePtrVec& stripes); - - void HandleFramebufferUpdateRequest() EXCLUDES(m_); - - void HandleSetEncodings(); - - void HandleSetPixelFormat(); - - void HandlePointerEvent() EXCLUDES(m_); - - void UpdateAccelerometer(float x, float y, float z); - - struct Coordinates { - float x; - float y; - float z; - }; - - Coordinates CoordinatesForOrientation(ScreenOrientation orientation) const; - - int ScreenWidth() const REQUIRES(m_); - - int ScreenHeight() const REQUIRES(m_); - - void SetScreenOrientation(ScreenOrientation orientation) EXCLUDES(m_); - - // Returns true if key is special and the screen was rotated. - bool RotateIfIsRotationCommand(std::uint32_t key); - - void HandleKeyEvent(); - - void HandleClientCutText(); - - void NormalSession(); - - mutable std::mutex m_; - ClientSocket client_; - bool control_key_down_ = false; - bool meta_key_down_ = false; - std::shared_ptr<VirtualInputs> virtual_inputs_{}; - - FrameBufferUpdateRequest previous_update_request_{}; - BlackBoard* bb_; - bool use_jpeg_compression_ GUARDED_BY(m_) = false; - - std::thread frame_buffer_request_handler_tid_; - bool closed_ GUARDED_BY(m_){}; - - PixelFormat pixel_format_ GUARDED_BY(m_) = { - std::uint8_t{32}, // bits per pixel - std::uint8_t{8}, // depth - std::uint8_t{}, // big_endian - std::uint8_t{}, // true_color - std::uint16_t{}, // red_max, (maxes not used when true color flag is 0) - std::uint16_t{}, // green_max - std::uint16_t{}, // blue_max - std::uint8_t{}, // red_shift (shifts not used when true color flag is 0) - std::uint8_t{}, // green_shift - std::uint8_t{}, // blue_shift - }; - - bool supports_desktop_size_encoding_ = false; - ScreenOrientation current_orientation_ GUARDED_BY(m_) = - ScreenOrientation::Portrait; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/vnc_server.cpp b/host/frontend/vnc_server/vnc_server.cpp deleted file mode 100644 index 3aba4677..00000000 --- a/host/frontend/vnc_server/vnc_server.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/frontend/vnc_server/vnc_server.h" - -#include <glog/logging.h> -#include "common/libs/tcp_socket/tcp_socket.h" -#include "host/frontend/vnc_server/blackboard.h" -#include "host/frontend/vnc_server/frame_buffer_watcher.h" -#include "host/frontend/vnc_server/jpeg_compressor.h" -#include "host/frontend/vnc_server/virtual_inputs.h" -#include "host/frontend/vnc_server/vnc_client_connection.h" -#include "host/frontend/vnc_server/vnc_utils.h" - -using cvd::vnc::VncServer; - -VncServer::VncServer(int port, bool aggressive) - : server_(port), - virtual_inputs_(VirtualInputs::Get()), - frame_buffer_watcher_{&bb_}, - aggressive_{aggressive} {} - -void VncServer::MainLoop() { - while (true) { - LOG(INFO) << "Awaiting connections"; - auto connection = server_.Accept(); - LOG(INFO) << "Accepted a client connection"; - StartClient(std::move(connection)); - } -} - -void VncServer::StartClient(ClientSocket sock) { - std::thread t(&VncServer::StartClientThread, this, std::move(sock)); - t.detach(); -} - -void VncServer::StartClientThread(ClientSocket sock) { - // NOTE if VncServer is expected to be destroyed, we have a problem here. - // All of the client threads will be pointing to the VncServer's - // data members. In the current setup, if the VncServer is destroyed with - // clients still running, the clients will all be left with dangling - // pointers. - VncClientConnection client(std::move(sock), virtual_inputs_, &bb_, - aggressive_); - client.StartSession(); -} diff --git a/host/frontend/vnc_server/vnc_server.h b/host/frontend/vnc_server/vnc_server.h deleted file mode 100644 index 66e17e05..00000000 --- a/host/frontend/vnc_server/vnc_server.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <memory> -#include <string> -#include <thread> -#include <utility> - -#include "common/libs/tcp_socket/tcp_socket.h" -#include "host/frontend/vnc_server/blackboard.h" -#include "host/frontend/vnc_server/frame_buffer_watcher.h" -#include "host/frontend/vnc_server/jpeg_compressor.h" -#include "host/frontend/vnc_server/virtual_inputs.h" -#include "host/frontend/vnc_server/vnc_client_connection.h" -#include "host/frontend/vnc_server/vnc_utils.h" - -namespace cvd { -namespace vnc { - -class VncServer { - public: - explicit VncServer(int port, bool aggressive); - - VncServer(const VncServer&) = delete; - VncServer& operator=(const VncServer&) = delete; - - [[noreturn]] void MainLoop(); - - private: - void StartClient(ClientSocket sock); - - void StartClientThread(ClientSocket sock); - - ServerSocket server_; - std::shared_ptr<VirtualInputs> virtual_inputs_; - BlackBoard bb_; - FrameBufferWatcher frame_buffer_watcher_; - bool aggressive_{}; -}; - -} // namespace vnc -} // namespace cvd diff --git a/host/frontend/vnc_server/vnc_utils.h b/host/frontend/vnc_server/vnc_utils.h deleted file mode 100644 index db881315..00000000 --- a/host/frontend/vnc_server/vnc_utils.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <array> -#include <cstdint> -#include <utility> -#include <vector> - -#include "common/libs/utils/size_utils.h" -#include "common/libs/tcp_socket/tcp_socket.h" -#include "host/libs/config/cuttlefish_config.h" - -namespace cvd { -namespace vnc { - -// TODO(haining) when the hwcomposer gives a sequence number type, use that -// instead. It might just work to replace this class with a type alias -// using StripeSeqNumber = whatever_the_hwcomposer_uses; -class StripeSeqNumber { - public: - StripeSeqNumber() = default; - explicit StripeSeqNumber(std::uint64_t t) : t_{t} {} - bool operator<(const StripeSeqNumber& other) const { return t_ < other.t_; } - - bool operator<=(const StripeSeqNumber& other) const { return t_ <= other.t_; } - - private: - std::uint64_t t_{}; -}; - -constexpr int32_t kJpegMaxQualityEncoding = -23; -constexpr int32_t kJpegMinQualityEncoding = -32; - -enum class ScreenOrientation { Portrait, Landscape }; -constexpr int kNumOrientations = 2; - -struct Stripe { - int index = -1; - std::uint64_t frame_id{}; - std::uint16_t x{}; - std::uint16_t y{}; - std::uint16_t width{}; - std::uint16_t stride{}; - std::uint16_t height{}; - Message raw_data{}; - Message jpeg_data{}; - StripeSeqNumber seq_number{}; - ScreenOrientation orientation{}; -}; - -inline constexpr int BytesPerPixel() { - return sizeof(uint32_t); -} - -// The width of the screen regardless of orientation. Does not change. -inline int ActualScreenWidth() { - return vsoc::CuttlefishConfig::Get()->x_res(); -} - -// The length of the screen stride regardless of orientation. Does not change. -inline int ActualScreenStride() { - return AlignToPowerOf2(ActualScreenWidth() * BytesPerPixel(), 4); -} - -// The height of the screen regardless of orientation. Does not change. -inline int ActualScreenHeight() { - return vsoc::CuttlefishConfig::Get()->y_res(); -} - -inline int ScreenSizeInBytes() { - return ActualScreenWidth() * ActualScreenHeight() * BytesPerPixel(); -} - -} // namespace vnc -} // namespace cvd diff --git a/host/libs/Android.bp b/host/libs/Android.bp deleted file mode 100644 index 0f82b57f..00000000 --- a/host/libs/Android.bp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (C) 2017 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. - -subdirs = [ - "adb_connection_maintainer", - "config", - "vm_manager", -] diff --git a/host/libs/adb_connection_maintainer/Android.bp b/host/libs/adb_connection_maintainer/Android.bp deleted file mode 100644 index 4a89da35..00000000 --- a/host/libs/adb_connection_maintainer/Android.bp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (C) 2018 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. - -cc_library_host_static { - name: "libadb_connection_maintainer", - srcs: [ - "adb_connection_maintainer.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libbase", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp b/host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp deleted file mode 100644 index 1336951b..00000000 --- a/host/libs/adb_connection_maintainer/adb_connection_maintainer.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cctype> -#include <iomanip> -#include <sstream> -#include <string> -#include <memory> -#include <vector> -#include <glog/logging.h> - -#include <unistd.h> - -#include "common/libs/fs/shared_fd.h" -#include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h" - -namespace { - -std::string MakeMessage(const std::string& user_message) { - std::ostringstream ss; - ss << std::setfill('0') << std::setw(4) << std::hex << user_message.size() - << user_message; - return ss.str(); -} - -std::string MakeShellUptimeMessage() { - return MakeMessage("shell,raw:cut -d. -f1 /proc/uptime"); -} - -std::string MakeTransportMessage(const std::string& address) { - return MakeMessage("host:transport:" + address); -} - -std::string MakeConnectMessage(const std::string& address) { - return MakeMessage("host:connect:" + address); -} - -std::string MakeDisconnectMessage(const std::string& address) { - return MakeMessage("host:connect:" + address); -} - -// returns true if successfully sent the whole message -bool SendAll(cvd::SharedFD sock, const std::string& msg) { - ssize_t total_written{}; - while (total_written < static_cast<ssize_t>(msg.size())) { - if (!sock->IsOpen()) { - return false; - } - auto just_written = sock->Send(msg.c_str() + total_written, - msg.size() - total_written, MSG_NOSIGNAL); - if (just_written <= 0) { - return false; - } - total_written += just_written; - } - return true; -} - -std::string RecvAll(cvd::SharedFD sock, const size_t count) { - size_t total_read{}; - std::unique_ptr<char[]> data(new char[count]); - while (total_read < count) { - auto just_read = sock->Read(data.get() + total_read, count - total_read); - if (just_read <= 0) { - LOG(WARNING) << "adb daemon socket closed early"; - return {}; - } - total_read += just_read; - } - return {data.get(), count}; -} - -// Response will either be OKAY or FAIL -constexpr char kAdbOkayStatusResponse[] = "OKAY"; -constexpr std::size_t kAdbStatusResponseLength = - sizeof kAdbOkayStatusResponse - 1; -// adb sends the length of what is to follow as a 4 characters string of hex -// digits -constexpr std::size_t kAdbMessageLengthLength = 4; - -constexpr int kAdbDaemonPort = 5037; - -bool AdbSendMessage(cvd::SharedFD sock, const std::string& message) { - if (!sock->IsOpen()) { - return false; - } - if (!SendAll(sock, message)) { - LOG(WARNING) << "failed to send all bytes to adb daemon"; - return false; - } - return RecvAll(sock, kAdbStatusResponseLength) == kAdbOkayStatusResponse; -} - -bool AdbSendMessage(const std::string& message) { - auto sock = cvd::SharedFD::SocketLocalClient(kAdbDaemonPort, SOCK_STREAM); - return AdbSendMessage(sock, message); -} - -bool AdbConnect(const std::string& address) { - return AdbSendMessage(MakeConnectMessage(address)); -} - -bool AdbDisconnect(const std::string& address) { - return AdbSendMessage(MakeDisconnectMessage(address)); -} - -bool IsInteger(const std::string& str) { - return !str.empty() && std::all_of(str.begin(), str.end(), - [](char c) { return std::isdigit(c); }); -} - -// assumes the OKAY/FAIL status has already been read -std::string RecvAdbResponse(cvd::SharedFD sock) { - auto length_as_hex_str = RecvAll(sock, kAdbMessageLengthLength); - if (!IsInteger(length_as_hex_str)) { - return {}; - } - auto length = std::stoi(length_as_hex_str, nullptr, 16); - return RecvAll(sock, length); -} - -// Returns a negative value if uptime result couldn't be read for -// any reason. -int RecvUptimeResult(cvd::SharedFD sock) { - std::vector<char> uptime_vec{}; - std::vector<char> just_read(16); - do { - auto count = sock->Read(just_read.data(), just_read.size()); - if (count < 0) { - LOG(INFO) << "couldn't receive adb shell output"; - return -1; - } - just_read.resize(count); - uptime_vec.insert(uptime_vec.end(), just_read.begin(), just_read.end()); - } while (!just_read.empty()); - - if (uptime_vec.empty()) { - LOG(INFO) << "empty adb shell result"; - return -1; - } - - uptime_vec.pop_back(); - - auto uptime_str = std::string{uptime_vec.data(), uptime_vec.size()}; - if (!IsInteger(uptime_str)) { - LOG(INFO) << "non-numeric: uptime result: " << uptime_str; - return -1; - } - - return std::stoi(uptime_str); -} - -// There needs to be a gap between the adb commands, the daemon isn't able to -// handle the avalanche of requests we would be sending without a sleep. Five -// seconds is much larger than seems necessary so we should be more than okay. -static constexpr int kAdbCommandGapTime = 5; - -void EstablishConnection(const std::string& address) { - LOG(INFO) << "Attempting to connect to device with address " << address; - while (!AdbConnect(address)) { - sleep(kAdbCommandGapTime); - } - LOG(INFO) << "adb connect message for " << address << " successfully sent"; - sleep(kAdbCommandGapTime); -} - -void WaitForAdbDisconnection(const std::string& address) { - // adb daemon doesn't seem to handle quick, successive messages well. The - // sleeps stabilize the communication. - LOG(INFO) << "Watching for disconnect on " << address; - while (true) { - auto sock = cvd::SharedFD::SocketLocalClient(kAdbDaemonPort, SOCK_STREAM); - if (!AdbSendMessage(sock, MakeTransportMessage(address))) { - LOG(INFO) << "transport message failed, response body: " - << RecvAdbResponse(sock); - break; - } - if (!AdbSendMessage(sock, MakeShellUptimeMessage())) { - LOG(INFO) << "adb shell uptime message failed"; - break; - } - - auto uptime = RecvUptimeResult(sock); - if (uptime < 0) { - LOG(INFO) << "couldn't read uptime result"; - break; - } - LOG(DEBUG) << "device on " << address << " uptime " << uptime; - sleep(kAdbCommandGapTime); - } - LOG(INFO) << "Sending adb disconnect"; - AdbDisconnect(address); - sleep(kAdbCommandGapTime); -} - -} // namespace - -[[noreturn]] void cvd::EstablishAndMaintainConnection(std::string address) { - while (true) { - EstablishConnection(address); - WaitForAdbDisconnection(address); - } -} diff --git a/host/libs/adb_connection_maintainer/adb_connection_maintainer.h b/host/libs/adb_connection_maintainer/adb_connection_maintainer.h deleted file mode 100644 index ca5584fe..00000000 --- a/host/libs/adb_connection_maintainer/adb_connection_maintainer.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -namespace cvd { - -[[noreturn]] void EstablishAndMaintainConnection(std::string address); - -} // namespace cvd diff --git a/host/libs/config/Android.bp b/host/libs/config/Android.bp deleted file mode 100644 index d88b2063..00000000 --- a/host/libs/config/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_library_host_static { - name: "libcuttlefish_host_config", - srcs: [ - "cuttlefish_config.cpp", - "fetcher_config.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - "libgflags", - ], - static_libs: [ - "libxml2", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp deleted file mode 100644 index 3b223d9a..00000000 --- a/host/libs/config/cuttlefish_config.cpp +++ /dev/null @@ -1,992 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/libs/config/cuttlefish_config.h" - -#include <algorithm> -#include <climits> -#include <cstdlib> -#include <cstring> -#include <fstream> -#include <iomanip> -#include <iterator> -#include <sstream> -#include <string> - -#include <android-base/strings.h> -#include <glog/logging.h> -#include <json/json.h> - -#include "common/libs/utils/environment.h" -#include "common/libs/utils/files.h" -#include "host/libs/vm_manager/qemu_manager.h" - - -namespace { - -int InstanceFromEnvironment() { - static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE"; - static constexpr int kDefaultInstance = 1; - - // CUTTLEFISH_INSTANCE environment variable - const char* instance_str = std::getenv(kInstanceEnvironmentVariable); - if (!instance_str) { - // Try to get it from the user instead - instance_str = std::getenv("USER"); - - if (!instance_str || std::strncmp(instance_str, vsoc::kVsocUserPrefix, - sizeof(vsoc::kVsocUserPrefix) - 1)) { - // No user or we don't recognize this user - LOG(WARNING) << "No user or non-vsoc user, returning default config"; - return kDefaultInstance; - } - instance_str += sizeof(vsoc::kVsocUserPrefix) - 1; - - // Set the environment variable so that child processes see it - setenv(kInstanceEnvironmentVariable, instance_str, 0); - } - - int instance = std::atoi(instance_str); - if (instance <= 0) { - instance = kDefaultInstance; - } - - return instance; -} - -const char* kSerialNumber = "serial_number"; -const char* kInstanceDir = "instance_dir"; -const char* kVmManager = "vm_manager"; -const char* const kGpuMode = "gpu_mode"; -const char* const kWaylandSocket = "wayland_socket"; -const char* const kXDisplay = "x_display"; -const char* kDeviceTitle = "device_title"; - -const char* kCpus = "cpus"; -const char* kMemoryMb = "memory_mb"; -const char* kDpi = "dpi"; -const char* kXRes = "x_res"; -const char* kYRes = "y_res"; -const char* kNumScreenBuffers = "num_screen_buffers"; -const char* kRefreshRateHz = "refresh_rate_hz"; - -const char* kKernelImagePath = "kernel_image_path"; -const char* kUseUnpackedKernel = "use_unpacked_kernel"; -const char* kDecompressedKernelImagePath = "decompressed_kernel_image_path"; -const char* kDecompressKernel = "decompress_kernel"; -const char* kGdbFlag = "gdb_flag"; -const char* kRamdiskImagePath = "ramdisk_image_path"; -const char* kInitramfsPath = "initramfs_path"; -const char* kFinalRamdiskPath = "final_ramdisk_path"; -const char* kVendorRamdiskImagePath = "vendor_ramdisk_image_path"; - -const char* kVirtualDiskPaths = "virtual_disk_paths"; -const char* kUsbV1SocketName = "usb_v1_socket_name"; -const char* kVhciPort = "vhci_port"; -const char* kUsbIpSocketName = "usb_ip_socket_name"; -const char* kKernelLogPipeName = "kernel_log_pipe_name"; -const char* kConsolePipeName = "console_pipe_name"; -const char* kDeprecatedBootCompleted = "deprecated_boot_completed"; -const char* kConsolePath = "console_path"; -const char* kLogcatPath = "logcat_path"; -const char* kLauncherLogPath = "launcher_log_path"; -const char* kLauncherMonitorPath = "launcher_monitor_socket"; - -const char* kMobileBridgeName = "mobile_bridge_name"; -const char* kMobileTapName = "mobile_tap_name"; -const char* kWifiTapName = "wifi_tap_name"; -const char* kVsockGuestCid = "vsock_guest_cid"; - -const char* kUuid = "uuid"; -const char* kCuttlefishEnvPath = "cuttlefish_env_path"; - -const char* kAdbMode = "adb_mode"; -const char* kHostPort = "host_port"; -const char* kAdbIPAndPort = "adb_ip_and_port"; -const char* kSetupWizardMode = "setupwizard_mode"; - -const char* kQemuBinary = "qemu_binary"; -const char* kCrosvmBinary = "crosvm_binary"; -const char* kConsoleForwarderBinary = "console_forwarder_binary"; -const char* kKernelLogMonitorBinary = "kernel_log_monitor_binary"; - -const char* kEnableVncServer = "enable_vnc_server"; -const char* kVncServerBinary = "vnc_server_binary"; -const char* kVncServerPort = "vnc_server_port"; - -const char* kRestartSubprocesses = "restart_subprocesses"; -const char* kRunAdbConnector = "run_adb_connector"; -const char* kAdbConnectorBinary = "adb_connector_binary"; -const char* kVirtualUsbManagerBinary = "virtual_usb_manager_binary"; -const char* kSocketForwardProxyBinary = "socket_forward_proxy_binary"; -const char* kSocketVsockProxyBinary = "socket_vsock_proxy_binary"; - -const char* kRunAsDaemon = "run_as_daemon"; - -const char* kDataPolicy = "data_policy"; -const char* kBlankDataImageMb = "blank_data_image_mb"; -const char* kBlankDataImageFmt = "blank_data_image_fmt"; - -const char* kLogcatMode = "logcat_mode"; -const char* kLogcatVsockPort = "logcat_vsock_port"; -const char* kConfigServerPort = "config_server_port"; -const char* kFramesVsockPort = "frames_vsock_port"; -const char* kLogcatReceiverBinary = "logcat_receiver_binary"; -const char* kConfigServerBinary = "config_server_binary"; - -const char* kRunTombstoneReceiver = "enable_tombstone_logger"; -const char* kTombstoneReceiverPort = "tombstone_logger_port"; -const char* kTombstoneReceiverBinary = "tombstone_receiver_binary"; - -const char* kBootloader = "bootloader"; -const char* kUseBootloader = "use_bootloader"; - -const char* kBootSlot = "boot_slot"; - -const char* kTouchSocketPort = "touch_socket_port"; -const char* kKeyboardSocketPort = "keyboard_socket_port"; - -const char* kLoopMaxPart = "loop_max_part"; -const char* kGuestEnforceSecurity = "guest_enforce_security"; -const char* kGuestAuditSecurity = "guest_audit_security"; -const char* kBootImageKernelCmdline = "boot_image_kernel_cmdline"; -const char* kExtraKernelCmdline = "extra_kernel_cmdline"; - -} // namespace - -namespace vsoc { - -const char* const kGpuModeGuestSwiftshader = "guest_swiftshader"; -const char* const kGpuModeDrmVirgl = "drm_virgl"; - -std::string DefaultEnvironmentPath(const char* environment_key, - const char* default_value, - const char* subpath) { - return cvd::StringFromEnv(environment_key, default_value) + "/" + subpath; -} - -std::string CuttlefishConfig::instance_dir() const { - return (*dictionary_)[kInstanceDir].asString(); -} -void CuttlefishConfig::set_instance_dir(const std::string& instance_dir) { - (*dictionary_)[kInstanceDir] = instance_dir; -} - -std::string CuttlefishConfig::instance_internal_dir() const { - return PerInstancePath(kInternalDirName); -} - -std::string CuttlefishConfig::vm_manager() const { - return (*dictionary_)[kVmManager].asString(); -} -void CuttlefishConfig::set_vm_manager(const std::string& name) { - (*dictionary_)[kVmManager] = name; -} - -std::string CuttlefishConfig::gpu_mode() const { - return (*dictionary_)[kGpuMode].asString(); -} -void CuttlefishConfig::set_gpu_mode(const std::string& name) { - (*dictionary_)[kGpuMode] = name; -} - -std::string CuttlefishConfig::wayland_socket() const { - // Don't use SetPath here: the path is already fully formed. - return (*dictionary_)[kWaylandSocket].asString(); -} -void CuttlefishConfig::set_wayland_socket(const std::string& path) { - (*dictionary_)[kWaylandSocket] = path; -} - -std::string CuttlefishConfig::x_display() const { - return (*dictionary_)[kXDisplay].asString(); -} -void CuttlefishConfig::set_x_display(const std::string& address) { - (*dictionary_)[kXDisplay] = address; -} - -std::string CuttlefishConfig::serial_number() const { - return (*dictionary_)[kSerialNumber].asString(); -} -void CuttlefishConfig::set_serial_number(const std::string& serial_number) { - (*dictionary_)[kSerialNumber] = serial_number; -} - -int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); } -void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; } - -int CuttlefishConfig::memory_mb() const { - return (*dictionary_)[kMemoryMb].asInt(); -} -void CuttlefishConfig::set_memory_mb(int memory_mb) { - (*dictionary_)[kMemoryMb] = memory_mb; -} - -int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); } -void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; } - -int CuttlefishConfig::x_res() const { return (*dictionary_)[kXRes].asInt(); } -void CuttlefishConfig::set_x_res(int x_res) { (*dictionary_)[kXRes] = x_res; } - -int CuttlefishConfig::y_res() const { return (*dictionary_)[kYRes].asInt(); } -void CuttlefishConfig::set_y_res(int y_res) { (*dictionary_)[kYRes] = y_res; } - -int CuttlefishConfig::num_screen_buffers() const { - return (*dictionary_)[kNumScreenBuffers].asInt(); -} -void CuttlefishConfig::set_num_screen_buffers(int num_screen_buffers) { - (*dictionary_)[kNumScreenBuffers] = num_screen_buffers; -} - -int CuttlefishConfig::refresh_rate_hz() const { - return (*dictionary_)[kRefreshRateHz].asInt(); -} -void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) { - (*dictionary_)[kRefreshRateHz] = refresh_rate_hz; -} - -std::string CuttlefishConfig::kernel_image_path() const { - return (*dictionary_)[kKernelImagePath].asString(); -} - -void CuttlefishConfig::SetPath(const std::string& key, - const std::string& path) { - if (!path.empty()) { - (*dictionary_)[key] = cvd::AbsolutePath(path); - } -} - -void CuttlefishConfig::set_kernel_image_path( - const std::string& kernel_image_path) { - SetPath(kKernelImagePath, kernel_image_path); -} - -bool CuttlefishConfig::use_unpacked_kernel() const { - return (*dictionary_)[kUseUnpackedKernel].asBool(); -} - -void CuttlefishConfig::set_use_unpacked_kernel(bool use_unpacked_kernel) { - (*dictionary_)[kUseUnpackedKernel] = use_unpacked_kernel; -} - -bool CuttlefishConfig::decompress_kernel() const { - return (*dictionary_)[kDecompressKernel].asBool(); -} -void CuttlefishConfig::set_decompress_kernel(bool decompress_kernel) { - (*dictionary_)[kDecompressKernel] = decompress_kernel; -} - -std::string CuttlefishConfig::decompressed_kernel_image_path() const { - return (*dictionary_)[kDecompressedKernelImagePath].asString(); -} -void CuttlefishConfig::set_decompressed_kernel_image_path( - const std::string& path) { - SetPath(kDecompressedKernelImagePath, path); -} - -std::string CuttlefishConfig::gdb_flag() const { - return (*dictionary_)[kGdbFlag].asString(); -} - -void CuttlefishConfig::set_gdb_flag(const std::string& device) { - (*dictionary_)[kGdbFlag] = device; -} - -std::string CuttlefishConfig::ramdisk_image_path() const { - return (*dictionary_)[kRamdiskImagePath].asString(); -} -void CuttlefishConfig::set_ramdisk_image_path( - const std::string& ramdisk_image_path) { - SetPath(kRamdiskImagePath, ramdisk_image_path); -} - -std::string CuttlefishConfig::initramfs_path() const { - return (*dictionary_)[kInitramfsPath].asString(); -} -void CuttlefishConfig::set_initramfs_path(const std::string& initramfs_path) { - SetPath(kInitramfsPath, initramfs_path); -} - -std::string CuttlefishConfig::final_ramdisk_path() const { - return (*dictionary_)[kFinalRamdiskPath].asString(); -} -void CuttlefishConfig::set_final_ramdisk_path( - const std::string& final_ramdisk_path) { - SetPath(kFinalRamdiskPath, final_ramdisk_path); -} - -std::string CuttlefishConfig::vendor_ramdisk_image_path() const { - return (*dictionary_)[kVendorRamdiskImagePath].asString(); -} -void CuttlefishConfig::set_vendor_ramdisk_image_path( - const std::string& vendor_ramdisk_image_path) { - SetPath(kVendorRamdiskImagePath, vendor_ramdisk_image_path); -} - -std::vector<std::string> CuttlefishConfig::virtual_disk_paths() const { - std::vector<std::string> virtual_disks; - auto virtual_disks_json_obj = (*dictionary_)[kVirtualDiskPaths]; - for (const auto& disk : virtual_disks_json_obj) { - virtual_disks.push_back(disk.asString()); - } - return virtual_disks; -} -void CuttlefishConfig::set_virtual_disk_paths( - const std::vector<std::string>& virtual_disk_paths) { - Json::Value virtual_disks_json_obj(Json::arrayValue); - for (const auto& arg : virtual_disk_paths) { - virtual_disks_json_obj.append(arg); - } - (*dictionary_)[kVirtualDiskPaths] = virtual_disks_json_obj; -} - -std::string CuttlefishConfig::usb_v1_socket_name() const { - return (*dictionary_)[kUsbV1SocketName].asString(); -} -void CuttlefishConfig::set_usb_v1_socket_name( - const std::string& usb_v1_socket_name) { - (*dictionary_)[kUsbV1SocketName] = usb_v1_socket_name; -} - -int CuttlefishConfig::vhci_port() const { - return (*dictionary_)[kVhciPort].asInt(); -} -void CuttlefishConfig::set_vhci_port(int vhci_port) { - (*dictionary_)[kVhciPort] = vhci_port; -} - -std::string CuttlefishConfig::usb_ip_socket_name() const { - return (*dictionary_)[kUsbIpSocketName].asString(); -} -void CuttlefishConfig::set_usb_ip_socket_name( - const std::string& usb_ip_socket_name) { - (*dictionary_)[kUsbIpSocketName] = usb_ip_socket_name; -} - -std::string CuttlefishConfig::kernel_log_pipe_name() const { - return (*dictionary_)[kKernelLogPipeName].asString(); -} -void CuttlefishConfig::set_kernel_log_pipe_name( - const std::string& kernel_log_pipe_name) { - (*dictionary_)[kKernelLogPipeName] = kernel_log_pipe_name; -} - -std::string CuttlefishConfig::console_pipe_name() const { - return (*dictionary_)[kConsolePipeName].asString(); -} -void CuttlefishConfig::set_console_pipe_name( - const std::string& console_pipe_name) { - SetPath(kConsolePipeName, console_pipe_name); -} - -bool CuttlefishConfig::deprecated_boot_completed() const { - return (*dictionary_)[kDeprecatedBootCompleted].asBool(); -} -void CuttlefishConfig::set_deprecated_boot_completed( - bool deprecated_boot_completed) { - (*dictionary_)[kDeprecatedBootCompleted] = deprecated_boot_completed; -} - -std::string CuttlefishConfig::console_path() const { - return (*dictionary_)[kConsolePath].asString(); -} -void CuttlefishConfig::set_console_path(const std::string& console_path) { - SetPath(kConsolePath, console_path); -} - -std::string CuttlefishConfig::logcat_path() const { - return (*dictionary_)[kLogcatPath].asString(); -} -void CuttlefishConfig::set_logcat_path(const std::string& logcat_path) { - SetPath(kLogcatPath, logcat_path); -} - -std::string CuttlefishConfig::launcher_monitor_socket_path() const { - return (*dictionary_)[kLauncherMonitorPath].asString(); -} -void CuttlefishConfig::set_launcher_monitor_socket_path( - const std::string& launcher_monitor_path) { - SetPath(kLauncherMonitorPath, launcher_monitor_path); -} - -std::string CuttlefishConfig::launcher_log_path() const { - return (*dictionary_)[kLauncherLogPath].asString(); -} -void CuttlefishConfig::set_launcher_log_path( - const std::string& launcher_log_path) { - (*dictionary_)[kLauncherLogPath] = launcher_log_path; -} - -std::string CuttlefishConfig::mobile_bridge_name() const { - return (*dictionary_)[kMobileBridgeName].asString(); -} -void CuttlefishConfig::set_mobile_bridge_name( - const std::string& mobile_bridge_name) { - (*dictionary_)[kMobileBridgeName] = mobile_bridge_name; -} - -std::string CuttlefishConfig::mobile_tap_name() const { - return (*dictionary_)[kMobileTapName].asString(); -} -void CuttlefishConfig::set_mobile_tap_name(const std::string& mobile_tap_name) { - (*dictionary_)[kMobileTapName] = mobile_tap_name; -} - -std::string CuttlefishConfig::wifi_tap_name() const { - return (*dictionary_)[kWifiTapName].asString(); -} -void CuttlefishConfig::set_wifi_tap_name(const std::string& wifi_tap_name) { - (*dictionary_)[kWifiTapName] = wifi_tap_name; -} - -int CuttlefishConfig::vsock_guest_cid() const { - return (*dictionary_)[kVsockGuestCid].asInt(); -} - -void CuttlefishConfig::set_vsock_guest_cid(int vsock_guest_cid) { - (*dictionary_)[kVsockGuestCid] = vsock_guest_cid; -} - -std::string CuttlefishConfig::uuid() const { - return (*dictionary_)[kUuid].asString(); -} -void CuttlefishConfig::set_uuid(const std::string& uuid) { - (*dictionary_)[kUuid] = uuid; -} - -void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) { - SetPath(kCuttlefishEnvPath, path); -} -std::string CuttlefishConfig::cuttlefish_env_path() const { - return (*dictionary_)[kCuttlefishEnvPath].asString(); -} - -static AdbMode stringToAdbMode(std::string mode) { - std::transform(mode.begin(), mode.end(), mode.begin(), ::tolower); - if (mode == "vsock_tunnel") { - return AdbMode::VsockTunnel; - } else if (mode == "vsock_half_tunnel") { - return AdbMode::VsockHalfTunnel; - } else if (mode == "native_vsock") { - return AdbMode::NativeVsock; - } else if (mode == "usb") { - return AdbMode::Usb; - } else { - return AdbMode::Unknown; - } -} - -std::set<AdbMode> CuttlefishConfig::adb_mode() const { - std::set<AdbMode> args_set; - for (auto& mode : (*dictionary_)[kAdbMode]) { - args_set.insert(stringToAdbMode(mode.asString())); - } - return args_set; -} - -void CuttlefishConfig::set_adb_mode(const std::set<std::string>& mode) { - Json::Value mode_json_obj(Json::arrayValue); - for (const auto& arg : mode) { - mode_json_obj.append(arg); - } - (*dictionary_)[kAdbMode] = mode_json_obj; -} - -int CuttlefishConfig::host_port() const { - return (*dictionary_)[kHostPort].asInt(); -} - -void CuttlefishConfig::set_host_port(int host_port) { - (*dictionary_)[kHostPort] = host_port; -} - -std::string CuttlefishConfig::adb_ip_and_port() const { - return (*dictionary_)[kAdbIPAndPort].asString(); -} - -void CuttlefishConfig::set_adb_ip_and_port(const std::string& ip_port) { - (*dictionary_)[kAdbIPAndPort] = ip_port; -} - -std::string CuttlefishConfig::adb_device_name() const { - // TODO(schuffelen): Deal with duplication between here and launch.cc - bool vsockTunnel = adb_mode().count(AdbMode::VsockTunnel) > 0; - bool vsockHalfProxy = adb_mode().count(AdbMode::VsockHalfTunnel) > 0; - bool nativeVsock = adb_mode().count(AdbMode::NativeVsock) > 0; - if (vsockTunnel || vsockHalfProxy || nativeVsock) { - return adb_ip_and_port(); - } else if (adb_mode().count(AdbMode::Usb) > 0) { - return serial_number(); - } - LOG(ERROR) << "no adb_mode found, returning bad device name"; - return "NO_ADB_MODE_SET_NO_VALID_DEVICE_NAME"; -} - -std::string CuttlefishConfig::device_title() const { - return (*dictionary_)[kDeviceTitle].asString(); -} - -void CuttlefishConfig::set_device_title(const std::string& title) { - (*dictionary_)[kDeviceTitle] = title; -} - -std::string CuttlefishConfig::setupwizard_mode() const { - return (*dictionary_)[kSetupWizardMode].asString(); -} - -void CuttlefishConfig::set_setupwizard_mode(const std::string& mode) { - (*dictionary_)[kSetupWizardMode] = mode; -} - -std::string CuttlefishConfig::qemu_binary() const { - return (*dictionary_)[kQemuBinary].asString(); -} - -void CuttlefishConfig::set_qemu_binary(const std::string& qemu_binary) { - (*dictionary_)[kQemuBinary] = qemu_binary; -} - -std::string CuttlefishConfig::crosvm_binary() const { - return (*dictionary_)[kCrosvmBinary].asString(); -} - -void CuttlefishConfig::set_crosvm_binary(const std::string& crosvm_binary) { - (*dictionary_)[kCrosvmBinary] = crosvm_binary; -} - -std::string CuttlefishConfig::console_forwarder_binary() const { - return (*dictionary_)[kConsoleForwarderBinary].asString(); -} - -void CuttlefishConfig::set_console_forwarder_binary( - const std::string& binary) { - (*dictionary_)[kConsoleForwarderBinary] = binary; -} - -std::string CuttlefishConfig::kernel_log_monitor_binary() const { - return (*dictionary_)[kKernelLogMonitorBinary].asString(); -} - -void CuttlefishConfig::set_kernel_log_monitor_binary( - const std::string& kernel_log_monitor_binary) { - (*dictionary_)[kKernelLogMonitorBinary] = kernel_log_monitor_binary; -} - -bool CuttlefishConfig::enable_vnc_server() const { - return (*dictionary_)[kEnableVncServer].asBool(); -} - -void CuttlefishConfig::set_enable_vnc_server(bool enable_vnc_server) { - (*dictionary_)[kEnableVncServer] = enable_vnc_server; -} - -std::string CuttlefishConfig::vnc_server_binary() const { - return (*dictionary_)[kVncServerBinary].asString(); -} - -void CuttlefishConfig::set_vnc_server_binary( - const std::string& vnc_server_binary) { - (*dictionary_)[kVncServerBinary] = vnc_server_binary; -} - -int CuttlefishConfig::vnc_server_port() const { - return (*dictionary_)[kVncServerPort].asInt(); -} - -void CuttlefishConfig::set_vnc_server_port(int vnc_server_port) { - (*dictionary_)[kVncServerPort] = vnc_server_port; -} - -bool CuttlefishConfig::restart_subprocesses() const { - return (*dictionary_)[kRestartSubprocesses].asBool(); -} - -void CuttlefishConfig::set_restart_subprocesses(bool restart_subprocesses) { - (*dictionary_)[kRestartSubprocesses] = restart_subprocesses; -} - -bool CuttlefishConfig::run_adb_connector() const { - return (*dictionary_)[kRunAdbConnector].asBool(); -} - -void CuttlefishConfig::set_run_adb_connector(bool run_adb_connector) { - (*dictionary_)[kRunAdbConnector] = run_adb_connector; -} - -std::string CuttlefishConfig::adb_connector_binary() const { - return (*dictionary_)[kAdbConnectorBinary].asString(); -} - -void CuttlefishConfig::set_adb_connector_binary( - const std::string& adb_connector_binary) { - (*dictionary_)[kAdbConnectorBinary] = adb_connector_binary; -} - -std::string CuttlefishConfig::virtual_usb_manager_binary() const { - return (*dictionary_)[kVirtualUsbManagerBinary].asString(); -} - -void CuttlefishConfig::set_virtual_usb_manager_binary( - const std::string& virtual_usb_manager_binary) { - (*dictionary_)[kVirtualUsbManagerBinary] = virtual_usb_manager_binary; -} - -std::string CuttlefishConfig::socket_forward_proxy_binary() const { - return (*dictionary_)[kSocketForwardProxyBinary].asString(); -} - -void CuttlefishConfig::set_socket_forward_proxy_binary( - const std::string& socket_forward_proxy_binary) { - (*dictionary_)[kSocketForwardProxyBinary] = socket_forward_proxy_binary; -} - -std::string CuttlefishConfig::socket_vsock_proxy_binary() const { - return (*dictionary_)[kSocketVsockProxyBinary].asString(); -} - -void CuttlefishConfig::set_socket_vsock_proxy_binary( - const std::string& socket_vsock_proxy_binary) { - (*dictionary_)[kSocketVsockProxyBinary] = socket_vsock_proxy_binary; -} - -bool CuttlefishConfig::run_as_daemon() const { - return (*dictionary_)[kRunAsDaemon].asBool(); -} - -void CuttlefishConfig::set_run_as_daemon(bool run_as_daemon) { - (*dictionary_)[kRunAsDaemon] = run_as_daemon; -} -std::string CuttlefishConfig::data_policy() const { - return (*dictionary_)[kDataPolicy].asString(); -} - -void CuttlefishConfig::set_data_policy(const std::string& data_policy) { - (*dictionary_)[kDataPolicy] = data_policy; -} - -int CuttlefishConfig::blank_data_image_mb() const { - return (*dictionary_)[kBlankDataImageMb].asInt(); -} - -void CuttlefishConfig::set_blank_data_image_mb(int blank_data_image_mb) { - (*dictionary_)[kBlankDataImageMb] = blank_data_image_mb; -} - -std::string CuttlefishConfig::blank_data_image_fmt() const { - return (*dictionary_)[kBlankDataImageFmt].asString(); -} - -void CuttlefishConfig::set_blank_data_image_fmt(const std::string& blank_data_image_fmt) { - (*dictionary_)[kBlankDataImageFmt] = blank_data_image_fmt; -} - - -void CuttlefishConfig::set_logcat_mode(const std::string& mode) { - (*dictionary_)[kLogcatMode] = mode; -} - -std::string CuttlefishConfig::logcat_mode() const { - return (*dictionary_)[kLogcatMode].asString(); -} - -void CuttlefishConfig::set_logcat_vsock_port(int port) { - (*dictionary_)[kLogcatVsockPort] = port; -} - -int CuttlefishConfig::logcat_vsock_port() const { - return (*dictionary_)[kLogcatVsockPort].asInt(); -} - -void CuttlefishConfig::set_config_server_port(int port) { - (*dictionary_)[kConfigServerPort] = port; -} - -int CuttlefishConfig::config_server_port() const { - return (*dictionary_)[kConfigServerPort].asInt(); -} - -void CuttlefishConfig::set_frames_vsock_port(int port) { - (*dictionary_)[kFramesVsockPort] = port; -} - -int CuttlefishConfig::frames_vsock_port() const { - return (*dictionary_)[kFramesVsockPort].asInt(); -} - -void CuttlefishConfig::set_logcat_receiver_binary(const std::string& binary) { - SetPath(kLogcatReceiverBinary, binary); -} - -std::string CuttlefishConfig::logcat_receiver_binary() const { - return (*dictionary_)[kLogcatReceiverBinary].asString(); -} - -void CuttlefishConfig::set_config_server_binary(const std::string& binary) { - SetPath(kConfigServerBinary, binary); -} - -std::string CuttlefishConfig::config_server_binary() const { - return (*dictionary_)[kConfigServerBinary].asString(); -} - -bool CuttlefishConfig::enable_tombstone_receiver() const { - return (*dictionary_)[kRunTombstoneReceiver].asBool(); -} - -void CuttlefishConfig::set_enable_tombstone_receiver(bool enable_tombstone_receiver) { - (*dictionary_)[kRunTombstoneReceiver] = enable_tombstone_receiver; -} - -std::string CuttlefishConfig::tombstone_receiver_binary() const { - return (*dictionary_)[kTombstoneReceiverBinary].asString(); -} - -void CuttlefishConfig::set_tombstone_receiver_binary(const std::string& e2e_test_binary) { - (*dictionary_)[kTombstoneReceiverBinary] = e2e_test_binary; -} - -void CuttlefishConfig::set_tombstone_receiver_port(int port) { - (*dictionary_)[kTombstoneReceiverPort] = port; -} - -bool CuttlefishConfig::use_bootloader() const { - return (*dictionary_)[kUseBootloader].asBool(); -} - -void CuttlefishConfig::set_use_bootloader(bool use_bootloader) { - (*dictionary_)[kUseBootloader] = use_bootloader; -} - -std::string CuttlefishConfig::bootloader() const { - return (*dictionary_)[kBootloader].asString(); -} - -void CuttlefishConfig::set_bootloader(const std::string& bootloader) { - SetPath(kBootloader, bootloader); -} - -void CuttlefishConfig::set_boot_slot(const std::string& boot_slot) { - (*dictionary_)[kBootSlot] = boot_slot; -} - -std::string CuttlefishConfig::boot_slot() const { - return (*dictionary_)[kBootSlot].asString(); -} - -int CuttlefishConfig::tombstone_receiver_port() const { - return (*dictionary_)[kTombstoneReceiverPort].asInt(); -} - -std::string CuttlefishConfig::touch_socket_path() const { - return PerInstanceInternalPath("touch.sock"); -} - -std::string CuttlefishConfig::keyboard_socket_path() const { - return PerInstanceInternalPath("keyboard.sock"); -} - -void CuttlefishConfig::set_touch_socket_port(int port) { - (*dictionary_)[kTouchSocketPort] = port; -} - -int CuttlefishConfig::touch_socket_port() const { - return (*dictionary_)[kTouchSocketPort].asInt(); -} - -void CuttlefishConfig::set_keyboard_socket_port(int port) { - (*dictionary_)[kKeyboardSocketPort] = port; -} - -int CuttlefishConfig::keyboard_socket_port() const { - return (*dictionary_)[kKeyboardSocketPort].asInt(); -} - -void CuttlefishConfig::set_loop_max_part(int loop_max_part) { - (*dictionary_)[kLoopMaxPart] = loop_max_part; -} -int CuttlefishConfig::loop_max_part() const { - return (*dictionary_)[kLoopMaxPart].asInt(); -} - -void CuttlefishConfig::set_guest_enforce_security(bool guest_enforce_security) { - (*dictionary_)[kGuestEnforceSecurity] = guest_enforce_security; -} -bool CuttlefishConfig::guest_enforce_security() const { - return (*dictionary_)[kGuestEnforceSecurity].asBool(); -} - -void CuttlefishConfig::set_guest_audit_security(bool guest_audit_security) { - (*dictionary_)[kGuestAuditSecurity] = guest_audit_security; -} -bool CuttlefishConfig::guest_audit_security() const { - return (*dictionary_)[kGuestAuditSecurity].asBool(); -} - -void CuttlefishConfig::set_boot_image_kernel_cmdline(std::string boot_image_kernel_cmdline) { - Json::Value args_json_obj(Json::arrayValue); - for (const auto& arg : android::base::Split(boot_image_kernel_cmdline, " ")) { - args_json_obj.append(arg); - } - (*dictionary_)[kBootImageKernelCmdline] = args_json_obj; -} -std::vector<std::string> CuttlefishConfig::boot_image_kernel_cmdline() const { - std::vector<std::string> cmdline; - for (const Json::Value& arg : (*dictionary_)[kBootImageKernelCmdline]) { - cmdline.push_back(arg.asString()); - } - return cmdline; -} - -void CuttlefishConfig::set_extra_kernel_cmdline(std::string extra_cmdline) { - Json::Value args_json_obj(Json::arrayValue); - for (const auto& arg : android::base::Split(extra_cmdline, " ")) { - args_json_obj.append(arg); - } - (*dictionary_)[kExtraKernelCmdline] = extra_cmdline; -} -std::vector<std::string> CuttlefishConfig::extra_kernel_cmdline() const { - std::vector<std::string> cmdline; - for (const Json::Value& arg : (*dictionary_)[kExtraKernelCmdline]) { - cmdline.push_back(arg.asString()); - } - return cmdline; -} - -// Creates the (initially empty) config object and populates it with values from -// the config file if the CUTTLEFISH_CONFIG_FILE env variable is present. -// Returns nullptr if there was an error loading from file -/*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl() { - auto config_file_path = cvd::StringFromEnv(kCuttlefishConfigEnvVarName, - vsoc::GetGlobalConfigFileLink()); - auto ret = new CuttlefishConfig(); - if (ret) { - auto loaded = ret->LoadFromFile(config_file_path.c_str()); - if (!loaded) { - delete ret; - return nullptr; - } - } - return ret; -} - -/*static*/ const CuttlefishConfig* CuttlefishConfig::Get() { - static std::shared_ptr<CuttlefishConfig> config(BuildConfigImpl()); - return config.get(); -} - -CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {} -// Can't use '= default' on the header because the compiler complains of -// Json::Value being an incomplete type -CuttlefishConfig::~CuttlefishConfig() {} - -bool CuttlefishConfig::LoadFromFile(const char* file) { - auto real_file_path = cvd::AbsolutePath(file); - if (real_file_path.empty()) { - LOG(ERROR) << "Could not get real path for file " << file; - return false; - } - Json::Reader reader; - std::ifstream ifs(real_file_path); - if (!reader.parse(ifs, *dictionary_)) { - LOG(ERROR) << "Could not read config file " << file << ": " - << reader.getFormattedErrorMessages(); - return false; - } - return true; -} -bool CuttlefishConfig::SaveToFile(const std::string& file) const { - std::ofstream ofs(file); - if (!ofs.is_open()) { - LOG(ERROR) << "Unable to write to file " << file; - return false; - } - ofs << *dictionary_; - return !ofs.fail(); -} - -std::string CuttlefishConfig::PerInstancePath(const char* file_name) const { - return (instance_dir() + "/") + file_name; -} - -std::string CuttlefishConfig::PerInstanceInternalPath( - const char* file_name) const { - if (file_name[0] == '\0') { - // Don't append a / if file_name is empty. - return PerInstancePath(kInternalDirName); - } - auto relative_path = (std::string(kInternalDirName) + "/") + file_name; - return PerInstancePath(relative_path.c_str()); -} - -std::string CuttlefishConfig::instance_name() const { - return GetPerInstanceDefault("cvd-"); -} - -int GetInstance() { - static int instance_id = InstanceFromEnvironment(); - return instance_id; -} - -std::string GetGlobalConfigFileLink() { - return cvd::StringFromEnv("HOME", ".") + "/.cuttlefish_config.json"; -} - -std::string GetPerInstanceDefault(const char* prefix) { - std::ostringstream stream; - stream << prefix << std::setfill('0') << std::setw(2) << GetInstance(); - return stream.str(); -} -int GetPerInstanceDefault(int base) { return base + GetInstance() - 1; } - -std::string GetDefaultPerInstanceDir() { - std::ostringstream stream; - stream << std::getenv("HOME") << "/cuttlefish_runtime"; - return stream.str(); -} - -int GetDefaultPerInstanceVsockCid() { - constexpr int kFirstGuestCid = 3; - return vsoc::HostSupportsVsock() ? GetPerInstanceDefault(kFirstGuestCid) : 0; -} - -std::string DefaultHostArtifactsPath(const std::string& file_name) { - return (cvd::StringFromEnv("ANDROID_HOST_OUT", - cvd::StringFromEnv("HOME", ".")) + - "/") + - file_name; -} - -std::string DefaultGuestImagePath(const std::string& file_name) { - return (cvd::StringFromEnv("ANDROID_PRODUCT_OUT", - cvd::StringFromEnv("HOME", ".")) + - "/") + - file_name; -} - -bool HostSupportsQemuCli() { - static bool supported = - std::system( - "/usr/lib/cuttlefish-common/bin/capability_query.py qemu_cli") == 0; - return supported; -} - -bool HostSupportsVsock() { - static bool supported = - std::system( - "/usr/lib/cuttlefish-common/bin/capability_query.py vsock") == 0; - return supported; -} -} // namespace vsoc diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h deleted file mode 100644 index bf3d2317..00000000 --- a/host/libs/config/cuttlefish_config.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <memory> -#include <string> -#include <set> - -namespace Json { -class Value; -} - -namespace vsoc { - -constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1"; -constexpr char kCuttlefishConfigEnvVarName[] = "CUTTLEFISH_CONFIG_FILE"; -constexpr char kVsocUserPrefix[] = "vsoc-"; -constexpr char kBootStartedMessage[] ="VIRTUAL_DEVICE_BOOT_STARTED"; -constexpr char kBootCompletedMessage[] = "VIRTUAL_DEVICE_BOOT_COMPLETED"; -constexpr char kBootFailedMessage[] = "VIRTUAL_DEVICE_BOOT_FAILED"; -constexpr char kMobileNetworkConnectedMessage[] = - "VIRTUAL_DEVICE_NETWORK_MOBILE_CONNECTED"; -constexpr char kWifiConnectedMessage[] = - "VIRTUAL_DEVICE_NETWORK_WIFI_CONNECTED"; -constexpr char kInternalDirName[] = "internal"; - - -enum class AdbMode { - VsockTunnel, - VsockHalfTunnel, - NativeVsock, - Usb, - Unknown, -}; - -// Holds the configuration of the cuttlefish instances. -class CuttlefishConfig { - public: - static const CuttlefishConfig* Get(); - - CuttlefishConfig(); - ~CuttlefishConfig(); - - // Saves the configuration object in a file, it can then be read in other - // processes by passing the --config_file option. - bool SaveToFile(const std::string& file) const; - - // Returns the path to a file with the given name in the instance directory.. - std::string PerInstancePath(const char* file_name) const; - std::string PerInstanceInternalPath(const char* file_name) const; - - std::string instance_name() const; - - void disable_usb_adb() { - // This seems to be the way usb is being disbled in the launcher - set_usb_v1_socket_name(""); - } - - std::string instance_dir() const; - void set_instance_dir(const std::string& instance_dir); - - std::string instance_internal_dir() const; - - std::string vm_manager() const; - void set_vm_manager(const std::string& name); - - std::string gpu_mode() const; - void set_gpu_mode(const std::string& name); - - std::string wayland_socket() const; - void set_wayland_socket(const std::string& path); - - std::string x_display() const; - void set_x_display(const std::string& address); - - std::string serial_number() const; - void set_serial_number(const std::string& serial_number); - - int cpus() const; - void set_cpus(int cpus); - - int memory_mb() const; - void set_memory_mb(int memory_mb); - - int dpi() const; - void set_dpi(int dpi); - - int x_res() const; - void set_x_res(int x_res); - - int y_res() const; - void set_y_res(int y_res); - - int num_screen_buffers() const; - void set_num_screen_buffers(int num_screen_buffers); - - int refresh_rate_hz() const; - void set_refresh_rate_hz(int refresh_rate_hz); - - // Returns kernel image extracted from the boot image or the user-provided one - // if given by command line to the launcher. This function should not be used - // to get the kernel image the vmm should boot, GetKernelImageToUse() should - // be used instead. - std::string kernel_image_path() const; - void set_kernel_image_path(const std::string& kernel_image_path); - - bool decompress_kernel() const; - void set_decompress_kernel(bool decompress_kernel); - - // Returns the path to the kernel image that should be given to the vm manager - // to boot, takes into account whether the original image was decompressed or - // not. - std::string GetKernelImageToUse() const { - return decompress_kernel() ? decompressed_kernel_image_path() - : kernel_image_path(); - } - - std::string decompressed_kernel_image_path() const; - void set_decompressed_kernel_image_path(const std::string& path); - - bool use_unpacked_kernel() const; - void set_use_unpacked_kernel(bool use_unpacked_kernel); - - std::string gdb_flag() const; - void set_gdb_flag(const std::string& gdb); - - std::string ramdisk_image_path() const; - void set_ramdisk_image_path(const std::string& ramdisk_image_path); - - std::string initramfs_path() const; - void set_initramfs_path(const std::string& initramfs_path); - - std::string final_ramdisk_path() const; - void set_final_ramdisk_path(const std::string& final_ramdisk_path); - - std::string vendor_ramdisk_image_path() const; - void set_vendor_ramdisk_image_path(const std::string& - vendor_ramdisk_image_path); - - std::vector<std::string> virtual_disk_paths() const; - void set_virtual_disk_paths(const std::vector<std::string>& disk_paths); - - // The name of the socket that will be used to forward access to USB gadget. - // This is for V1 of the USB bus. - std::string usb_v1_socket_name() const; - void set_usb_v1_socket_name(const std::string& usb_v1_socket_name); - - int vhci_port() const; - void set_vhci_port(int vhci_port); - - std::string usb_ip_socket_name() const; - void set_usb_ip_socket_name(const std::string& usb_ip_socket_name); - - std::string kernel_log_pipe_name() const; - void set_kernel_log_pipe_name(const std::string& kernel_log_pipe_name); - - std::string console_pipe_name() const; - void set_console_pipe_name(const std::string& console_pipe_name); - - bool deprecated_boot_completed() const; - void set_deprecated_boot_completed(bool deprecated_boot_completed); - - std::string console_path() const; - void set_console_path(const std::string& console_path); - - std::string logcat_path() const; - void set_logcat_path(const std::string& logcat_path); - - std::string logcat_receiver_binary() const; - void set_logcat_receiver_binary(const std::string& binary); - - std::string config_server_binary() const; - void set_config_server_binary(const std::string& binary); - - std::string launcher_log_path() const; - void set_launcher_log_path(const std::string& launcher_log_path); - - std::string launcher_monitor_socket_path() const; - void set_launcher_monitor_socket_path( - const std::string& launhcer_monitor_path); - - std::string mobile_bridge_name() const; - void set_mobile_bridge_name(const std::string& mobile_bridge_name); - - std::string mobile_tap_name() const; - void set_mobile_tap_name(const std::string& mobile_tap_name); - - std::string wifi_tap_name() const; - void set_wifi_tap_name(const std::string& wifi_tap_name); - - void set_vsock_guest_cid(int vsock_guest_cid); - int vsock_guest_cid() const; - - std::string uuid() const; - void set_uuid(const std::string& uuid); - - void set_cuttlefish_env_path(const std::string& path); - std::string cuttlefish_env_path() const; - - void set_adb_mode(const std::set<std::string>& modes); - std::set<AdbMode> adb_mode() const; - - void set_host_port(int host_port); - int host_port() const; - - void set_adb_ip_and_port(const std::string& ip_port); - std::string adb_ip_and_port() const; - - std::string adb_device_name() const; - - void set_device_title(const std::string& title); - std::string device_title() const; - - void set_setupwizard_mode(const std::string& title); - std::string setupwizard_mode() const; - - void set_qemu_binary(const std::string& qemu_binary); - std::string qemu_binary() const; - - void set_crosvm_binary(const std::string& crosvm_binary); - std::string crosvm_binary() const; - - void set_console_forwarder_binary(const std::string& crosvm_binary); - std::string console_forwarder_binary() const; - - void set_kernel_log_monitor_binary( - const std::string& kernel_log_monitor_binary); - std::string kernel_log_monitor_binary() const; - - void set_enable_vnc_server(bool enable_vnc_server); - bool enable_vnc_server() const; - - void set_vnc_server_port(int vnc_server_port); - int vnc_server_port() const; - - void set_vnc_server_binary(const std::string& vnc_server_binary); - std::string vnc_server_binary() const; - - void set_restart_subprocesses(bool restart_subprocesses); - bool restart_subprocesses() const; - - void set_run_adb_connector(bool run_adb_connector); - bool run_adb_connector() const; - - void set_adb_connector_binary(const std::string& adb_connector_binary); - std::string adb_connector_binary() const; - - void set_virtual_usb_manager_binary(const std::string& binary); - std::string virtual_usb_manager_binary() const; - - void set_socket_forward_proxy_binary(const std::string& binary); - std::string socket_forward_proxy_binary() const; - - void set_socket_vsock_proxy_binary(const std::string& binary); - std::string socket_vsock_proxy_binary() const; - - void set_run_as_daemon(bool run_as_daemon); - bool run_as_daemon() const; - - void set_data_policy(const std::string& data_policy); - std::string data_policy() const; - - void set_blank_data_image_mb(int blank_data_image_mb); - int blank_data_image_mb() const; - - void set_blank_data_image_fmt(const std::string& blank_data_image_fmt); - std::string blank_data_image_fmt() const; - - void set_logcat_mode(const std::string& mode); - std::string logcat_mode() const; - - void set_logcat_vsock_port(int port); - int logcat_vsock_port() const; - - void set_config_server_port(int port); - int config_server_port() const; - - void set_frames_vsock_port(int port); - int frames_vsock_port() const; - - void set_enable_tombstone_receiver(bool enable_tombstone_receiver); - bool enable_tombstone_receiver() const; - - void set_tombstone_receiver_binary(const std::string& binary); - std::string tombstone_receiver_binary() const; - - void set_tombstone_receiver_port(int port); - int tombstone_receiver_port() const; - - void set_use_bootloader(bool use_bootloader); - bool use_bootloader() const; - - void set_bootloader(const std::string& bootloader_path); - std::string bootloader() const; - - void set_boot_slot(const std::string& boot_slot); - std::string boot_slot() const; - - std::string touch_socket_path() const; - std::string keyboard_socket_path() const; - - void set_touch_socket_port(int touch_socket_port); - int touch_socket_port() const; - - void set_keyboard_socket_port(int keyboard_socket_port); - int keyboard_socket_port() const; - - void set_loop_max_part(int loop_max_part); - int loop_max_part() const; - - void set_guest_enforce_security(bool guest_enforce_security); - bool guest_enforce_security() const; - - void set_guest_audit_security(bool guest_audit_security); - bool guest_audit_security() const; - - void set_boot_image_kernel_cmdline(std::string boot_image_kernel_cmdline); - std::vector<std::string> boot_image_kernel_cmdline() const; - - void set_extra_kernel_cmdline(std::string extra_cmdline); - std::vector<std::string> extra_kernel_cmdline() const; - - private: - std::unique_ptr<Json::Value> dictionary_; - - void SetPath(const std::string& key, const std::string& path); - bool LoadFromFile(const char* file); - static CuttlefishConfig* BuildConfigImpl(); - - CuttlefishConfig(const CuttlefishConfig&) = delete; - CuttlefishConfig& operator=(const CuttlefishConfig&) = delete; -}; - -// Returns the instance number as obtained from the CUTTLEFISH_INSTANCE -// environment variable or the username. -int GetInstance(); -// Returns a path where the launhcer puts a link to the config file which makes -// it easily discoverable regardless of what vm manager is in use -std::string GetGlobalConfigFileLink(); - -// These functions modify a given base value to make it different accross -// different instances by appending the instance id in case of strings or adding -// it in case of integers. -std::string GetPerInstanceDefault(const char* prefix); -int GetPerInstanceDefault(int base); - -std::string GetDefaultPerInstanceDir(); -std::string GetDefaultMempath(); -int GetDefaultPerInstanceVsockCid(); - -std::string DefaultHostArtifactsPath(const std::string& file); -std::string DefaultGuestImagePath(const std::string& file); -std::string DefaultEnvironmentPath(const char* environment_key, - const char* default_value, - const char* path); - -// Whether the host supports qemu -bool HostSupportsQemuCli(); -bool HostSupportsVsock(); - -// GPU modes -extern const char* const kGpuModeGuestSwiftshader; -extern const char* const kGpuModeDrmVirgl; -} // namespace vsoc diff --git a/host/libs/config/fetcher_config.cpp b/host/libs/config/fetcher_config.cpp deleted file mode 100644 index 86e16dcf..00000000 --- a/host/libs/config/fetcher_config.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/libs/config/fetcher_config.h" - -#include <fstream> -#include <map> -#include <string> -#include <vector> - -#include <gflags/gflags.h> -#include <glog/logging.h> -#include <json/json.h> - -#include "common/libs/utils/files.h" - -namespace cvd { - -namespace { - -const char* kFlags = "flags"; -const char* kCvdFiles = "cvd_files"; -const char* kCvdFileSource = "source"; -const char* kCvdFileBuildId = "build_id"; -const char* kCvdFileBuildTarget = "build_target"; - -FileSource SourceStringToEnum(std::string source) { - for (auto& c : source) { - c = std::tolower(c); - } - if (source == "default_build") { - return FileSource::DEFAULT_BUILD; - } else if (source == "system_build") { - return FileSource::SYSTEM_BUILD; - } else if (source == "kernel_build") { - return FileSource::KERNEL_BUILD; - } else if (source == "local_file") { - return FileSource::LOCAL_FILE; - } else if (source == "generated") { - return FileSource::GENERATED; - } else { - return FileSource::UNKNOWN_PURPOSE; - } -} - -std::string SourceEnumToString(const FileSource& source) { - if (source == FileSource::DEFAULT_BUILD) { - return "default_build"; - } else if (source == FileSource::SYSTEM_BUILD) { - return "system_build"; - } else if (source == FileSource::KERNEL_BUILD) { - return "kernel_build"; - } else if (source == FileSource::LOCAL_FILE) { - return "local_file"; - } else if (source == FileSource::GENERATED) { - return "generated"; - } else { - return "unknown"; - } -} - -} // namespace - -CvdFile::CvdFile() { -} - -CvdFile::CvdFile(const FileSource& source, const std::string& build_id, - const std::string& build_target, const std::string& file_path) - : source(source), build_id(build_id), build_target(build_target), file_path(file_path) { -} - -std::ostream& operator<<(std::ostream& os, const CvdFile& cvd_file) { - os << "CvdFile("; - os << "source = " << SourceEnumToString(cvd_file.source) << ", "; - os << "build_id = " << cvd_file.build_id << ", "; - os << "build_target = " << cvd_file.build_target << ", "; - os << "file_path = " << cvd_file.file_path << ")"; - return os; -} - -FetcherConfig::FetcherConfig() : dictionary_(new Json::Value()) { -} - -FetcherConfig::FetcherConfig(FetcherConfig&&) = default; - -FetcherConfig::~FetcherConfig() { -} - -bool FetcherConfig::SaveToFile(const std::string& file) const { - std::ofstream ofs(file); - if (!ofs.is_open()) { - LOG(ERROR) << "Unable to write to file " << file; - return false; - } - ofs << *dictionary_; - return !ofs.fail(); -} - -bool FetcherConfig::LoadFromFile(const std::string& file) { - auto real_file_path = cvd::AbsolutePath(file); - if (real_file_path.empty()) { - LOG(ERROR) << "Could not get real path for file " << file; - return false; - } - Json::Reader reader; - std::ifstream ifs(real_file_path); - if (!reader.parse(ifs, *dictionary_)) { - LOG(ERROR) << "Could not read config file " << file << ": " - << reader.getFormattedErrorMessages(); - return false; - } - return true; -} - -void FetcherConfig::RecordFlags() { - std::vector<gflags::CommandLineFlagInfo> all_flags; - GetAllFlags(&all_flags); - Json::Value flags_json(Json::arrayValue); - for (const auto& flag : all_flags) { - Json::Value flag_json; - flag_json["name"] = flag.name; - flag_json["type"] = flag.type; - flag_json["description"] = flag.description; - flag_json["current_value"] = flag.current_value; - flag_json["default_value"] = flag.default_value; - flag_json["filename"] = flag.filename; - flag_json["has_validator_fn"] = flag.has_validator_fn; - flag_json["is_default"] = flag.is_default; - flags_json.append(flag_json); - } - (*dictionary_)[kFlags] = flags_json; -} - -namespace { - -CvdFile JsonToCvdFile(const std::string& file_path, const Json::Value& json) { - CvdFile cvd_file; - cvd_file.file_path = file_path; - if (json.isMember(kCvdFileSource)) { - cvd_file.source = SourceStringToEnum(json[kCvdFileSource].asString()); - } else { - cvd_file.source = UNKNOWN_PURPOSE; - } - if (json.isMember(kCvdFileBuildId)) { - cvd_file.build_id = json[kCvdFileBuildId].asString(); - } - if (json.isMember(kCvdFileBuildTarget)) { - cvd_file.build_target = json[kCvdFileBuildTarget].asString(); - } - return cvd_file; -} - -Json::Value CvdFileToJson(const CvdFile& cvd_file) { - Json::Value json; - json[kCvdFileSource] = SourceEnumToString(cvd_file.source); - json[kCvdFileBuildId] = cvd_file.build_id; - json[kCvdFileBuildTarget] = cvd_file.build_target; - return json; -} - -} // namespace - -bool FetcherConfig::add_cvd_file(const CvdFile& file, bool override_entry) { - if (!dictionary_->isMember(kCvdFiles)) { - Json::Value files_json(Json::objectValue); - (*dictionary_)[kCvdFiles] = files_json; - } - if ((*dictionary_)[kCvdFiles].isMember(file.file_path) && !override_entry) { - return false; - } - (*dictionary_)[kCvdFiles][file.file_path] = CvdFileToJson(file); - return true; -} - -std::map<std::string, CvdFile> FetcherConfig::get_cvd_files() const { - if (!dictionary_->isMember(kCvdFiles)) { - return {}; - } - std::map<std::string, CvdFile> files; - const auto& json_files = (*dictionary_)[kCvdFiles]; - for (auto it = json_files.begin(); it != json_files.end(); it++) { - files[it.key().asString()] = JsonToCvdFile(it.key().asString(), *it); - } - return files; -} - -std::string FetcherConfig::FindCvdFileWithSuffix(const std::string& suffix) const { - if (!dictionary_->isMember(kCvdFiles)) { - return {}; - } - const auto& json_files = (*dictionary_)[kCvdFiles]; - for (auto it = json_files.begin(); it != json_files.end(); it++) { - auto file = it.key().asString(); - auto expected_pos = file.size() - suffix.size(); - if (file.rfind(suffix) == expected_pos) { - return file; - } - } - LOG(ERROR) << "Could not find file ending in " << suffix; - return ""; -} - -} // namespace cvd diff --git a/host/libs/config/fetcher_config.h b/host/libs/config/fetcher_config.h deleted file mode 100644 index 825fbc60..00000000 --- a/host/libs/config/fetcher_config.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <map> -#include <ostream> -#include <string> - -namespace Json { -class Value; -} - -namespace cvd { - -// Order in enum is not guaranteed to be stable, serialized as a string. -enum FileSource { - UNKNOWN_PURPOSE = 0, - DEFAULT_BUILD, - SYSTEM_BUILD, - KERNEL_BUILD, - LOCAL_FILE, - GENERATED, -}; - -/* - * Attempts to answer the general question "where did this file come from, and - * what purpose is it serving? - */ -struct CvdFile { - FileSource source; - std::string build_id; - std::string build_target; - std::string file_path; - - CvdFile(); - CvdFile(const FileSource& source, const std::string& build_id, - const std::string& build_target, const std::string& file_path); -}; - -std::ostream& operator<<(std::ostream&, const CvdFile&); - -/** - * A report of state to transfer from fetch_cvd to downstream consumers. - * - * This includes data intended for programmatic access by other tools such as - * assemble_cvd. assemble_cvd can use signals like that multiple build IDs are - * present to judge that it needs to do super image remixing or rebuilding the - * boot image for a new kernel. - * - * The output json also includes data relevant for human debugging, like which - * flags fetch_cvd was invoked with. - */ -class FetcherConfig { - std::unique_ptr<Json::Value> dictionary_; -public: - FetcherConfig(); - FetcherConfig(FetcherConfig&&); - ~FetcherConfig(); - - bool SaveToFile(const std::string& file) const; - bool LoadFromFile(const std::string& file); - - // For debugging only, not intended for programmatic access. - void RecordFlags(); - - bool add_cvd_file(const CvdFile& file, bool override_entry = false); - std::map<std::string, CvdFile> get_cvd_files() const; - - std::string FindCvdFileWithSuffix(const std::string& suffix) const; -}; - -} // namespace cvd diff --git a/host/libs/vm_manager/Android.bp b/host/libs/vm_manager/Android.bp deleted file mode 100644 index 61cda54c..00000000 --- a/host/libs/vm_manager/Android.bp +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (C) 2017 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. - -cc_library_host_static { - name: "libcuttlefish_vm_manager", - srcs: [ - "crosvm_manager.cpp", - "qemu_manager.cpp", - "vm_manager.cpp", - ], - header_libs: [ - "cuttlefish_glog", - ], - shared_libs: [ - "libcuttlefish_fs", - "libcuttlefish_utils", - "libbase", - "libicuuc", - ], - static_libs: [ - "libxml2", - "libcuttlefish_host_config", - "libjsoncpp", - ], - defaults: ["cuttlefish_host_only"], -} - -sh_binary_host { - name: "cf_qemu.sh", - src: "cf_qemu.sh", -} diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh deleted file mode 100755 index 969332d6..00000000 --- a/host/libs/vm_manager/cf_qemu.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/bin/bash - -# -# Copyright (C) 2018 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. -# - -print_command() { - binary=$1; shift - binary_args=("$@") - printf %s "${binary}" - for i in "${binary_args[@]}"; do - case "$i" in - -*) printf "\\%s %s " $'\n' "$i" ;; - *) printf "%s " "$i" ;; - esac - done - echo -} - -exec_run() { - binary=$1; shift - binary_args=("$@") - print_command "${binary}" "${binary_args[@]}" - exec "${binary}" "${binary_args[@]}" -} - -run() { - binary=$1; shift - binary_args=("$@") - print_command "${binary}" "${binary_args[@]}" - "${binary}" "${binary_args[@]}" -} - -default_instance_number() { - if [[ "${USER::5}" == "vsoc-" ]]; then - echo "${USER: -2}" - else - echo "01" - fi -} -CUTTLEFISH_INSTANCE="${CUTTLEFISH_INSTANCE:-$(default_instance_number)}" -default_instance_name="cvd-${CUTTLEFISH_INSTANCE}" -default_uuid="699acfc4-c8c4-11e7-882b-5065f31dc1${CUTTLEFISH_INSTANCE}" -default_dir="${HOME}/cuttlefish_runtime" -default_internal_dir="${default_internal_dir}" -default_mobile_tap_name="cvd-mtap-${CUTTLEFISH_INSTANCE}" -default_wifi_tap_name="cvd-wtap-${CUTTLEFISH_INSTANCE}" - -qemu_binary=${qemu_binary=/usr/bin/qemu-system-x86_64} -dtc_binary=${dtc_binary:-dtc} - -if [[ "${qemu_binary##*/}" = "qemu-system-aarch64" ]]; then - # On ARM, the early console can be PCI, and ISA is not supported - kernel_console_serial="pci-serial" - machine="virt,gic_version=2" - cpu=cortex-a53 -else - # On x86, the early console must be ISA, not PCI, so we start to get kernel - # messages as soon as possible. ISA devices do not have 'addr' assignments. - kernel_console_serial="isa-serial" - machine="pc-i440fx-2.8,accel=kvm" - cpu=host -fi - -# Put anything here that might affect the machine configuration generated by -# QEMU. Anything which connects statefully to another service (like a socket) -# should be added in another section below. -args=( - -name "guest=${instance_name:-${default_instance_name}},debug-threads=on" - -machine "${machine},usb=off,dump-guest-core=off" - -m "${memory_mb:-2048}" - -realtime mlock=off - -smp "${cpus:-2},sockets=${cpus:-2},cores=1,threads=1" - -uuid "${uuid:-${default_uuid}}" - -display none - -no-user-config - -nodefaults - -rtc "base=utc" - -no-shutdown - -boot "strict=on" - -kernel "${kernel_image_path:-${HOME}/kernel}" - -append "${kernel_cmdline:-"loop.max_part=7 console=ttyS0 androidboot.console=ttyS1 androidboot.hardware=vsoc enforcing=0 audit=1 androidboot.selinux=permissive mac80211_hwsim.radios=0 security=selinux buildvariant=userdebug androidboot.serialno=CUTTLEFISHCVD01 androidboot.lcd_density=160 androidboot.boot_devices=pci0000:00/0000:00:03.0"}" - -device "piix3-usb-uhci,id=usb,addr=0x1.0x2" - -device "virtio-serial-pci,id=virtio-serial0" -) - -IFS=';' read -ra virtual_disk_array <<< "$virtual_disk_paths" -virtual_disk_index=0 -for virtual_disk in "${virtual_disk_array[@]}"; do - if [[ $virtual_disk_index == 0 ]]; then - bootindex=",bootindex=1" - else - bootindex="" - fi - args+=( - -drive "file=${virtual_disk},format=raw,if=none,id=drive-virtio-disk${virtual_disk_index},aio=threads" - -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk${virtual_disk_index},id=virtio-disk${virtual_disk_index}${bootindex}" - ) - virtual_disk_index=$((virtual_disk_index + 1)) -done - -args+=( - -netdev "tap,id=hostnet0,ifname=${wifi_tap_name:-${default_wifi_tap_name}},script=no,downscript=no" - -device "virtio-net-pci,netdev=hostnet0,id=net0" - -netdev "tap,id=hostnet1,ifname=${mobile_tap_name:-${default_mobile_tap_name}},script=no,downscript=no" - -device "virtio-net-pci,netdev=hostnet1,id=net1" - -device "virtio-balloon-pci,id=balloon0" - -object "rng-random,id=objrng0,filename=/dev/urandom" - -device "virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=1024,period=2000" - -cpu "${cpu}" - -msg "timestamp=on" - -device "AC97" -) - -# The services providing these sockets don't expect multiple connections, -# so we must not have them in 'args' when we dump the machine FDT. It's -# OK to add them now, after the dumping and patching has completed. -# The (maybe patched) DTB can also be provided now. - -if [[ "${use_bootloader}" = "true" ]]; then - args+=( - -bios "${bootloader}" - ) -fi - -args+=( - -chardev "socket,id=charmonitor,path=${monitor_path:-${default_internal_dir}/qemu_monitor.sock},server,nowait" - -mon "chardev=charmonitor,id=monitor,mode=control" - -chardev "file,id=charserial0,path=${kernel_log_pipe_name:-${default_internal_dir}/kernel-log},append=on" - -device "${kernel_console_serial},chardev=charserial0,id=serial0" - -chardev "socket,id=charserial1,path=${console_path:-${default_dir}/console},server,nowait" - -device "${kernel_console_serial},chardev=charserial1,id=serial1" -) - -if [[ "${logcat_mode}" == "serial" ]]; then - args+=( - -chardev "file,id=charchannel0,path=${logcat_path:-${default_dir}/logcat},append=on" - -device "virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=cf-logcat" - ) -fi - -if [[ -n "${gdb_flag}" ]]; then - args+=(-gdb "${gdb_flag}") -fi - -if [[ -n "${ramdisk_image_path}" ]]; then - args+=(-initrd "${ramdisk_image_path}") -fi - -if [[ -n "${usb_v1_socket_name}" ]]; then - args+=( - -chardev "socket,id=charchannel1,path=${usb_v1_socket_name:-${default_internal_dir}/usb-v1}" - -device "virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=cf-gadget-usb-v1" - ) -fi - -if [[ ${vsock_guest_cid:-0} -gt 2 ]]; then - args+=(-device "vhost-vsock-pci,guest-cid=${vsock_guest_cid}") -fi - -export QEMU_AUDIO_DRV=none -exec_run "${qemu_binary}" "${args[@]}" diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp deleted file mode 100644 index 6ed43c21..00000000 --- a/host/libs/vm_manager/crosvm_manager.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/libs/vm_manager/crosvm_manager.h" - -#include <sys/stat.h> -#include <sys/types.h> - -#include <string> -#include <vector> - -#include <android-base/strings.h> -#include <glog/logging.h> - -#include "common/libs/utils/network.h" -#include "common/libs/utils/subprocess.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/vm_manager/qemu_manager.h" - -namespace vm_manager { - -namespace { - -std::string GetControlSocketPath(const vsoc::CuttlefishConfig* config) { - return config->PerInstanceInternalPath("crosvm_control.sock"); -} - -void AddTapFdParameter(cvd::Command* crosvm_cmd, const std::string& tap_name) { - auto tap_fd = cvd::OpenTapInterface(tap_name); - if (tap_fd->IsOpen()) { - crosvm_cmd->AddParameter("--tap-fd=", tap_fd); - } else { - LOG(ERROR) << "Unable to connect to " << tap_name << ": " - << tap_fd->StrError(); - } -} - -bool Stop() { - auto config = vsoc::CuttlefishConfig::Get(); - cvd::Command command(config->crosvm_binary()); - command.AddParameter("stop"); - command.AddParameter(GetControlSocketPath(config)); - - auto process = command.Start(); - - return process.Wait() == 0; -} - -} // namespace - -const std::string CrosvmManager::name() { return "crosvm"; } - -std::vector<std::string> CrosvmManager::ConfigureGpu(const std::string& gpu_mode) { - // Override the default HAL search paths in all cases. We do this because - // the HAL search path allows for fallbacks, and fallbacks in conjunction - // with properities lead to non-deterministic behavior while loading the - // HALs. - if (gpu_mode == vsoc::kGpuModeDrmVirgl) { - return { - "androidboot.hardware.gralloc=minigbm", - "androidboot.hardware.hwcomposer=drm_minigbm", - "androidboot.hardware.egl=mesa", - }; - } - if (gpu_mode == vsoc::kGpuModeGuestSwiftshader) { - return { - "androidboot.hardware.gralloc=cutf_ashmem", - "androidboot.hardware.hwcomposer=cutf_cvm_ashmem", - "androidboot.hardware.egl=swiftshader", - "androidboot.hardware.vulkan=pastel", - }; - } - return {}; -} - -std::vector<std::string> CrosvmManager::ConfigureBootDevices() { - // PCI domain 0, bus 0, device 1, function 0 - // TODO There is no way to control this assignment with crosvm (yet) - return { "androidboot.boot_devices=pci0000:00/0000:00:01.0" }; -} - -CrosvmManager::CrosvmManager(const vsoc::CuttlefishConfig* config) - : VmManager(config) {} - -std::vector<cvd::Command> CrosvmManager::StartCommands() { - cvd::Command crosvm_cmd(config_->crosvm_binary(), [](cvd::Subprocess* proc) { - auto stopped = Stop(); - if (stopped) { - return true; - } - LOG(WARNING) << "Failed to stop VMM nicely, attempting to KILL"; - return KillSubprocess(proc); - }); - crosvm_cmd.AddParameter("run"); - - if (config_->gpu_mode() != vsoc::kGpuModeGuestSwiftshader) { - crosvm_cmd.AddParameter("--gpu"); - if (config_->wayland_socket().size()) { - crosvm_cmd.AddParameter("--wayland-sock=", config_->wayland_socket()); - } - if (config_->x_display().size()) { - crosvm_cmd.AddParameter("--x-display=", config_->x_display()); - } - } - if (!config_->final_ramdisk_path().empty()) { - crosvm_cmd.AddParameter("--initrd=", config_->final_ramdisk_path()); - } - crosvm_cmd.AddParameter("--null-audio"); - crosvm_cmd.AddParameter("--mem=", config_->memory_mb()); - crosvm_cmd.AddParameter("--cpus=", config_->cpus()); - crosvm_cmd.AddParameter("--params=", kernel_cmdline_); - for (const auto& disk : config_->virtual_disk_paths()) { - crosvm_cmd.AddParameter("--rwdisk=", disk); - } - crosvm_cmd.AddParameter("--socket=", GetControlSocketPath(config_)); - - if (frontend_enabled_) { - crosvm_cmd.AddParameter("--single-touch=", config_->touch_socket_path(), - ":", config_->x_res(), ":", config_->y_res()); - crosvm_cmd.AddParameter("--keyboard=", config_->keyboard_socket_path()); - } - - AddTapFdParameter(&crosvm_cmd, config_->wifi_tap_name()); - AddTapFdParameter(&crosvm_cmd, config_->mobile_tap_name()); - - // TODO remove this (use crosvm's seccomp files) - crosvm_cmd.AddParameter("--disable-sandbox"); - - if (config_->vsock_guest_cid() >= 2) { - crosvm_cmd.AddParameter("--cid=", config_->vsock_guest_cid()); - } - - // Redirect the first serial port with the kernel logs to the appropriate file - crosvm_cmd.AddParameter("--serial=num=1,type=file,path=", - config_->kernel_log_pipe_name(), ",console=true"); - - // Redirect standard input to a pipe for the console forwarder host process - // to handle. - cvd::SharedFD console_in_rd, console_in_wr; - if (!cvd::SharedFD::Pipe(&console_in_rd, &console_in_wr)) { - LOG(ERROR) << "Failed to create console pipe for crosvm's stdin: " - << console_in_rd->StrError(); - return {}; - } - auto console_pipe_name = config_->console_pipe_name(); - if (mkfifo(console_pipe_name.c_str(), 0660) != 0) { - auto error = errno; - LOG(ERROR) << "Failed to create console fifo for crosvm: " - << strerror(error); - return {}; - } - - // This fd will only be read from, but it's open with write access as well to - // keep the pipe open in case the subprocesses exit. - cvd::SharedFD console_out_rd = - cvd::SharedFD::Open(console_pipe_name.c_str(), O_RDWR); - if (!console_out_rd->IsOpen()) { - LOG(ERROR) << "Failed to open console fifo for reads: " - << console_out_rd->StrError(); - return {}; - } - // stdin is the only currently supported way to write data to a serial port in - // crosvm. A file (named pipe) is used here instead of stdout to ensure only - // the serial port output is received by the console forwarder as crosvm may - // print other messages to stdout. - crosvm_cmd.AddParameter("--serial=num=2,type=file,path=", console_pipe_name, - ",stdin=true"); - - crosvm_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdIn, - console_in_rd); - cvd::Command console_cmd(config_->console_forwarder_binary()); - console_cmd.AddParameter("--console_in_fd=", console_in_wr); - console_cmd.AddParameter("--console_out_fd=", console_out_rd); - - // This needs to be the last parameter - crosvm_cmd.AddParameter(config_->GetKernelImageToUse()); - - std::vector<cvd::Command> ret; - ret.push_back(std::move(crosvm_cmd)); - ret.push_back(std::move(console_cmd)); - return ret; -} - -} // namespace vm_manager diff --git a/host/libs/vm_manager/crosvm_manager.h b/host/libs/vm_manager/crosvm_manager.h deleted file mode 100644 index 848f2ae4..00000000 --- a/host/libs/vm_manager/crosvm_manager.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> -#include <vector> - -#include "host/libs/vm_manager/vm_manager.h" - -#include "common/libs/fs/shared_fd.h" -#include "common/libs/utils/subprocess.h" - -namespace vm_manager { - -// Starts a guest VM with crosvm. It requires the host package to support the -// qemu-cli capability (for network only). -class CrosvmManager : public VmManager { - public: - static const std::string name(); - static bool EnsureInstanceDirExists(const std::string& instance_dir); - static std::vector<std::string> ConfigureGpu(const std::string& gpu_mode); - static std::vector<std::string> ConfigureBootDevices(); - - CrosvmManager(const vsoc::CuttlefishConfig* config); - virtual ~CrosvmManager() = default; - - std::vector<cvd::Command> StartCommands() override; -}; - -} // namespace vm_manager diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp deleted file mode 100644 index 45e3003a..00000000 --- a/host/libs/vm_manager/qemu_manager.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/libs/vm_manager/qemu_manager.h" - -#include <string.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/un.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <cstdlib> -#include <sstream> -#include <string> -#include <thread> -#include <vector> - -#include <android-base/strings.h> -#include <glog/logging.h> - -#include "common/libs/fs/shared_select.h" -#include "common/libs/utils/files.h" -#include "common/libs/utils/subprocess.h" -#include "common/libs/utils/users.h" -#include "host/libs/config/cuttlefish_config.h" - -namespace vm_manager { - -namespace { - -std::string GetMonitorPath(const vsoc::CuttlefishConfig* config) { - return config->PerInstanceInternalPath("qemu_monitor.sock"); -} - -void LogAndSetEnv(const char* key, const std::string& value) { - setenv(key, value.c_str(), 1); - LOG(INFO) << key << "=" << value; -} - -std::string JoinString(const std::vector<std::string>& args, - const std::string& delim) { - bool first = true; - std::stringstream output; - for (const auto& arg : args) { - if (first) { - first = false; - } else { - output << delim; - } - output << arg; - } - return output.str(); -} - -bool Stop() { - auto config = vsoc::CuttlefishConfig::Get(); - auto monitor_path = GetMonitorPath(config); - auto monitor_sock = cvd::SharedFD::SocketLocalClient( - monitor_path.c_str(), false, SOCK_STREAM); - - if (!monitor_sock->IsOpen()) { - LOG(ERROR) << "The connection to qemu is closed, is it still running?"; - return false; - } - char msg[] = "{\"execute\":\"qmp_capabilities\"}{\"execute\":\"quit\"}"; - ssize_t len = sizeof(msg) - 1; - while (len > 0) { - int tmp = monitor_sock->Write(msg, len); - if (tmp < 0) { - LOG(ERROR) << "Error writing to socket: " << monitor_sock->StrError(); - return false; - } - len -= tmp; - } - // Log the reply - char buff[1000]; - while ((len = monitor_sock->Read(buff, sizeof(buff) - 1)) > 0) { - buff[len] = '\0'; - LOG(INFO) << "From qemu monitor: " << buff; - } - - return true; -} - -} // namespace - -const std::string QemuManager::name() { return "qemu_cli"; } - -std::vector<std::string> QemuManager::ConfigureGpu(const std::string& gpu_mode) { - if (gpu_mode != vsoc::kGpuModeGuestSwiftshader) { - return {}; - } - // Override the default HAL search paths in all cases. We do this because - // the HAL search path allows for fallbacks, and fallbacks in conjunction - // with properities lead to non-deterministic behavior while loading the - // HALs. - return { - "androidboot.hardware.gralloc=cutf_ashmem", - "androidboot.hardware.hwcomposer=cutf_cvm_ashmem", - "androidboot.hardware.egl=swiftshader", - "androidboot.hardware.vulkan=pastel", - }; -} - -std::vector<std::string> QemuManager::ConfigureBootDevices() { - // PCI domain 0, bus 0, device 3, function 0 - // This is controlled with 'addr=0x3' in cf_qemu.sh - return { "androidboot.boot_devices=pci0000:00/0000:00:03.0" }; -} - -QemuManager::QemuManager(const vsoc::CuttlefishConfig* config) - : VmManager(config) {} - -std::vector<cvd::Command> QemuManager::StartCommands() { - // Set the config values in the environment - LogAndSetEnv("qemu_binary", config_->qemu_binary()); - LogAndSetEnv("instance_name", config_->instance_name()); - LogAndSetEnv("memory_mb", std::to_string(config_->memory_mb())); - LogAndSetEnv("cpus", std::to_string(config_->cpus())); - LogAndSetEnv("uuid", config_->uuid()); - LogAndSetEnv("monitor_path", GetMonitorPath(config_)); - LogAndSetEnv("kernel_image_path", config_->GetKernelImageToUse()); - LogAndSetEnv("gdb_flag", config_->gdb_flag()); - LogAndSetEnv("ramdisk_image_path", config_->final_ramdisk_path()); - LogAndSetEnv("kernel_cmdline", kernel_cmdline_); - LogAndSetEnv("virtual_disk_paths", JoinString(config_->virtual_disk_paths(), - ";")); - LogAndSetEnv("wifi_tap_name", config_->wifi_tap_name()); - LogAndSetEnv("mobile_tap_name", config_->mobile_tap_name()); - LogAndSetEnv("kernel_log_pipe_name", - config_->kernel_log_pipe_name()); - LogAndSetEnv("console_path", config_->console_path()); - LogAndSetEnv("logcat_path", config_->logcat_path()); - LogAndSetEnv("usb_v1_socket_name", config_->usb_v1_socket_name()); - LogAndSetEnv("vsock_guest_cid", std::to_string(config_->vsock_guest_cid())); - LogAndSetEnv("logcat_mode", config_->logcat_mode()); - LogAndSetEnv("use_bootloader", config_->use_bootloader() ? "true" : "false"); - LogAndSetEnv("bootloader", config_->bootloader()); - - cvd::Command qemu_cmd(vsoc::DefaultHostArtifactsPath("bin/cf_qemu.sh"), - [](cvd::Subprocess* proc) { - auto stopped = Stop(); - if (stopped) { - return true; - } - LOG(WARNING) << "Failed to stop VMM nicely, " - << "attempting to KILL"; - return KillSubprocess(proc); - }); - std::vector<cvd::Command> ret; - ret.push_back(std::move(qemu_cmd)); - return ret; -} - -} // namespace vm_manager diff --git a/host/libs/vm_manager/qemu_manager.h b/host/libs/vm_manager/qemu_manager.h deleted file mode 100644 index 4b048762..00000000 --- a/host/libs/vm_manager/qemu_manager.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <string> -#include <vector> - -#include "host/libs/vm_manager/vm_manager.h" - -#include "common/libs/fs/shared_fd.h" - -namespace vm_manager { - -// Starts a guest VM using the qemu command directly. It requires the host -// package to support the qemu-cli capability. -class QemuManager : public VmManager { - public: - static const std::string name(); - static std::vector<std::string> ConfigureGpu(const std::string& gpu_mode); - static std::vector<std::string> ConfigureBootDevices(); - - QemuManager(const vsoc::CuttlefishConfig* config); - virtual ~QemuManager() = default; - - std::vector<cvd::Command> StartCommands() override; -}; - -} // namespace vm_manager diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp deleted file mode 100644 index 2ab41578..00000000 --- a/host/libs/vm_manager/vm_manager.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "host/libs/vm_manager/vm_manager.h" - -#include <memory> - -#include <glog/logging.h> -#include <sys/utsname.h> - -#include "common/libs/utils/users.h" -#include "host/libs/config/cuttlefish_config.h" -#include "host/libs/vm_manager/qemu_manager.h" -#include "host/libs/vm_manager/crosvm_manager.h" - -namespace vm_manager { - -VmManager::VmManager(const vsoc::CuttlefishConfig* config) - : config_(config) {} - -namespace{ -template <typename T> -VmManager* GetManagerSingleton(const vsoc::CuttlefishConfig* config) { - static std::shared_ptr<VmManager> vm_manager(new T(config)); - return vm_manager.get(); -} -} - -std::map<std::string, VmManager::VmManagerHelper> - VmManager::vm_manager_helpers_ = { - { - QemuManager::name(), - { - [](const vsoc::CuttlefishConfig* config) { - return GetManagerSingleton<QemuManager>(config); - }, - []() { return vsoc::HostSupportsQemuCli(); }, - [](const std::string& gpu_mode) { - return QemuManager::ConfigureGpu(gpu_mode); - }, - []() { - return QemuManager::ConfigureBootDevices(); - } - }, - }, - { - CrosvmManager::name(), - { - [](const vsoc::CuttlefishConfig* config) { - return GetManagerSingleton<CrosvmManager>(config); - }, - // Same as Qemu for the time being - []() { return vsoc::HostSupportsQemuCli(); }, - [](const std::string& gpu_mode) { - return CrosvmManager::ConfigureGpu(gpu_mode); - }, - []() { - return CrosvmManager::ConfigureBootDevices(); - } - } - } - }; - -VmManager* VmManager::Get(const std::string& vm_manager_name, - const vsoc::CuttlefishConfig* config) { - if (VmManager::IsValidName(vm_manager_name)) { - return vm_manager_helpers_[vm_manager_name].builder(config); - } - LOG(ERROR) << "Requested invalid VmManager: " << vm_manager_name; - return nullptr; -} - -bool VmManager::IsValidName(const std::string& name) { - return vm_manager_helpers_.count(name) > 0; -} - -bool VmManager::IsVmManagerSupported(const std::string& name) { - return VmManager::IsValidName(name) && - vm_manager_helpers_[name].support_checker(); -} - -std::vector<std::string> VmManager::ConfigureGpuMode( - const std::string& vmm_name, const std::string& gpu_mode) { - auto it = vm_manager_helpers_.find(vmm_name); - if (it == vm_manager_helpers_.end()) { - return {}; - } - return it->second.configure_gpu_mode(gpu_mode); -} - -std::vector<std::string> VmManager::ConfigureBootDevices( - const std::string& vmm_name) { - auto it = vm_manager_helpers_.find(vmm_name); - if (it == vm_manager_helpers_.end()) { - return {}; - } - return it->second.configure_boot_devices(); -} - -std::vector<std::string> VmManager::GetValidNames() { - std::vector<std::string> ret = {}; - for (const auto& key_val: vm_manager_helpers_) { - ret.push_back(key_val.first); - } - return ret; -} - -bool VmManager::UserInGroup(const std::string& group, - std::vector<std::string>* config_commands) { - if (!cvd::InGroup(group)) { - LOG(ERROR) << "User must be a member of " << group; - config_commands->push_back("# Add your user to the " + group + " group:"); - config_commands->push_back("sudo usermod -aG " + group + " $USER"); - return false; - } - return true; -} - -bool VmManager::LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands) { - struct utsname info; - if (!uname(&info)) { - char* digit = strtok(info.release, "+.-"); - int major = atoi(digit); - if (digit) { - digit = strtok(NULL, "+.-"); - int minor = atoi(digit); - if (major > 4 || (major == 4 && minor >= 8)) { - return true; - } - } - } - LOG(ERROR) << "Kernel version must be >=4.8"; - config_commands->push_back("# Please upgrade your kernel to >=4.8"); - return false; -} - -bool VmManager::ValidateHostConfiguration( - std::vector<std::string>* config_commands) const { - // the check for cvdnetwork needs to happen even if the user is not in kvm, so - // we can't just say UserInGroup("kvm") && UserInGroup("cvdnetwork") - auto in_kvm = VmManager::UserInGroup("kvm", config_commands); - auto in_cvdnetwork = VmManager::UserInGroup("cvdnetwork", config_commands); - auto linux_ver_4_8 = VmManager::LinuxVersionAtLeast4_8(config_commands); - return in_kvm && in_cvdnetwork && linux_ver_4_8; -} - -void VmManager::WithFrontend(bool enabled) { - frontend_enabled_ = enabled; -} - -void VmManager::WithKernelCommandLine(const std::string& kernel_cmdline) { - kernel_cmdline_ = kernel_cmdline; -} - -} // namespace vm_manager diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h deleted file mode 100644 index a14ad05d..00000000 --- a/host/libs/vm_manager/vm_manager.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <map> -#include <set> -#include <string> -#include <utility> -#include <vector> - -#include <common/libs/utils/subprocess.h> -#include <host/libs/config/cuttlefish_config.h> - -namespace vm_manager { - -// Superclass of every guest VM manager. It provides a static getter that -// returns the requested vm manager as a singleton. -class VmManager { - public: - // Returns the most suitable vm manager as a singleton. It may return nullptr - // if the requested vm manager is not supported by the current version of the - // host packages - static VmManager* Get(const std::string& vm_manager_name, - const vsoc::CuttlefishConfig* config); - static bool IsValidName(const std::string& name); - static std::vector<std::string> ConfigureGpuMode( - const std::string& vmm_name, const std::string& gpu_mode); - static std::vector<std::string> ConfigureBootDevices( - const std::string& vmm_name); - static bool IsVmManagerSupported(const std::string& name); - static std::vector<std::string> GetValidNames(); - - virtual ~VmManager() = default; - - virtual void WithFrontend(bool); - virtual void WithKernelCommandLine(const std::string&); - - // Starts the VMM. It will usually build a command and pass it to the - // command_starter function, although it may start more than one. The - // command_starter function allows to customize the way vmm commands are - // started/tracked/etc. - virtual std::vector<cvd::Command> StartCommands() = 0; - - virtual bool ValidateHostConfiguration( - std::vector<std::string>* config_commands) const; - - protected: - static bool UserInGroup(const std::string& group, - std::vector<std::string>* config_commands); - static bool LinuxVersionAtLeast4_8(std::vector<std::string>* config_commands); - - const vsoc::CuttlefishConfig* config_; - VmManager(const vsoc::CuttlefishConfig* config); - - bool frontend_enabled_; - std::string kernel_cmdline_; - - private: - struct VmManagerHelper { - // The singleton implementation - std::function<VmManager*(const vsoc::CuttlefishConfig*)> builder; - // Whether the host packages support this vm manager - std::function<bool()> support_checker; - std::function<std::vector<std::string>(const std::string&)> configure_gpu_mode; - std::function<std::vector<std::string>()> configure_boot_devices; - }; - // Asociates a vm manager helper to every valid vm manager name - static std::map<std::string, VmManagerHelper> vm_manager_helpers_; -}; - -} // namespace vm_manager diff --git a/tests/Android.mk b/tests/Android.mk deleted file mode 100644 index 337f5b90..00000000 --- a/tests/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (C) 2017 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. - -LOCAL_PATH:= $(call my-dir) -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/hidl/Android.bp b/tests/hidl/Android.bp deleted file mode 100644 index a1827e31..00000000 --- a/tests/hidl/Android.bp +++ /dev/null @@ -1,13 +0,0 @@ -cc_test { - name: "hidl_implementation_test", - srcs: ["hidl_implementation_test.cpp"], - static_libs: [ - "libhidlmetadata", - "libhidl-gen-utils", - ], - shared_libs: [ - "libbase", - "libvintf", - ], - test_suites: ["device-tests"], -} diff --git a/tests/hidl/OWNERS b/tests/hidl/OWNERS deleted file mode 100644 index 40164aae..00000000 --- a/tests/hidl/OWNERS +++ /dev/null @@ -1 +0,0 @@ -smoreland@google.com diff --git a/tests/hidl/hidl_implementation_test.cpp b/tests/hidl/hidl_implementation_test.cpp deleted file mode 100644 index 3eedc96e..00000000 --- a/tests/hidl/hidl_implementation_test.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <android-base/logging.h> -#include <gtest/gtest.h> -#include <hidl/metadata.h> -#include <hidl-util/FQName.h> -#include <vintf/VintfObject.h> - -using namespace android; - -static const std::set<std::string> kKnownMissing = { - "android.frameworks.bufferhub@1.0", - "android.frameworks.cameraservice.device@2.0", - "android.frameworks.vr.composer@1.0", - "android.frameworks.vr.composer@2.0", - "android.hardware.audio@2.0", - "android.hardware.audio@4.0", - "android.hardware.audio@6.0", - "android.hardware.audio.effect@2.0", - "android.hardware.audio.effect@4.0", - "android.hardware.audio.effect@6.0", - "android.hardware.automotive.audiocontrol@1.0", - "android.hardware.automotive.can@1.0", - "android.hardware.automotive.evs@1.0", - "android.hardware.automotive.evs@1.1", - "android.hardware.automotive.vehicle@2.0", - "android.hardware.biometrics.face@1.0", - "android.hardware.biometrics.fingerprint@2.1", - "android.hardware.bluetooth.a2dp@1.0", - "android.hardware.broadcastradio@1.1", - "android.hardware.broadcastradio@2.0", - "android.hardware.camera.provider@2.5", - "android.hardware.cas@1.2", - "android.hardware.cas.native@1.0", - "android.hardware.confirmationui@1.0", - "android.hardware.contexthub@1.0", - "android.hardware.fastboot@1.0", - "android.hardware.gnss.measurement_corrections@1.0", - "android.hardware.gnss.visibility_control@1.0", - "android.hardware.graphics.allocator@3.0", - "android.hardware.graphics.allocator@4.0", - "android.hardware.graphics.bufferqueue@1.0", - "android.hardware.graphics.bufferqueue@2.0", - "android.hardware.graphics.composer@2.3", - "android.hardware.graphics.composer@2.4", - "android.hardware.graphics.mapper@3.0", - "android.hardware.graphics.mapper@4.0", - "android.hardware.health@1.0", - "android.hardware.ir@1.0", - "android.hardware.keymaster@3.0", - "android.hardware.media.bufferpool@1.0", - "android.hardware.media.bufferpool@2.0", - "android.hardware.memtrack@1.0", - "android.hardware.nfc@1.2", - "android.hardware.oemlock@1.0", - "android.hardware.power@1.3", - "android.hardware.radio.deprecated@1.0", - "android.hardware.renderscript@1.0", - "android.hardware.secure_element@1.1", - "android.hardware.sensors@1.0", - "android.hardware.soundtrigger@2.2", - "android.hardware.tetheroffload.config@1.0", - "android.hardware.tetheroffload.control@1.0", - "android.hardware.thermal@1.1", - "android.hardware.tv.cec@1.0", - "android.hardware.tv.cec@2.0", - "android.hardware.tv.input@1.0", - "android.hardware.tv.tuner@1.0", - "android.hardware.usb@1.2", - "android.hardware.usb.gadget@1.0", - "android.hardware.vibrator@1.3", - "android.hardware.vr@1.0", - "android.hardware.weaver@1.0", - "android.hardware.wifi@1.3", - "android.hardware.wifi@1.4", - "android.hardware.wifi.hostapd@1.1", - "android.hardware.wifi.offload@1.0", - "android.hidl.base@1.0", - "android.hidl.memory.token@1.0", -}; - -// AOSP packages which are never considered -static bool isPackageWhitelist(const FQName& name) { - static std::vector<std::string> gAospExclude = { - // packages not implemented now that we never expect to be implemented - "android.hardware.tests", - // packages not registered with hwservicemanager, usually sub-interfaces - "android.hardware.camera.device", - }; - for (const std::string& package : gAospExclude) { - if (name.inPackage(package)) { - return true; - } - } - return false; -} - -static bool isAospInterface(const FQName& name) { - static std::vector<std::string> gAospPackages = { - "android.hidl", - "android.hardware", - "android.frameworks", - "android.system", - }; - for (const std::string& package : gAospPackages) { - if (name.inPackage(package) && !isPackageWhitelist(name)) { - return true; - } - } - return false; -} - -static std::set<FQName> allTreeInterfaces() { - std::set<FQName> ret; - for (const auto& iface : HidlInterfaceMetadata::all()) { - FQName f; - CHECK(f.setTo(iface.name)) << iface.name; - ret.insert(f); - } - return ret; -} - -static std::set<FQName> allManifestInstances() { - std::set<FQName> ret; - auto setInserter = [&] (const vintf::ManifestInstance& i) -> bool { - if (i.format() != vintf::HalFormat::HIDL) { - std::cout << "[ WARNING ] Not checking non-HIDL instance: " << i.description() << std::endl; - return true; // continue - } - ret.insert(i.getFqInstance().getFqName()); - return true; // continue - }; - vintf::VintfObject::GetDeviceHalManifest()->forEachInstance(setInserter); - vintf::VintfObject::GetFrameworkHalManifest()->forEachInstance(setInserter); - return ret; -} - -TEST(Hidl, IsAospDevice) { - for (const FQName& name : allManifestInstances()) { - EXPECT_TRUE(isAospInterface(name)) << name.string(); - } -} - -TEST(Hidl, InterfacesImplemented) { - // instances -> major version -> minor versions - std::map<std::string, std::map<size_t, std::set<size_t>>> unimplemented; - - for (const FQName& f : allTreeInterfaces()) { - if (!isAospInterface(f)) continue; - - unimplemented[f.package()][f.getPackageMajorVersion()].insert(f.getPackageMinorVersion()); - } - - // we'll be removing items from this which we know are missing - // in order to be left with those elements which we thought we - // knew were missing but are actually present - std::set<std::string> thoughtMissing = kKnownMissing; - - for (const FQName& f : allManifestInstances()) { - if (thoughtMissing.erase(f.getPackageAndVersion().string()) > 0) { - std::cout << "[ WARNING ] Instance in missing list, but available: " << f.string() << std::endl; - } - - std::set<size_t>& minors = unimplemented[f.package()][f.getPackageMajorVersion()]; - size_t minor = f.getPackageMinorVersion(); - - auto it = minors.find(minor); - if (it == minors.end()) continue; - - // if 1.2 is implemented, also considere 1.0, 1.1 implemented - minors.erase(minors.begin(), std::next(it)); - } - - for (const auto& [package, minorsPerMajor] : unimplemented) { - for (const auto& [major, minors] : minorsPerMajor) { - if (minors.empty()) continue; - - size_t maxMinor = *minors.rbegin(); - - FQName missing; - ASSERT_TRUE(missing.setTo(package, major, maxMinor)); - - if (thoughtMissing.erase(missing.string()) > 0) continue; - - ADD_FAILURE() << "Missing implementation from " << missing.string(); - } - } - - for (const std::string& missing : thoughtMissing) { - std::cout << "[ WARNING ] Instance in missing list, and cannot find it anywhere: " << missing << std::endl; - } -} diff --git a/tests/ril/Android.mk b/tests/ril/Android.mk deleted file mode 100644 index 178e916d..00000000 --- a/tests/ril/Android.mk +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2017 Google Inc. All Rights Reserved. -# -# 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. - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 24; echo $$?)) - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -# Only compile source java files in this apk. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CuttlefishRilTests -LOCAL_SDK_VERSION := current -LOCAL_CERTIFICATE := platform -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?)) -LOCAL_JAVA_LIBRARIES := android.test.runner.stubs -else -LOCAL_JAVA_LIBRARIES := android.test.runner -endif -LOCAL_STATIC_JAVA_LIBRARIES := android-support-test espresso-core - -LOCAL_STATIC_JAVA_LIBRARIES+=platform-test-annotations - -include $(BUILD_PACKAGE) - -endif diff --git a/tests/ril/AndroidManifest.xml b/tests/ril/AndroidManifest.xml deleted file mode 100644 index 462daa67..00000000 --- a/tests/ril/AndroidManifest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2017 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.cuttlefish.ril.tests" - android:versionCode="1" - android:versionName="1.0" - android:sharedUserId="android.uid.system"> - - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> - - <uses-sdk - android:minSdkVersion="19" - android:targetSdkVersion="25" /> - - <instrumentation - android:name="android.support.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.cuttlefish.ril.tests" /> - - <application> - <uses-library android:name="android.test.runner" /> - </application> - -</manifest> diff --git a/tests/ril/runtests.sh b/tests/ril/runtests.sh deleted file mode 100755 index d2714557..00000000 --- a/tests/ril/runtests.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -if [[ "$1" == "--help" ]]; then - cat <<END -Usage for $0 - - <no-args> run all tests - -r print raw results - -e class <class>[#<test>] run test/s specified by class - -Example: -$ $0 -r -e class com.android.cuttlefish.ril.RilE2eTests#testRilConnects -Run just the specified test, and show the raw output. -END - exit 0 -fi - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi - -set -e # fail early -make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk MODULES-IN-device-google-cuttlefish-tests-ril -adb wait-for-device -# Same as 'package' in manifest file -adb uninstall com.android.cuttlefish.ril.tests || true -adb install -r -g "$OUT/data/app/CuttlefishRilTests/CuttlefishRilTests.apk" -# optionally: -e class com.android.cuttlefish.ril.RilE2eTests#testName -adb shell am instrument -w "$@" 'com.android.cuttlefish.ril.tests/android.support.test.runner.AndroidJUnitRunner' diff --git a/tests/ril/src/com/android/cuttlefish/ril/tests/RilE2eTests.java b/tests/ril/src/com/android/cuttlefish/ril/tests/RilE2eTests.java deleted file mode 100644 index e09895f2..00000000 --- a/tests/ril/src/com/android/cuttlefish/ril/tests/RilE2eTests.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.cuttlefish.ril.tests; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkInfo; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.support.test.InstrumentationRegistry; -import android.telephony.CellInfoGsm; -import android.telephony.CellSignalStrengthGsm; -import android.telephony.TelephonyManager; -import android.util.Log; - -import static org.hamcrest.Matchers.greaterThan; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.net.Socket; -import java.util.List; - -/** - * Tests used to validate E2E RIL functionality. - */ -@RunWith(JUnit4.class) -public class RilE2eTests { - private static final String TAG = "RilE2eTests"; - private static final int MAX_POLL_DISABLED_WIFI_COUNT = 10; - private Context mContext; - private WifiManager mWifiManager; - private ConnectivityManager mConnManager; - private TelephonyManager mTeleManager; - - @Before - public void setUp() throws Exception { - mContext = InstrumentationRegistry.getInstrumentation().getContext(); - mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - mConnManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - mTeleManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE); - // There must not be an active wifi connection while running the test or else - // getActiveNetworkInfo() will return that instead of the telephony network. - // Turning wifi off should do the trick. - disableWifi(); - } - - - private void disableWifi() throws Exception { - Log.i(TAG, "Disabling WIFI..."); - - mWifiManager.setWifiEnabled(false); - int count = MAX_POLL_DISABLED_WIFI_COUNT; - while (mWifiManager.isWifiEnabled() && count-- > 0) { - Log.i(TAG, "Waiting for WIFI to be disabled..."); - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - if (count < 0) { - Log.e(TAG, "Reached max number of polls while waiting to disable wifi"); - throw new Exception("Timed out waiting for wifi to be disabled"); - } - } - - - /** - * Verify that RIL stack is able to get up and connect to network in - * 60 seconds. - */ - @Test(timeout = 10 * 1000) - public void testRilConnects() throws Exception { - while (true) { - NetworkInfo net = mConnManager.getActiveNetworkInfo(); - if (net != null && net.getType() == ConnectivityManager.TYPE_MOBILE) break; - - Log.i(TAG, "Waiting for MOBILE to become primary network for DATA."); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - - // Bind process to MOBILE network. This should allow us to verify network is functional. - Network net = mConnManager.getActiveNetwork(); - Assert.assertNotNull(net); - Assert.assertTrue(mConnManager.bindProcessToNetwork(net)); - - // Open connection to google.com servers. - try (Socket s = new Socket("google.com", 80)) { - Assert.assertTrue(s.isConnected()); - } - } - - - /** - * Verify that AVD is connected to our virtual network operator and is - * phone-, sms- and data capable. - */ - @Test - public void testBasicPhoneAttributes() throws Exception { - Assert.assertEquals("Android Virtual Operator", mTeleManager.getNetworkOperatorName()); - Assert.assertFalse(mTeleManager.isNetworkRoaming()); - Assert.assertTrue(mTeleManager.isSmsCapable()); - Assert.assertSame(TelephonyManager.NETWORK_TYPE_LTE, mTeleManager.getVoiceNetworkType()); - Assert.assertSame(TelephonyManager.SIM_STATE_READY, mTeleManager.getSimState()); - Assert.assertSame(TelephonyManager.PHONE_TYPE_GSM, mTeleManager.getPhoneType()); - Assert.assertSame(mTeleManager.getPhoneCount(), 1); - // See SIM FS response for 178 28480 (Cuttlefish RIL). - Assert.assertEquals("+15551234567", mTeleManager.getLine1Number()); - // See SIM FS response for 178 28615 (Cuttlefish RIL). - Assert.assertEquals("+15557654321", mTeleManager.getVoiceMailNumber()); - Assert.assertSame(TelephonyManager.DATA_CONNECTED, mTeleManager.getDataState()); - } - - // See b/74256305 - @Ignore - @Test - public void testSignalLevels() throws Exception { - CellInfoGsm cellinfogsm = (CellInfoGsm)mTeleManager.getAllCellInfo().get(0); - CellSignalStrengthGsm cellSignalStrengthGsm = cellinfogsm.getCellSignalStrength(); - int bars = cellSignalStrengthGsm.getLevel(); - Assert.assertThat("Signal Bars", bars, greaterThan(1)); - } -} diff --git a/tests/wifi/Android.mk b/tests/wifi/Android.mk deleted file mode 100644 index 50ba9093..00000000 --- a/tests/wifi/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2017 Google Inc. All Rights Reserved. -# -# 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. - -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 24; echo $$?)) -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -# Only compile source java files in this apk. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CuttlefishWifiTests -LOCAL_SDK_VERSION := current -LOCAL_CERTIFICATE := platform -ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?)) -LOCAL_JAVA_LIBRARIES := android.test.runner.stubs -else -LOCAL_JAVA_LIBRARIES := android.test.runner -endif -LOCAL_STATIC_JAVA_LIBRARIES := android-support-test platform-test-annotations - -include $(BUILD_PACKAGE) -endif diff --git a/tests/wifi/AndroidManifest.xml b/tests/wifi/AndroidManifest.xml deleted file mode 100644 index 0ff13884..00000000 --- a/tests/wifi/AndroidManifest.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2017 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. ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.cuttlefish.wifi.tests" - android:versionCode="1" - android:versionName="1.0" - android:sharedUserId="android.uid.system"> - - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> - - <uses-sdk - android:minSdkVersion="19" - android:targetSdkVersion="25" /> - - <instrumentation - android:name="android.support.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.cuttlefish.wifi.tests" /> - - <application> - <uses-library android:name="android.test.runner" /> - </application> - -</manifest> diff --git a/tests/wifi/runtests.sh b/tests/wifi/runtests.sh deleted file mode 100755 index c8679014..00000000 --- a/tests/wifi/runtests.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -if [[ "$1" == "--help" ]]; then - cat <<END -Usage for $0 - - <no-args> run all tests - -r print raw results - -e class <class>[#<test>] run test/s specified by class - -Example: -$ $0 -r -e class com.android.cuttlefish.wifi.WifiE2eTests#testWifiConnects -Run just the specified test, and show the raw output. -END - exit 0 -fi - -if [ -z $ANDROID_BUILD_TOP ]; then - echo "You need to source and lunch before you can use this script" - exit 1 -fi - -set -e # fail early -make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk CuttlefishWifiTests -adb wait-for-device -# Same as 'package' in manifest file -adb uninstall com.android.cuttlefish.wifi.tests || true -adb install -r -g "$OUT/data/app/CuttlefishWifiTests/CuttlefishWifiTests.apk" -# optionally: -e class com.android.cuttlefish.wifi.WifiE2eTests#testName -adb shell am instrument -w "$@" 'com.android.cuttlefish.wifi.tests/android.support.test.runner.AndroidJUnitRunner' diff --git a/tests/wifi/src/com/android/cuttlefish/wifi/tests/WifiE2eTests.java b/tests/wifi/src/com/android/cuttlefish/wifi/tests/WifiE2eTests.java deleted file mode 100644 index e3d9e708..00000000 --- a/tests/wifi/src/com/android/cuttlefish/wifi/tests/WifiE2eTests.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.cuttlefish.wifi.tests; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkInfo; -import android.net.ConnectivityManager; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.support.test.InstrumentationRegistry; -import android.util.Log; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.net.Socket; -import java.util.List; - -/** - * Tests used to validate E2E WIFI functionality. - */ -@RunWith(JUnit4.class) -public class WifiE2eTests { - private static final String TAG = "WifiE2eTests"; - private Context mContext; - private WifiManager mWifiManager; - private ConnectivityManager mConnManager; - - @Before - public void setUp() throws Exception { - mContext = InstrumentationRegistry.getInstrumentation().getContext(); - mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - mConnManager = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - } - - - private void enableWifi() { - Log.i(TAG, "Enabling WIFI..."); - mWifiManager.setWifiEnabled(true); - while (!(mWifiManager.isWifiEnabled() && mWifiManager.pingSupplicant())) { - Log.i(TAG, "Waiting for WIFI (Enabled: " + mWifiManager.isWifiEnabled() + - ", Ready: " + mWifiManager.pingSupplicant() + ")"); - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - } - - - private void disableWifi() { - Log.i(TAG, "Disabling WIFI..."); - - mWifiManager.setWifiEnabled(false); - while (mWifiManager.isWifiEnabled()) { - Log.i(TAG, "Waiting for WIFI to be disabled..."); - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - } - - - private void waitForSupplicantState(SupplicantState... expectedStates) { - while (true) { - WifiInfo info = mWifiManager.getConnectionInfo(); - SupplicantState currentState = info.getSupplicantState(); - - Log.i(TAG, "WIFI State: " + currentState); - for (SupplicantState state : expectedStates) { - if (currentState == state) { - Log.i(TAG, "WIFI is now in expected state."); - return; - } - } - - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - } - - - private void enableNetwork(String SSID) { - WifiConfiguration conf = new WifiConfiguration(); - conf.SSID = SSID; - conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - int networkId = mWifiManager.addNetwork(conf); - Assert.assertTrue(networkId >= 0); - mWifiManager.enableNetwork(networkId, false); - } - - - /** - * Initialize wifi, erase all settings. - */ - @Test(timeout = 10 * 1000) - public void testWifiInitialization() { - enableWifi(); - - List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); - Assert.assertNotNull(configs); - for (WifiConfiguration config : configs) { - Log.i(TAG, "Removing network " + config.networkId + ": " + config.SSID); - Assert.assertTrue(mWifiManager.disableNetwork(config.networkId)); - Assert.assertTrue(mWifiManager.removeNetwork(config.networkId)); - } - - waitForSupplicantState( - SupplicantState.INACTIVE, - SupplicantState.DISCONNECTED, - SupplicantState.SCANNING); - - disableWifi(); - } - - - /** - * Verify that WIFI stack is able to get up and connect to network in - * 60 seconds. - */ - @Test(timeout = 60 * 1000) - public void testWifiConnects() throws Exception { - // 1. Make sure we start with WIFI disabled. - // It could be, that WIFI is currently disabled anyway. - // Let's make sure that's the case. - disableWifi(); - - // 2. Wait until stack is up. - enableWifi(); - - // 3. Configure WIFI: - // - Add network, - // - Enable network, - // - Scan for network - Log.i(TAG, "Configuring WIFI..."); - enableNetwork("\"VirtWifi\""); - enableNetwork("\"AndroidWifi\""); - mWifiManager.startScan(); - - // 4. Wait until connected. - Log.i(TAG, "Waiting for connectivity..."); - waitForSupplicantState(SupplicantState.COMPLETED); - - // 5. Wait until WIFI is current network. - while (true) { - NetworkInfo net = mConnManager.getActiveNetworkInfo(); - if (net != null && net.getType() == ConnectivityManager.TYPE_WIFI) break; - - Log.i(TAG, "Waiting for WIFI to become primary network for DATA."); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - } - - // 6. Bind process to WIFI network. This should allow us to verify network is functional. - Network net = mConnManager.getActiveNetwork(); - Assert.assertNotNull(net); - Assert.assertTrue(mConnManager.bindProcessToNetwork(net)); - - // 7. Open connection to google.com servers. - try (Socket s = new Socket("google.com", 80)) { - Assert.assertTrue(s.isConnected()); - } - } -} diff --git a/tools/bazel.rc b/tools/bazel.rc deleted file mode 100644 index 6b32331c..00000000 --- a/tools/bazel.rc +++ /dev/null @@ -1,2 +0,0 @@ -test --client_env=CC=/usr/bin/clang-3.8 --color=yes --test_output all -build --client_env=CC=/usr/bin/clang-3.8 --color=yes diff --git a/tools/create_base_image.sh b/tools/create_base_image.sh deleted file mode 100755 index 950b9936..00000000 --- a/tools/create_base_image.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# Creates a base image suitable for booting cuttlefish on GCE - -source "${ANDROID_BUILD_TOP}/device/google/cuttlefish_common/tools/create_base_image_hostlib.sh" - -FLAGS "$@" || exit 1 -main "${FLAGS_ARGV[@]}" diff --git a/tools/create_base_image_arm.sh b/tools/create_base_image_arm.sh deleted file mode 100755 index b65600cc..00000000 --- a/tools/create_base_image_arm.sh +++ /dev/null @@ -1,620 +0,0 @@ -#!/bin/bash - -# Copyright 2019 Google Inc. All rights reserved. - -# 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. - -source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags" - -DEFINE_boolean p1 \ - false "Only generate/write the 1st partition (loader1)" "1" -DEFINE_boolean p2 \ - false "Only generate/write the 2nd partition (env)" "2" -DEFINE_boolean p3 \ - false "Only generate/write the 3rd partition (loader2)" "3" -DEFINE_boolean p4 \ - false "Only generate/write the 4th partition (trust)" "4" -DEFINE_boolean p5 \ - false "Only generate/write the 5th partition (rootfs)" "5" - -FLAGS_HELP="USAGE: $0 <KERNEL_DIR> [IMAGE] [flags]" - -FLAGS "$@" || exit $? -eval set -- "${FLAGS_ARGV}" - -if [ ${FLAGS_p1} -eq ${FLAGS_FALSE} ] && - [ ${FLAGS_p2} -eq ${FLAGS_FALSE} ] && - [ ${FLAGS_p3} -eq ${FLAGS_FALSE} ] && - [ ${FLAGS_p4} -eq ${FLAGS_FALSE} ] && - [ ${FLAGS_p5} -eq ${FLAGS_FALSE} ]; then - FLAGS_p1=${FLAGS_TRUE} - FLAGS_p2=${FLAGS_TRUE} - FLAGS_p3=${FLAGS_TRUE} - FLAGS_p4=${FLAGS_TRUE} - FLAGS_p5=${FLAGS_TRUE} -fi - -for arg in "$@" ; do - if [ -z $KERNEL_DIR ]; then - KERNEL_DIR=$arg - elif [ -z $IMAGE ]; then - IMAGE=$arg - else - flags_help - exit 1 - fi -done - -USE_IMAGE=`[ -z "${IMAGE}" ] && echo "0" || echo "1"` -OVERWRITE=`[ -e "${IMAGE}" ] && echo "1" || echo "0"` -if [ -z $KERNEL_DIR ]; then - flags_help - exit 1 -fi -if [ ! -e "${KERNEL_DIR}" ]; then - echo "error: can't find '${KERNEL_DIR}'. aborting..." - exit 1 -fi - -# escalate to superuser -if [ $UID -ne 0 ]; then - cd ${ANDROID_BUILD_TOP} - . ./build/envsetup.sh - lunch ${TARGET_PRODUCT}-${TARGET_BUILD_VARIANT} - mmma external/u-boot - cd - - exec sudo -E "${0}" ${@} -fi - -if [ $OVERWRITE -eq 1 ]; then - OVERWRITE_IMAGE=${IMAGE} - IMAGE=`mktemp` -fi - -if [ $USE_IMAGE -eq 0 ]; then - init_devs=`lsblk --nodeps -oNAME -n` - echo "Reinsert device (to write to) into PC" - while true; do - devs=`lsblk --nodeps -oNAME -n` - new_devs="$(echo -e "${init_devs}\n${devs}" | sort | uniq -u | awk 'NF')" - num_devs=`echo "${new_devs}" | wc -l` - if [[ "${new_devs}" == "" ]]; then - num_devs=0 - fi - if [[ ${num_devs} -gt 1 ]]; then - echo "error: too many new devices detected! aborting..." - exit 1 - fi - if [[ ${num_devs} -eq 1 ]]; then - if [[ "${new_devs}" != "${mmc_dev}" ]]; then - if [[ "${mmc_dev}" != "" ]]; then - echo "error: block device name mismatch ${new_devs} != ${mmc_dev}" - echo "Reinsert device (to write to) into PC" - fi - mmc_dev=${new_devs} - continue - fi - echo "${init_devs}" | grep "${mmc_dev}" >/dev/null - if [[ $? -eq 0 ]]; then - init_devs="${devs}" - continue - fi - break - fi - done - # now inform the user - echo "Detected device at /dev/${mmc_dev}" -fi - -if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then - cd ${ANDROID_BUILD_TOP}/external/arm-trusted-firmware - CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rk3399 DEBUG=0 ERROR_DEPRECATED=1 bl31 - export BL31="${ANDROID_BUILD_TOP}/external/arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf" - cd - -fi - -cd ${ANDROID_BUILD_TOP}/external/u-boot - -if [ ${FLAGS_p2} -eq ${FLAGS_TRUE} ]; then - tmpfile=`mktemp` - bootenv=`mktemp` - cat > ${tmpfile} << "EOF" -bootdelay=2 -baudrate=1500000 -scriptaddr=0x00500000 -boot_targets=mmc1 mmc0 -bootcmd=run distro_bootcmd -distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done -bootcmd_mmc0=devnum=0; run mmc_boot -bootcmd_mmc1=devnum=1; run mmc_boot -mmc_boot=if mmc dev ${devnum}; then ; run scan_for_boot_part; fi -scan_for_boot_part=part list mmc ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype mmc ${devnum}:${distro_bootpart} bootfstype; then run find_script; fi; done; setenv devplist; -find_script=if test -e mmc ${devnum}:${distro_bootpart} /boot/boot.scr; then echo Found U-Boot script /boot/boot.scr; run run_scr; fi -run_scr=load mmc ${devnum}:${distro_bootpart} ${scriptaddr} /boot/boot.scr; source ${scriptaddr} -EOF - script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - echo "Sha=`${script_dir}/gen_sha.sh --kernel ${KERNEL_DIR}`" >> ${tmpfile} - ${ANDROID_HOST_OUT}/bin/mkenvimage -s 32768 -o ${bootenv} - < ${tmpfile} -fi - -if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ] || [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then - make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- rock-pi-4-rk3399_defconfig - if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then - make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j`nproc` - fi - if [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then - make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- u-boot.itb - fi - if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then - idbloader=`mktemp` - ${ANDROID_HOST_OUT}/bin/mkimage -n rk3399 -T rksd -d tpl/u-boot-tpl.bin ${idbloader} - cat spl/u-boot-spl.bin >> ${idbloader} - fi -fi -cd - - -if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then - ${ANDROID_BUILD_TOP}/kernel/tests/net/test/build_rootfs.sh -a arm64 -s buster -n ${IMAGE} - if [ $? -ne 0 ]; then - echo "error: failed to build rootfs. exiting..." - exit 1 - fi - truncate -s +3G ${IMAGE} - e2fsck -f ${IMAGE} - resize2fs ${IMAGE} - - mntdir=`mktemp -d` - mount ${IMAGE} ${mntdir} - if [ $? != 0 ]; then - echo "error: unable to mount ${IMAGE} ${mntdir}" - exit 1 - fi - - cat > ${mntdir}/boot/boot.cmd << "EOF" -setenv bootcmd_dhcp ' -mw.b ${scriptaddr} 0 0x8000 -mmc dev 0 0 -mmc read ${scriptaddr} 0x1fc0 0x40 -env import -b ${scriptaddr} 0x8000 -mw.b ${scriptaddr} 0 0x8000 -if dhcp ${scriptaddr} manifest.txt; then - setenv OldSha ${Sha} - setenv Sha - env import -t ${scriptaddr} 0x8000 ManifestVersion - echo "Manifest version $ManifestVersion"; - if test "$ManifestVersion" = "1"; then - run manifest1 - elif test "$ManifestVersion" = "2"; then - run manifest2 - else - run manifestX - fi -fi' -setenv manifestX 'echo "***** ERROR: Unknown manifest version! *****";' -setenv manifest1 ' -env import -t ${scriptaddr} 0x8000 -if test "$Sha" != "$OldSha"; then - setenv serverip ${TftpServer} - setenv loadaddr 0x00200000 - mmc dev 0 0; - setenv file $TplSplImg; offset=0x40; size=0x1f80; run tftpget1; setenv TplSplImg - setenv file $UbootItb; offset=0x4000; size=0x2000; run tftpget1; setenv UbootItb - setenv file $TrustImg; offset=0x6000; size=0x2000; run tftpget1; setenv TrustImg - setenv file $RootfsImg; offset=0x8000; size=0; run tftpget1; setenv RootfsImg - setenv file $UbootEnv; offset=0x1fc0; size=0x40; run tftpget1; setenv UbootEnv - mw.b ${scriptaddr} 0 0x8000 - env export -b ${scriptaddr} 0x8000 - mmc write ${scriptaddr} 0x1fc0 0x40 -else - echo "Already have ${Sha}. Booting..." -fi' -setenv manifest2 ' -env import -t ${scriptaddr} 0x8000 -if test "$DFUethaddr" = "$ethaddr" || test "$DFUethaddr" = ""; then - if test "$Sha" != "$OldSha"; then - setenv serverip ${TftpServer} - setenv loadaddr 0x00200000 - mmc dev 0 0; - setenv file $TplSplImg; offset=0x40; size=0x1f80; run tftpget1; setenv TplSplImg - setenv file $UbootItb; offset=0x4000; size=0x2000; run tftpget1; setenv UbootItb - setenv file $TrustImg; offset=0x6000; size=0x2000; run tftpget1; setenv TrustImg - setenv file $RootfsImg; offset=0x8000; size=0; run tftpget1; setenv RootfsImg - setenv file $UbootEnv; offset=0x1fc0; size=0x40; run tftpget1; setenv UbootEnv - mw.b ${scriptaddr} 0 0x8000 - env export -b ${scriptaddr} 0x8000 - mmc write ${scriptaddr} 0x1fc0 0x40 - else - echo "Already have ${Sha}. Booting..." - fi -else - echo "Update ${Sha} is not for me. Booting..." -fi' -setenv tftpget1 ' -if test "$file" != ""; then - mw.b ${loadaddr} 0 0x400000 - tftp ${file} - if test $? = 0; then - setenv isGz 0 && setexpr isGz sub .*\\.gz\$ 1 ${file} - if test $isGz = 1; then - if test ${file} = ${UbootEnv}; then - echo "** gzipped env unsupported **" - else - setexpr boffset ${offset} * 0x200 - gzwrite mmc 0 ${loadaddr} 0x${filesize} 100000 ${boffset} && echo Updated: ${file} - fi - elif test ${file} = ${UbootEnv}; then - env import -b ${loadaddr} && echo Updated: ${file} - else - if test $size = 0; then - setexpr x $filesize - 1 - setexpr x $x / 0x1000 - setexpr x $x + 1 - setexpr x $x * 0x1000 - setexpr x $x / 0x200 - size=0x${x} - fi - mmc write ${loadaddr} ${offset} ${size} && echo Updated: ${file} - fi - fi - if test $? != 0; then - echo ** UPDATE FAILED: ${file} ** - fi -fi' -if mmc dev 1 0; then; else - run bootcmd_dhcp; -fi -load mmc ${devnum}:${distro_bootpart} 0x02080000 /boot/Image -load mmc ${devnum}:${distro_bootpart} 0x04000000 /boot/uInitrd -load mmc ${devnum}:${distro_bootpart} 0x01f00000 /boot/dtb/rockchip/rk3399-rock-pi-4.dtb -setenv finduuid "part uuid mmc ${devnum}:${distro_bootpart} uuid" -run finduuid -setenv bootargs "earlycon=uart8250,mmio32,0xff1a0000 console=ttyS2,1500000n8 loglevel=7 root=PARTUUID=${uuid} rootwait rootfstype=ext4 sdhci.debug_quirks=0x20000000" -booti 0x02080000 0x04000000 0x01f00000 -EOF - ${ANDROID_HOST_OUT}/bin/mkimage \ - -C none -A arm -T script -d ${mntdir}/boot/boot.cmd ${mntdir}/boot/boot.scr - - cd ${KERNEL_DIR} - export PATH=${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/clang-r353983c/bin:$PATH - export PATH=${ANDROID_BUILD_TOP}/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH - make ARCH=arm64 CC=clang CROSS_COMPILE=aarch64-linux-androidkernel- \ - CLANG_TRIPLE=aarch64-linux-gnu- rockpi4_defconfig - make ARCH=arm64 CC=clang CROSS_COMPILE=aarch64-linux-androidkernel- \ - CLANG_TRIPLE=aarch64-linux-gnu- -j`nproc` - - cp ${KERNEL_DIR}/arch/arm64/boot/Image ${mntdir}/boot/ - mkdir -p ${mntdir}/boot/dtb/rockchip/ - cp ${KERNEL_DIR}/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtb ${mntdir}/boot/dtb/rockchip/ - cd - - - mount -o bind /proc ${mntdir}/proc - mount -o bind /sys ${mntdir}/sys - mount -o bind /dev ${mntdir}/dev - - echo "Installing required packages..." - chroot ${mntdir} /bin/bash <<EOF -apt-get update -apt-get install -y -f initramfs-tools u-boot-tools network-manager openssh-server sudo man-db vim git dpkg-dev cdbs debhelper config-package-dev gdisk eject lzop binfmt-support ntpdate -EOF - - echo "Turning on DHCP client..." - cat >${mntdir}/etc/systemd/network/dhcp.network <<EOF -[Match] -Name=en* - -[Network] -DHCP=yes -EOF - - chroot ${mntdir} /bin/bash << "EOT" -echo "Adding user vsoc-01 and groups..." -useradd -m -G kvm,sudo -d /home/vsoc-01 --shell /bin/bash vsoc-01 -echo -e "cuttlefish\ncuttlefish" | passwd -echo -e "cuttlefish\ncuttlefish" | passwd vsoc-01 -EOT - - echo "Cloning android-cuttlefish..." - cd ${mntdir}/home/vsoc-01 - git clone https://github.com/google/android-cuttlefish.git - cd - - - echo "Creating led script..." - cat > ${mntdir}/usr/local/bin/led << "EOF" -#!/bin/bash - -if [ "$1" == "--start" ]; then - echo 125 > /sys/class/gpio/export - echo out > /sys/class/gpio/gpio125/direction - chmod 666 /sys/class/gpio/gpio125/value - echo 0 > /sys/class/gpio/gpio125/value - exit 0 -fi - -if [ "$1" == "--stop" ]; then - echo 0 > /sys/class/gpio/gpio125/value - echo 125 > /sys/class/gpio/unexport - exit 0 -fi - -if [ ! -e /sys/class/gpio/gpio125/value ]; then - echo "error: led service not initialized" - exit 1 -fi - -if [ "$1" == "0" ] || [ "$1" == "off" ] || [ "$1" == "OFF" ]; then - echo 0 > /sys/class/gpio/gpio125/value - exit 0 -fi - -if [ "$1" == "1" ] || [ "$1" == "on" ] || [ "$1" == "ON" ]; then - echo 1 > /sys/class/gpio/gpio125/value - exit 0 -fi - -echo "usage: led <0|1>" -exit 1 -EOF - chown root:root ${mntdir}/usr/local/bin/led - chmod 755 ${mntdir}/usr/local/bin/led - - echo "Creating led service..." - cat > ${mntdir}/etc/systemd/system/led.service << EOF -[Unit] - Description=led service - ConditionPathExists=/usr/local/bin/led - -[Service] - Type=oneshot - ExecStart=/usr/local/bin/led --start - ExecStop=/usr/local/bin/led --stop - RemainAfterExit=true - StandardOutput=journal - -[Install] - WantedBy=multi-user.target -EOF - - echo "Creating SD duplicator script..." - cat > ${mntdir}/usr/local/bin/sd-dupe << "EOF" -#!/bin/bash -led 0 - -src_dev=mmcblk0 -dest_dev=mmcblk1 -part_num=p5 - -if [ -e /dev/mmcblk0p5 ]; then - led 1 - - sgdisk -Z -a1 /dev/${dest_dev} - sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 /dev/${dest_dev} - sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env /dev/${dest_dev} - sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 /dev/${dest_dev} - sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust /dev/${dest_dev} - sgdisk -a1 -n:5:32768:- -A:5:set:2 -t:5:8305 -c:5:rootfs /dev/${dest_dev} - - src_block_count=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block count:" | sed 's/.*: *//'` - src_block_size=`tune2fs -l /dev/${src_dev}${part_num} | grep "Block size:" | sed 's/.*: *//'` - src_fs_size=$(( src_block_count*src_block_size )) - src_fs_size_m=$(( src_fs_size / 1024 / 1024 + 1 )) - - dd if=/dev/${src_dev}p1 of=/dev/${dest_dev}p1 conv=sync,noerror status=progress - dd if=/dev/${src_dev}p2 of=/dev/${dest_dev}p2 conv=sync,noerror status=progress - dd if=/dev/${src_dev}p3 of=/dev/${dest_dev}p3 conv=sync,noerror status=progress - dd if=/dev/${src_dev}p4 of=/dev/${dest_dev}p4 conv=sync,noerror status=progress - - echo "Writing ${src_fs_size_m} MB: /dev/${src_dev} -> /dev/${dest_dev}..." - dd if=/dev/${src_dev}${part_num} of=/dev/${dest_dev}${part_num} bs=1M conv=sync,noerror status=progress - - echo "Expanding /dev/${dest_dev}${part_num} filesystem..." - e2fsck -fy /dev/${dest_dev}${part_num} - resize2fs /dev/${dest_dev}${part_num} - tune2fs -O has_journal /dev/${dest_dev}${part_num} - e2fsck -fy /dev/${dest_dev}${part_num} - sync /dev/${dest_dev} - - echo "Cleaning up..." - mount /dev/${dest_dev}${part_num} /media - chroot /media /usr/local/bin/install-cleanup - - if [ $? == 0 ]; then - echo "Successfully copied Rock Pi image!" - while true; do - led 1; sleep 0.5 - led 0; sleep 0.5 - done - else - echo "Error while copying Rock Pi image" - while true; do - led 1; sleep 0.1 - led 0; sleep 0.1 - done - fi -else - echo "Expanding /dev/${dest_dev}${part_num} filesystem..." - e2fsck -fy /dev/${dest_dev}${part_num} - resize2fs /dev/${dest_dev}${part_num} - tune2fs -O has_journal /dev/${dest_dev}${part_num} - e2fsck -fy /dev/${dest_dev}${part_num} - sync /dev/${dest_dev} - - echo "Cleaning up..." - /usr/local/bin/install-cleanup -fi -EOF - chmod +x ${mntdir}/usr/local/bin/sd-dupe - - echo "Creating SD duplicator service..." - cat > ${mntdir}/etc/systemd/system/sd-dupe.service << EOF -[Unit] - Description=Duplicate SD card rootfs to eMMC on Rock Pi - ConditionPathExists=/usr/local/bin/sd-dupe - After=led.service - -[Service] - Type=simple - ExecStart=/usr/local/bin/sd-dupe - TimeoutSec=0 - StandardOutput=tty - -[Install] - WantedBy=multi-user.target -EOF - - echo "Creating cleanup script..." - cat > ${mntdir}/usr/local/bin/install-cleanup << "EOF" -#!/bin/bash -echo "Installing cuttlefish-common package..." -echo "nameserver 8.8.8.8" > /etc/resolv.conf -MAC=`ip link | grep eth0 -A1 | grep ether | sed 's/.*\(..:..:..:..:..:..\) .*/\1/' | tr -d :` -sed -i " 1 s/.*/& rockpi-${MAC}/" /etc/hosts -sudo hostnamectl set-hostname "rockpi-${MAC}" - -dpkg --add-architecture amd64 -until ping -c1 ftp.debian.org; do sleep 1; done -ntpdate time.google.com -while true; do - apt-get -o Acquire::Check-Valid-Until=false update - if [ $? != 0 ]; then sleep 1; continue; fi - apt-get install -y -f libc6:amd64 qemu-user-static - if [ $? != 0 ]; then sleep 1; continue; fi - break -done -cd /home/vsoc-01/android-cuttlefish -dpkg-buildpackage -d -uc -us -apt-get install -y -f ../cuttlefish-common_*_arm64.deb -apt-get clean -usermod -aG cvdnetwork vsoc-01 -chmod 660 /dev/vhost-vsock -chown root:cvdnetwork /dev/vhost-vsock - -rm /etc/machine-id -rm /var/lib/dbus/machine-id -dbus-uuidgen --ensure -systemd-machine-id-setup - -systemctl disable sd-dupe -rm /etc/systemd/system/sd-dupe.service -rm /usr/local/bin/sd-dupe -rm /usr/local/bin/install-cleanup -EOF - chmod +x ${mntdir}/usr/local/bin/install-cleanup - - chroot ${mntdir} /bin/bash << "EOT" -echo "Enabling services..." -systemctl enable led -systemctl enable sd-dupe - -echo "Creating Initial Ramdisk..." -update-initramfs -c -t -k "5.2.0" -mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n uInitrd -d /boot/initrd.img-5.2.0 /boot/uInitrd-5.2.0 -ln -s /boot/uInitrd-5.2.0 /boot/uInitrd -EOT - - umount ${mntdir}/sys - umount ${mntdir}/dev - umount ${mntdir}/proc - umount ${mntdir} - - # Turn on journaling - tune2fs -O ^has_journal ${IMAGE} - e2fsck -fy ${IMAGE} >/dev/null 2>&1 -fi - -if [ ${USE_IMAGE} -eq 0 ]; then - # 32GB eMMC size - end_sector=61071326 - device=/dev/${mmc_dev} - devicep=${device} - - sgdisk -Z -a1 ${device} - sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 ${device} - sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env ${device} - sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 ${device} - sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust ${device} - sgdisk -a1 -n:5:32768:${end_sector} -A:5:set:2 -t:5:8305 -c:5:rootfs ${device} - if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then - dd if=${IMAGE} of=${devicep}5 bs=1M - resize2fs ${devicep}5 >/dev/null 2>&1 - fi -else - device=$(losetup -f) - devicep=${device}p - if [ ${FLAGS_p5} -eq ${FLAGS_FALSE} ]; then - fs_end=3G - end_sector=- - fi - if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then - # Minimize rootfs filesystem - while true; do - out=`sudo resize2fs -M ${IMAGE} 2>&1` - if [[ $out =~ "Nothing to do" ]]; then - break - fi - done - # Minimize rootfs file size - block_count=`sudo tune2fs -l ${IMAGE} | grep "Block count:" | sed 's/.*: *//'` - block_size=`sudo tune2fs -l ${IMAGE} | grep "Block size:" | sed 's/.*: *//'` - sector_size=512 - start_sector=32768 - fs_size=$(( block_count*block_size )) - fs_sectors=$(( fs_size/sector_size )) - part_sectors=$(( ((fs_sectors-1)/2048+1)*2048 )) # 1MB-aligned - end_sector=$(( start_sector+part_sectors-1 )) - secondary_gpt_sectors=33 - fs_end=$(( (end_sector+secondary_gpt_sectors+1)*sector_size )) - image_size=$(( part_sectors*sector_size )) - truncate -s ${image_size} ${IMAGE} - e2fsck -fy ${IMAGE} >/dev/null 2>&1 - fi - - # Create final image - if [ $OVERWRITE -eq 1 ]; then - tmpimg=${OVERWRITE_IMAGE} - else - tmpimg=`mktemp` - fi - truncate -s ${fs_end} ${tmpimg} - - # Create GPT - sgdisk -Z -a1 ${tmpimg} - sgdisk -a1 -n:1:64:8127 -t:1:8301 -c:1:loader1 ${tmpimg} - sgdisk -a1 -n:2:8128:8191 -t:2:8301 -c:2:env ${tmpimg} - sgdisk -a1 -n:3:16384:24575 -t:3:8301 -c:3:loader2 ${tmpimg} - sgdisk -a1 -n:4:24576:32767 -t:4:8301 -c:4:trust ${tmpimg} - sgdisk -a1 -n:5:32768:${end_sector} -A:5:set:2 -t:5:8305 -c:5:rootfs ${tmpimg} - - losetup ${device} ${tmpimg} - partx -v --add ${device} - - if [ ${FLAGS_p5} -eq ${FLAGS_TRUE} ]; then - dd if=${IMAGE} of=${devicep}5 bs=1M - fi -fi -if [ ${FLAGS_p1} -eq ${FLAGS_TRUE} ]; then - dd if=${idbloader} of=${devicep}1 -fi -if [ ${FLAGS_p2} -eq ${FLAGS_TRUE} ]; then - dd if=${bootenv} of=${devicep}2 -fi -if [ ${FLAGS_p3} -eq ${FLAGS_TRUE} ]; then - dd if=${ANDROID_BUILD_TOP}/external/u-boot/u-boot.itb of=${devicep}3 -fi -if [ ${USE_IMAGE} -eq 1 ]; then - chown $SUDO_USER:`id -ng $SUDO_USER` ${tmpimg} - if [ $OVERWRITE -eq 0 ]; then - mv ${tmpimg} ${IMAGE} - fi - partx -v --delete ${device} - losetup -d ${device} -fi diff --git a/tools/create_base_image_gce.sh b/tools/create_base_image_gce.sh deleted file mode 100755 index 09443e37..00000000 --- a/tools/create_base_image_gce.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash - -set -x -set -o errexit - -sudo apt-get update - -# Stuff we need to get build support - -sudo apt install -y debhelper ubuntu-dev-tools equivs "${extra_packages[@]}" - -# Install the cuttlefish build deps - -for dsc in *.dsc; do - yes | sudo mk-build-deps -i "${dsc}" -t apt-get -done - -# Installing the build dependencies left some .deb files around. Remove them -# to keep them from landing on the image. -yes | rm -f *.deb - -for dsc in *.dsc; do - # Unpack the source and build it - - dpkg-source -x "${dsc}" - dir="$(basename "${dsc}" .dsc)" - dir="${dir/_/-}" - pushd "${dir}/" - debuild -uc -us - popd -done - -# Now gather all of the *.deb files to copy them into the image -debs=(*.deb) - -tmp_debs=() -for i in "${debs[@]}"; do - tmp_debs+=(/tmp/"$(basename "$i")") -done - -# Now install the packages on the disk -sudo mkdir /mnt/image -sudo mount /dev/sdb1 /mnt/image -cp "${debs[@]}" /mnt/image/tmp -sudo mount -t sysfs none /mnt/image/sys -sudo mount -t proc none /mnt/image/proc -sudo mount --bind /dev/ /mnt/image/dev -sudo mount --bind /dev/pts /mnt/image/dev/pts -sudo mount --bind /run /mnt/image/run -# resolv.conf is needed on Debian but not Ubuntu -sudo cp /etc/resolv.conf /mnt/image/etc/ -sudo chroot /mnt/image /usr/bin/apt update -sudo chroot /mnt/image /usr/bin/apt install -y "${tmp_debs[@]}" -# install tools dependencies -sudo chroot /mnt/image /usr/bin/apt install -y openjdk-11-jre -sudo chroot /mnt/image /usr/bin/apt install -y unzip bzip2 lzop -sudo chroot /mnt/image /usr/bin/apt install -y aapt - -sudo chroot /mnt/image /usr/bin/find /home -ls - - -# Install GPU driver dependencies -sudo chroot /mnt/image /usr/bin/apt install -y gcc -sudo chroot /mnt/image /usr/bin/apt install -y linux-source -sudo chroot /mnt/image /usr/bin/apt install -y linux-headers-`uname -r` -sudo chroot /mnt/image /usr/bin/apt install -y make - -# Download the latest GPU driver installer -gsutil cp \ - $(gsutil ls gs://nvidia-drivers-us-public/GRID/GRID*/*-Linux-x86_64-*.run \ - | sort \ - | tail -n 1) \ - /mnt/image/tmp/nvidia-driver-installer.run - -# Make GPU driver installer executable -chmod +x /mnt/image/tmp/nvidia-driver-installer.run - -# Install the latest GPU driver with default options and the dispatch libs -sudo chroot /mnt/image /tmp/nvidia-driver-installer.run \ - --silent \ - --install-libglvnd - -# Cleanup after install -rm /mnt/image/tmp/nvidia-driver-installer.run - -# Verify -query_nvidia() { - sudo chroot /mnt/image nvidia-smi --format=csv,noheader --query-gpu="$@" -} - -if [[ $(query_nvidia "count") != "1" ]]; then - echo "Failed to detect GPU." - exit 1 -fi - -if [[ $(query_nvidia "driver_version") == "" ]]; then - echo "Failed to detect GPU driver." - exit 1 -fi - - -# Clean up the builder's version of resolv.conf -sudo rm /mnt/image/etc/resolv.conf - -# Skip unmounting: -# Sometimes systemd starts, making it hard to unmount -# In any case we'll unmount cleanly when the instance shuts down - -echo IMAGE_WAS_CREATED diff --git a/tools/create_base_image_hostlib.sh b/tools/create_base_image_hostlib.sh deleted file mode 100755 index e5d2e3c5..00000000 --- a/tools/create_base_image_hostlib.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/bin/bash - -# Common code to build a host image on GCE - -# INTERNAL_extra_source may be set to a directory containing the source for -# extra package to build. - -# INTERNAL_IP can be set to --internal-ip run on a GCE instance -# The instance will need --scope compute-rw - -source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags" - -DEFINE_string build_instance \ - "${USER}-build" "Instance name to create for the build" "i" -DEFINE_string build_project "$(gcloud config get-value project)" \ - "Project to use for scratch" -DEFINE_string build_zone "$(gcloud config get-value compute/zone)" \ - "Zone to use for scratch resources" -DEFINE_string dest_image "vsoc-host-scratch-${USER}" "Image to create" "o" -DEFINE_string dest_family "" "Image family to add the image to" "f" -DEFINE_string dest_project "$(gcloud config get-value project)" \ - "Project to use for the new image" "p" -DEFINE_string launch_instance "" \ - "Name of the instance to launch with the new image" "l" -DEFINE_string source_image_family "debian-10" \ - "Image familty to use as the base" "s" -DEFINE_string source_image_project debian-cloud \ - "Project holding the base image" "m" -DEFINE_string repository_url \ - "https://github.com/google/android-cuttlefish.git" \ - "URL to the repository with host changes" "u" -DEFINE_string repository_branch master \ - "Branch to check out" "b" -DEFINE_string variant master \ - "Variant to build: generally master or stable" - - -SSH_FLAGS=(${INTERNAL_IP}) - -wait_for_instance() { - alive="" - while [[ -z "${alive}" ]]; do - sleep 5 - alive="$(gcloud compute ssh "${SSH_FLAGS[@]}" "$@" -- uptime || true)" - done -} - -package_source() { - local url="$1" - local branch="$2" - local repository_dir="${url/*\//}" - local debian_dir="$(basename "${repository_dir}" .git)" - if [[ $# -eq 4 ]]; then - debian_dir="${repository_dir}/$4" - fi - git clone "${url}" -b "${branch}" - dpkg-source -b "${debian_dir}" - rm -rf "${debian_dir}" -} - -main() { - set -o errexit - set -x - PZ=(--project=${FLAGS_build_project} --zone=${FLAGS_build_zone}) - if [[ -n "${FLAGS_dest_family}" ]]; then - dest_family_flag=("--family=${FLAGS_dest_family}") - else - dest_family_flag=() - fi - scratch_dir="$(mktemp -d)" - pushd "${scratch_dir}" - package_source "${FLAGS_repository_url}" "${FLAGS_repository_branch}" \ - "cuttlefish-common_${FLAGS_version}" - popd - source_files=( - "${ANDROID_BUILD_TOP}/device/google/cuttlefish_common/tools/create_base_image_gce.sh" - ${scratch_dir}/* - ) - if [[ -n "${INTERNAL_extra_source}" ]]; then - source_files+=("${INTERNAL_extra_source}"/*) - fi - - delete_instances=("${FLAGS_build_instance}" "${FLAGS_dest_image}") - if [[ -n "${FLAGS_launch_instance}" ]]; then - delete_instances+=("${FLAGS_launch_instance}") - fi - gcloud compute instances delete -q \ - "${PZ[@]}" "${delete_instances[@]}" || \ - echo Not running - gcloud compute disks delete -q \ - "${PZ[@]}" "${FLAGS_dest_image}" || echo No scratch disk - gcloud compute images delete -q \ - --project="${FLAGS_build_project}" "${FLAGS_dest_image}" || echo Not respinning - gcloud compute disks create \ - "${PZ[@]}" \ - --image-family="${FLAGS_source_image_family}" \ - --image-project="${FLAGS_source_image_project}" \ - "${FLAGS_dest_image}" - gcloud compute instances create \ - "${PZ[@]}" \ - --machine-type=n1-standard-16 \ - --image-family="${FLAGS_source_image_family}" \ - --image-project="${FLAGS_source_image_project}" \ - --boot-disk-size=200GiB \ - --accelerator="type=nvidia-tesla-p100-vws,count=1" \ - --maintenance-policy=TERMINATE \ - "${FLAGS_build_instance}" - wait_for_instance "${PZ[@]}" "${FLAGS_build_instance}" - # Ubuntu tends to mount the wrong disk as root, so help it by waiting until - # it has booted before giving it access to the clean image disk - gcloud compute instances attach-disk \ - "${PZ[@]}" \ - "${FLAGS_build_instance}" --disk="${FLAGS_dest_image}" - # beta for the --internal-ip flag that may be passed via SSH_FLAGS - gcloud beta compute scp "${SSH_FLAGS[@]}" "${PZ[@]}" \ - "${source_files[@]}" \ - "${FLAGS_build_instance}:" - gcloud compute ssh "${SSH_FLAGS[@]}" \ - "${PZ[@]}" "${FLAGS_build_instance}" -- \ - ./create_base_image_gce.sh - gcloud compute instances delete -q \ - "${PZ[@]}" "${FLAGS_build_instance}" - gcloud compute images create \ - --project="${FLAGS_build_project}" \ - --source-disk="${FLAGS_dest_image}" \ - --source-disk-zone="${FLAGS_build_zone}" \ - --licenses=https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx \ - "${dest_family_flag[@]}" \ - "${FLAGS_dest_image}" - gcloud compute disks delete -q "${PZ[@]}" \ - "${FLAGS_dest_image}" - if [[ -n "${FLAGS_launch_instance}" ]]; then - gcloud compute instances create "${PZ[@]}" \ - --image-project="${FLAGS_build_project}" \ - --image="${FLAGS_dest_image}" \ - --machine-type=n1-standard-4 \ - --scopes storage-ro \ - --accelerator="type=nvidia-tesla-p100-vws,count=1" \ - --maintenance-policy=TERMINATE \ - "${FLAGS_launch_instance}" - fi - cat <<EOF - echo Test and if this looks good, consider releasing it via: - - gcloud compute images create \ - --project="${FLAGS_dest_project}" \ - --source-image="${FLAGS_dest_image}" \ - --source-image-project="${FLAGS_build_project}" \ - "${dest_family_flag[@]}" \ - "${FLAGS_dest_image}" -EOF -} diff --git a/tools/flash-blk-dev.sh b/tools/flash-blk-dev.sh deleted file mode 100755 index e5381e04..00000000 --- a/tools/flash-blk-dev.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/bash - -# Copyright 2019 Google Inc. All rights reserved. - -# 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. - -usage() { - echo "USAGE: $0 [flags] image" - echo "flags:" - echo " -e,--expand: expand filesystem to fill device (default: false)" - echo " -h,--help: show this help (default: false)" -} - -main() -{ - if [ ! -e "${image}" ]; then - echo "error: can't find image. aborting..." - exit 1 - fi - - init_devs=`lsblk --nodeps -oNAME -n` - echo "Reinsert device (to write to) into PC" - while true; do - devs=`lsblk --nodeps -oNAME -n` - new_devs="$(echo -e "${init_devs}\n${devs}" | sort | uniq -u | awk 'NF')" - num_devs=`echo "${new_devs}" | wc -l` - if [[ "${new_devs}" == "" ]]; then - num_devs=0 - fi - if [[ ${num_devs} -gt 1 ]]; then - echo "error: too many new devices detected! aborting..." - exit 1 - fi - if [[ ${num_devs} -eq 1 ]]; then - break - fi - done - blk_dev=${new_devs} - # don't inform user we found the block device yet (it's confusing) - - init_devs=${devs} - echo "${init_devs}" | grep "${blk_dev}" >/dev/null - if [[ $? -ne 0 ]]; then - while true; do - devs=`lsblk --nodeps -oNAME -n` - new_devs="$(echo -e "${init_devs}\n${devs}" | sort | uniq -u | awk 'NF')" - num_devs=`echo "${new_devs}" | wc -l` - if [[ "${new_devs}" == "" ]]; then - num_devs=0 - fi - if [[ ${num_devs} -gt 1 ]]; then - echo "error: too many new devices detected! aborting..." - exit 1 - fi - if [[ ${num_devs} -eq 1 ]]; then - if [[ "${new_devs}" != "${blk_dev}" ]]; then - echo "error: block device name mismatch ${new_devs} != ${blk_dev}" - echo "Reinsert device (to write to) into PC" - blk_dev=${new_devs} - new_devs="" - continue - fi - break - fi - done - fi - # now inform the user - echo "Detected device at /dev/${blk_dev}" - - imgsize=`ls -lah ${image} | awk -F " " {'print $5'}` - echo "Ready to write ${imgsize} image to block device at /dev/${blk_dev}..." - sudo chmod 666 /dev/${blk_dev} - type pv > /dev/null 2>&1 - if [ $? == 0 ]; then - pv ${image} > /dev/${blk_dev} - else - dd if=${image} of=/dev/${blk_dev} bs=1M conv=sync,noerror status=progress - fi - if [ $? != 0 ]; then - echo "error: failed to write to device. aborting..." - exit 1 - fi - - if [ ${expand} -eq 1 ]; then - echo "Expanding partition and filesystem..." - part_type=`sudo gdisk -l /dev/${blk_dev} 2>/dev/null | grep ": present" | sed 's/ *\([^:]*\):.*/\1/'` - if [ "$part_type" == "MBR" ]; then - sudo parted -s /dev/${blk_dev} resizepart 1 100% - sudo e2fsck -y -f /dev/${blk_dev}1 >/dev/null 2>&1 - sudo resize2fs /dev/${blk_dev}1 >/dev/null 2>&1 - elif [ "$part_type" == "GPT" ]; then - parts=`sudo gdisk -l /dev/${blk_dev} | grep "^Number" -A999 | tail -n +2 | wc -l` - FIRST_SECTOR=`sudo gdisk -l /dev/${blk_dev} 2>/dev/null | tail -1 | tr -s ' ' | cut -d" " -f3` - sudo sgdisk -d${parts} /dev/${blk_dev} >/dev/null 2>&1 - sudo sgdisk -a1 -n:${parts}:${FIRST_SECTOR}:- -A:${parts}:set:2 -t:${parts}:8305 -c:${parts}:rootfs /dev/${blk_dev} >/dev/null 2>&1 - sudo e2fsck -fy /dev/${blk_dev}${parts} >/dev/null 2>&1 - sudo resize2fs /dev/${blk_dev}${parts} >/dev/null 2>&1 - fi - fi - sudo sync /dev/${blk_dev} - sudo eject /dev/${blk_dev} -} - -expand=0 -if [ "$1" == "-e" ] || [ "$1" == "--expand" ]; then - expand=1 - shift -fi - -if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then - usage - exit 0 -fi - -image=$1 -if [ "${image}" == "" ]; then - usage - exit 1 -fi - -main "$@" diff --git a/tools/gen_sha.sh b/tools/gen_sha.sh deleted file mode 100755 index dec71f73..00000000 --- a/tools/gen_sha.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Copyright 2019 Google Inc. All rights reserved. - -# 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. - -source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags" - -DEFINE_string kernel \ - "" "Path to kernel build dir" "k" - -FLAGS_HELP="USAGE: $0 [flags]" - -FLAGS "$@" || exit $? -eval set -- "${FLAGS_ARGV}" - -if [ -z ${FLAGS_kernel} ]; then - flags_help - exit 1 -fi - -cd "${ANDROID_BUILD_TOP}/device/google/cuttlefish_common" -Sha=`git rev-parse HEAD` -cd - >/dev/null -cd "${ANDROID_BUILD_TOP}/external/u-boot" -Sha="$Sha,`git rev-parse HEAD`" -cd - >/dev/null -cd "${ANDROID_BUILD_TOP}/external/arm-trusted-firmware" -Sha="$Sha,`git rev-parse HEAD`" -cd - >/dev/null -cd "${FLAGS_kernel}" -Sha="$Sha,`git rev-parse HEAD`" -cd - >/dev/null -echo $Sha diff --git a/tools/make_manifest.sh b/tools/make_manifest.sh deleted file mode 100755 index c8b52960..00000000 --- a/tools/make_manifest.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -# Copyright 2019 Google Inc. All rights reserved. - -# 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. - -source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags" - -DEFINE_string loader1 \ - "" "Path to loader1 image (partition 1)" "l" -DEFINE_string env \ - "" "Path to env image (partition 2)" "e" -DEFINE_string loader2 \ - "" "Path to loader2 image (partition 3)" "u" -DEFINE_string trust \ - "" "Path to trust image (partition 4)" "t" -DEFINE_string rootfs \ - "" "Path to rootfs image (partition 5)" "r" -DEFINE_string tftp \ - "192.168.0.1" "TFTP server address" "f" -DEFINE_string tftpdir \ - "/tftpboot" "TFTP server directory" "d" -DEFINE_string version \ - "2" "Specify which manifest version to use (default: latest)" "v" -DEFINE_string ethaddr \ - "" "MAC address of device to DFU (default: all)" "m" -DEFINE_string kernel \ - "" "Path to kernel build dir" "k" - -FLAGS_HELP="USAGE: $0 --kernel <dir> [flags]" - -FLAGS "$@" || exit $? -eval set -- "${FLAGS_ARGV}" - -for arg in "$@" ; do - flags_help - exit 1 -done - -if [ -z ${FLAGS_kernel} ]; then - flags_help - exit 1 -fi - -confirm() { - read -r -p "${1:-Are you sure you want to continue? [y/N]} " response - case "$response" in - [yY][eE][sS]|[yY]) - true - ;; - *) - false - ;; - esac -} - -createManifest() { - >>manifest.txt -} - -addKVToManifest() { - key=$1 - value=$2 - grep -q "^${key}=" manifest.txt && \ - sed -i "s/^${key}=.*/${key}=${value}/" manifest.txt || \ - echo "${key}=${value}" >> manifest.txt -} - -addShaToManifest() { - DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" - addKVToManifest "Sha" `${DIR}/gen_sha.sh --kernel ${FLAGS_kernel}` -} - -addPathToManifest() { - key=$1 - path=$2 - - if [ "${path}" != "" ]; then - filename=$(basename $path) - filetype=`file -b --mime-type "${path}"` - if [ "$key" == "UbootEnv" ] && [ "${filetype}" == "application/gzip" ]; then - echo "error: gzip not supported for env images" - fi - if [ "$key" != "UbootEnv" ] && [ "${filetype}" != "application/gzip" ]; then - echo "warning: gzip recommended for all non-env images" - confirm || exit 1 - fi - if [ ! "${path}" -ef "${FLAGS_tftpdir}/${filename}" ]; then - cp "${path}" "${FLAGS_tftpdir}/" - fi - else - unset filename - fi - - addKVToManifest "${key}" "${filename}" -} - -createManifest -addKVToManifest ManifestVersion ${FLAGS_version} -addKVToManifest TftpServer ${FLAGS_tftp} -addKVToManifest DFUethaddr ${FLAGS_ethaddr} -addPathToManifest RootfsImg ${FLAGS_rootfs} -addPathToManifest UbootEnv ${FLAGS_env} -addPathToManifest TplSplImg ${FLAGS_loader1} -addPathToManifest UbootItb ${FLAGS_loader2} -addShaToManifest diff --git a/tools/network-setup.sh b/tools/network-setup.sh deleted file mode 100755 index 019c1935..00000000 --- a/tools/network-setup.sh +++ /dev/null @@ -1,301 +0,0 @@ -#!/bin/bash - -# Copyright 2019 Google Inc. All rights reserved. - -# 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. - -if [[ "$OSTYPE" != "linux-gnu" ]]; then - echo "error: must be running linux" - exit 1 -fi - -# escalate to superuser -if [ "$UID" -ne 0 ]; then - exec sudo bash "$0" -fi - -cleanup() { - echo "Starting up network-manager..." - service network-manager start - if [ $? != 0 ]; then - echo "error: failed to start network-manager" - exit 1 - fi - - echo "Starting up networking..." - service networking start - if [ $? != 0 ]; then - echo "error: failed to start networking" - exit 1 - fi - if [ ! -z "$1" ]; then - exit $1 - fi -} - -sleep_time=0.1 -max_attempts=100 -DEFAULTNET=$1 -if [ "$DEFAULTNET" == "" ]; then - warn_no_default_network=0 - warn_disconnect_rockpi=0 - attempts=0 - while true; do - NETLIST=`ip link | grep "state UP" | sed 's/[0-9]*: \([^:]*\):.*/\1/'` - if [[ "${NETLIST}" == "" ]]; then - if [[ $warn_no_default_network -eq 0 ]]; then - echo "error: couldn't detect any connected default network" - warn_no_default_network=1 - fi - continue - elif [ `echo "${NETLIST}" | wc -l` -eq 1 ]; then - DEFAULTNET=${NETLIST} - break - elif [ `echo "${NETLIST}" | wc -l` -ne 1 ]; then - if [[ $warn_disconnect_rockpi -eq 0 ]]; then - echo "Please disconnect the network cable from the Rock Pi" - warn_disconnect_rockpi=1 - fi - if [[ ${attempts} -gt ${max_attempts} ]]; then - echo -e "\nerror: detected multiple connected networks, please tell me what to do:" - count=1 - for net in ${NETLIST}; do - echo "${count}) $net" - let count+=1 - done - read -p "Enter the number of your default network connection: " num_default - count=1 - for net in ${NETLIST}; do - if [ ${count} -eq ${num_default} ]; then - echo "Setting default to: ${net}" - DEFAULTNET=${net} - fi - let count+=1 - done - warn_no_default_network=0 - break - fi - echo -ne "\r" - printf "Manual configuration in %.1f seconds..." "$(( max_attempts-attempts ))e-1" - sleep $sleep_time - fi - let attempts+=1 - done -fi -echo "Found default network at ${DEFAULTNET}" - -if [ "${ROCKNET}" == "" ]; then - echo "Please reconnect network cable from Rock Pi to PC's spare network port" - attempts=0 - while true; do - NETLIST=`ip link | grep "state UP" | grep -v $DEFAULTNET | sed 's/[0-9]*: \([^:]*\):.*/\1/' | awk 'NF'` - networks=`echo "$NETLIST" | wc -l` - if [[ "${NETLIST}" == "" ]]; then - networks=0 - fi - if [ $networks -eq 1 ]; then - ROCKNET=${NETLIST} - break - elif [ $networks -gt 1 ]; then - if [[ ${attempts} -gt ${max_attempts} ]]; then - echo -e "\nerror: detected multiple connected networks, please tell me what to do:" - count=1 - for net in ${NETLIST}; do - echo "${count}) $net" - let count+=1 - done - read -p "Enter the number of your rock pi network connection: " num_rockpi - count=1 - for net in ${NETLIST}; do - if [ ${count} -eq ${num_rockpi} ]; then - echo "Setting rock pi to: ${net}" - ROCKNET=${net} - fi - let count+=1 - done - break - fi - echo -ne "\r" - printf "Manual configuration in %.1f seconds..." "$(( max_attempts-attempts ))e-1" - let attempts+=1 - fi - sleep $sleep_time - done -fi -echo "Found Rock Pi network at ${ROCKNET}" -sudo ifconfig ${ROCKNET} down - -echo "Downloading dnsmasq..." -apt-get install -d -y dnsmasq >/dev/null - -echo "Shutting down network-manager to prevent interference..." -service network-manager stop -if [ $? != 0 ]; then - echo "error: failed to stop network-manager" - cleanup 1 -fi - -echo "Shutting down networking to prevent interference..." -service networking stop -if [ $? != 0 ]; then - echo "error: failed to stop networking" - cleanup 1 -fi - -echo "Installing dnsmasq..." -apt-get install dnsmasq >/dev/null - -echo "Enabling dnsmasq daemon..." -cat /etc/default/dnsmasq | grep "ENABLED" >/dev/null -if [ $? == 0 ]; then - sed -i 's/.*ENABLED.*/ENABLED=1/' /etc/default/dnsmasq -else - echo "ENABLED=1" >> /etc/default/dnsmasq -fi - -echo "Configuring dnsmasq for Rock Pi network..." -cat >/etc/dnsmasq.d/${ROCKNET}.conf << EOF -interface=${ROCKNET} -bind-interfaces -except-interface=lo -dhcp-authoritative -leasefile-ro -port=0 -dhcp-range=192.168.0.100,192.168.0.199 -EOF - -echo "Configuring udev rules..." -cat >/etc/udev/rules.d/82-${ROCKNET}.rules <<EOF -ACTION=="add", SUBSYSTEM=="net", KERNEL=="${ROCKNET}", ENV{NM_UNMANAGED}="1" -EOF - -echo "Configuring network interface..." -cat >/etc/network/interfaces.d/${ROCKNET}.conf <<EOF -auto ${ROCKNET} -iface ${ROCKNET} inet static - address 192.168.0.1 - netmask 255.255.255.0 -EOF - -echo "Enabling IP forwarding..." -echo 1 >/proc/sys/net/ipv4/ip_forward - -echo "Creating IP tables rules script..." -cat > /usr/local/sbin/iptables-rockpi.sh << EOF -#!/bin/bash -/sbin/iptables -A FORWARD -i ${ROCKNET} -o ${DEFAULTNET} -m state --state RELATED,ESTABLISHED -j ACCEPT -/sbin/iptables -A FORWARD -i ${ROCKNET} -o ${DEFAULTNET} -j ACCEPT -/sbin/iptables -t nat -A POSTROUTING -o ${DEFAULTNET} -j MASQUERADE -EOF -sudo chown root:root /usr/local/sbin/iptables-rockpi.sh -sudo chmod 750 /usr/local/sbin/iptables-rockpi.sh - -echo "Creating IP tables rules service..." -cat > /etc/systemd/system/iptables-rockpi.service << EOF -[Unit] -Description=iptables rockpi service -After=network.target - -[Service] -Type=oneshot -ExecStart=/usr/local/sbin/iptables-rockpi.sh -RemainAfterExit=true -StandardOutput=journal - -[Install] -WantedBy=multi-user.target -EOF - -echo "Reloading systemd manager configuration..." -sudo systemctl daemon-reload - -echo "Start IP tables rules service..." -sudo systemctl enable iptables-rockpi -sudo systemctl start iptables-rockpi - -cleanup - -echo "Restarting dnsmasq service..." -service dnsmasq restart -if [ $? != 0 ]; then - echo "error: failed to restart dnsmasq" - exit 1 -fi - -# Verify the Rock Pi was configured correctly -ip link show ${ROCKNET} >/dev/null -if [ $? != 0 ]; then - echo "error: wasn't able to successfully configure connection to Rock Pi" - exit 1 -fi - -echo "Searching for Rock Pi's IP address..." -while true; do - rockip=`cat /proc/net/arp | grep ${ROCKNET} | grep -v 00:00:00:00:00:00 | cut -d" " -f1` - if [[ ${#rockip} -ge 7 ]] && [[ ${#rockip} -le 15 ]]; then - break - fi - sleep 0.1 -done - -echo "Writing Rock Pi configuration to ~/.ssh/config..." -USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6) -grep -w "Host rock01" $USER_HOME/.ssh/config > /dev/null 2>&1 -if [ $? != 0 ]; then - cat >>$USER_HOME/.ssh/config << EOF -Host rock01 - HostName ${rockip} - User vsoc-01 - IdentityFile ~/.ssh/rock01_key - LocalForward 6520 127.0.0.1:6520 - LocalForward 6444 127.0.0.1:6444 -EOF -else - sed -i '/Host rock01/{n;s/.*/ HostName '${rockip}'/}' $USER_HOME/.ssh/config -fi -grep -w "Host rockpi01" $USER_HOME/.ssh/config > /dev/null 2>&1 -if [ $? != 0 ]; then - cat >>$USER_HOME/.ssh/config << EOF -Host rockpi01 - HostName ${rockip} - User vsoc-01 - IdentityFile ~/.ssh/rock01_key -EOF -else - sed -i '/Host rockpi01/{n;s/.*/ HostName '${rockip}'/}' $USER_HOME/.ssh/config -fi - -sudo chown $SUDO_USER:`id -ng $SUDO_USER` $USER_HOME/.ssh/config -sudo chmod 600 $USER_HOME/.ssh/config - -echo "Creating ssh key..." -sudo -u $SUDO_USER echo "n" | sudo -u $SUDO_USER ssh-keygen -q -t rsa -b 4096 -f $USER_HOME/.ssh/rock01_key -N '' >/dev/null 2>&1 -tmpfile=`mktemp` -echo "echo cuttlefish" > "$tmpfile" -chmod a+x "$tmpfile" -chown $SUDO_USER "$tmpfile" -sudo SSH_ASKPASS="${tmpfile}" DISPLAY=:0 su $SUDO_USER -c "setsid -w ssh-copy-id -i ${USER_HOME}/.ssh/rock01_key -o StrictHostKeyChecking=no vsoc-01@${rockip} >/dev/null 2>&1" -if [ $? != 0 ]; then - sed -i "/${rockip}/d" ${USER_HOME}/.ssh/known_hosts - sudo SSH_ASKPASS="${tmpfile}" DISPLAY=:0 su $SUDO_USER -c "setsid -w ssh-copy-id -i ${USER_HOME}/.ssh/rock01_key -o StrictHostKeyChecking=no vsoc-01@${rockip} >/dev/null 2>&1" - if [ $? != 0 ]; then - echo "error: wasn't able to connect to Rock Pi over ssh" - exit 1 - fi -fi - -echo "Successfully configured!" -echo " Host: 192.168.0.1" -echo "RockPi: ${rockip}" -echo "SSH Alias: rock01 (auto port-forwarding)" -echo "SSH Alias: rockpi01 (no port-forwarding)" diff --git a/tools/play_audio/.gitignore b/tools/play_audio/.gitignore deleted file mode 100644 index a6795baa..00000000 --- a/tools/play_audio/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -play_audio -opuscpp diff --git a/tools/play_audio/Makefile b/tools/play_audio/Makefile deleted file mode 100644 index 30730ef4..00000000 --- a/tools/play_audio/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -CXXFLAGS := -Wextra -Wall -pedantic-errors -std=c++17 -LDLIBS := -lopus -lgflags -lglog -lSDL2 -LINK.o := $(LINK.cc) - -PROG := play_audio -OBJS := $(PROG).o client_socket.o sdl_wrapper.o opuscpp/opus_wrapper.o - -$(PROG): $(OBJS) - -clean: - rm -f $(OBJS) $(PROG) - diff --git a/tools/play_audio/README.md b/tools/play_audio/README.md deleted file mode 100644 index 28c227fe..00000000 --- a/tools/play_audio/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Play Audio - -Audio receiver for a cuttlefish instance. A binary to play audio from a remote -Android virtual device. - -## Install Dependencies - -``` -git clone https://github.com/google/opuscpp -sudo apt install libsdl2-2.0-0 libsdl2-dev libopus-dev libopus0 libgflags-dev libgoogle-glog-dev -``` - -## Build - -``` -make -``` - -## Run -Use ssh port forwarding to forward `7444` from a running instance. Then run the -`play_audio` binary. - -``` -./play_audio -``` - -If you are running multiple virtual devices on a host, you must pass the -`device_num` flag to specify the device corresponding to the `vsoc-##` username, -and you will have to add `1 - device_num` to the port that you forward (vsoc-02 -= port 7445). diff --git a/tools/play_audio/client_socket.cpp b/tools/play_audio/client_socket.cpp deleted file mode 100644 index 97c6b133..00000000 --- a/tools/play_audio/client_socket.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "client_socket.h" - -#include "glog/logging.h" - -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <unistd.h> - -#include <cstdint> -#include <cstring> -#include <vector> - -namespace { -std::uint16_t HostOrderUInt16(const void* src) { - std::uint16_t result{}; - std::memcpy(&result, src, sizeof result); - return htons(result); -} - -std::uint32_t HostOrderUInt32(const void* src) { - std::uint32_t result{}; - std::memcpy(&result, src, sizeof result); - return htonl(result); -} -} // namespace - -using cfp::ClientSocket; - -ClientSocket::ClientSocket(std::uint16_t port) - : socket_fd_{socket(AF_INET, SOCK_STREAM, 0)} { - sockaddr_in server_addr{}; - - if (socket_fd_ < 0) { - LOG(ERROR) << "couldn't create socket\n"; - return; - } - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons(port); - - if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) { - LOG(ERROR) << "couldn't convert localhost address\n"; - close(); - return; - } - - if (connect(socket_fd_, reinterpret_cast<sockaddr*>(&server_addr), - sizeof server_addr) < 0) { - LOG(ERROR) << "connection failed\n"; - close(); - return; - } -} - -ClientSocket::~ClientSocket() { close(); } - -ClientSocket::ClientSocket(ClientSocket&& other) - : socket_fd_{other.socket_fd_} { - other.socket_fd_ = -1; -} - -ClientSocket& ClientSocket::operator=(ClientSocket&& other) { - close(); - socket_fd_ = other.socket_fd_; - other.socket_fd_ = -1; - return *this; -} - -std::vector<unsigned char> ClientSocket::RecvAll(ssize_t count) { - std::vector<unsigned char> buf(count); - size_t total_read = 0; - while (total_read < buf.size()) { - auto just_read = - read(socket_fd_, buf.data() + total_read, buf.size() - total_read); - if (just_read <= 0) { - LOG(ERROR) << "read failed"; - return {}; - } - total_read += static_cast<size_t>(just_read); - } - return buf; -} - -std::uint16_t ClientSocket::RecvUInt16() { - return HostOrderUInt16(RecvAll(sizeof(std::uint16_t)).data()); -} - -std::uint32_t ClientSocket::RecvUInt32() { - return HostOrderUInt32(RecvAll(sizeof(std::uint32_t)).data()); -} - -void ClientSocket::close() { - if (socket_fd_ >= 0) { - ::close(socket_fd_); - socket_fd_ = -1; - } -} diff --git a/tools/play_audio/client_socket.h b/tools/play_audio/client_socket.h deleted file mode 100644 index f51cb6ad..00000000 --- a/tools/play_audio/client_socket.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright (C) 2018 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. - */ -#ifndef CFP_CLIENT_SOCKET_ -#define CFP_CLIENT_SOCKET_ - -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <unistd.h> - -#include <cstdint> -#include <cstring> -#include <iostream> -#include <vector> - -namespace cfp { - -class ClientSocket { - public: - ClientSocket(std::uint16_t port); - ~ClientSocket(); - - ClientSocket(ClientSocket&& other); - ClientSocket& operator=(ClientSocket&& other); - - ClientSocket(const ClientSocket&) = delete; - ClientSocket& operator=(const ClientSocket&) = delete; - - bool valid() const { return socket_fd_ >= 0; } - - std::vector<unsigned char> RecvAll(ssize_t count); - - std::uint16_t RecvUInt16(); - std::uint32_t RecvUInt32(); - - private: - void close(); - int socket_fd_ = -1; -}; - -} // namespace cfp - -#endif diff --git a/tools/play_audio/play_audio.cpp b/tools/play_audio/play_audio.cpp deleted file mode 100644 index 2594396f..00000000 --- a/tools/play_audio/play_audio.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "client_socket.h" -#include "sdl_wrapper.h" - -#include "glog/logging.h" -#include "gflags/gflags.h" -#include "opuscpp/opus_wrapper.h" -#include <SDL2/SDL.h> - -#include <cstdint> -#include <tuple> -#include <vector> - -DEFINE_int32( - device_num, 1, - "Cuttlefish device number, corresponding to username vsoc-## number"); - -namespace { -std::uint16_t AudioPort() { - constexpr std::uint16_t kAudioStreamBasePort = 7444; - std::uint16_t audio_port = kAudioStreamBasePort + (FLAGS_device_num - 1); - return audio_port; -} - -cfp::ClientSocket Connect() { - const auto port = AudioPort(); - auto conn = cfp::ClientSocket{port}; - if (!conn.valid()) { - LOG(FATAL) << "couldn't connect on port " << port; - } - return conn; -} - -std::tuple<std::uint16_t, std::uint16_t> RecvHeader(cfp::ClientSocket* conn) { - // creating variables because these must be received in order - auto num_channels = conn->RecvUInt16(); - auto frame_rate = conn->RecvUInt16(); - LOG(INFO) << "\nnum_channels: " << num_channels - << "\nframe_rate: " << frame_rate << '\n'; - return {num_channels, frame_rate}; -} - -// Returns frame_size and encoded audio -std::tuple<std::uint32_t, std::vector<unsigned char>> RecvEncodedAudio( - cfp::ClientSocket* conn) { - auto length = conn->RecvUInt32(); - auto frame_size = conn->RecvUInt32(); - auto encoded = conn->RecvAll(length); - - if (encoded.size() < length) { - encoded.clear(); - } - return {frame_size, std::move(encoded)}; -} - -void PlayDecodedAudio(cfp::SDLAudioDevice* audio_device, - const std::vector<opus_int16>& audio) { - auto sz = audio.size() * sizeof audio[0]; - auto ret = audio_device->QueueAudio(audio.data(), sz); - if (ret < 0) { - LOG(ERROR) << "failed to queue audio: " << SDL_GetError() << '\n'; - } -} - -} // namespace - -int main(int argc, char* argv[]) { - ::google::InitGoogleLogging(argv[0]); - ::gflags::ParseCommandLineFlags(&argc, &argv, true); - cfp::SDLLib sdl{}; - - auto conn = Connect(); - const auto& [num_channels, frame_rate] = RecvHeader(&conn); - - auto audio_device = sdl.OpenAudioDevice(frame_rate, num_channels); - auto dec = - opus::Decoder{static_cast<std::uint32_t>(frame_rate), num_channels}; - CHECK(dec.valid()) << "Could not construct Decoder. Maybe bad frame_rate (" - << frame_rate <<") or num_channels (" << num_channels - << ")?"; - - while (true) { - CHECK(dec.valid()) << "decoder in invalid state"; - const auto& [frame_size, encoded] = RecvEncodedAudio(&conn); - if (encoded.empty()) { - break; - } - auto decoded = dec.Decode(encoded, frame_size, false); - if (decoded.empty()) { - break; - } - PlayDecodedAudio(&audio_device, decoded); - } -} diff --git a/tools/play_audio/sdl_wrapper.cpp b/tools/play_audio/sdl_wrapper.cpp deleted file mode 100644 index 11f76df4..00000000 --- a/tools/play_audio/sdl_wrapper.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sdl_wrapper.h" - -#include "glog/logging.h" -#include <SDL2/SDL.h> - -#include <cstdint> - -using cfp::SDLAudioDevice; -using cfp::SDLLib; - -SDLAudioDevice::SDLAudioDevice(SDLAudioDevice&& other) - : device_id_{other.device_id_} { - other.device_id_ = 0; -} -SDLAudioDevice& SDLAudioDevice::operator=(SDLAudioDevice&& other) { - close(); - device_id_ = other.device_id_; - other.device_id_ = 0; - return *this; -} - -SDLAudioDevice::~SDLAudioDevice() { close(); } - -int SDLAudioDevice::QueueAudio(const void* data, std::uint32_t len) { - return SDL_QueueAudio(device_id_, data, len); -} - -SDLAudioDevice::SDLAudioDevice(SDL_AudioDeviceID device_id) - : device_id_{device_id} {} - -void SDLAudioDevice::close() { - if (device_id_ != 0) { - SDL_CloseAudioDevice(device_id_); - } -} - -SDLLib::SDLLib() { SDL_Init(SDL_INIT_AUDIO); } -SDLLib::~SDLLib() { SDL_Quit(); } - -SDLAudioDevice SDLLib::OpenAudioDevice(int freq, std::uint8_t num_channels) { - SDL_AudioSpec wav_spec{}; - wav_spec.freq = freq; - wav_spec.format = AUDIO_S16LSB; - wav_spec.channels = num_channels; - wav_spec.silence = 0; - // .samples seems to work as low as 256, - // docs say this is 4096 when used with SDL_LoadWAV so I'm sticking with - // that - wav_spec.samples = 4096; - wav_spec.size = 0; - - auto audio_device_id = SDL_OpenAudioDevice(nullptr, 0, &wav_spec, nullptr, 0); - if (audio_device_id == 0) { - LOG(FATAL) << "failed to open audio device: " << SDL_GetError() << '\n'; - } - SDL_PauseAudioDevice(audio_device_id, false); - return SDLAudioDevice{audio_device_id}; -} diff --git a/tools/play_audio/sdl_wrapper.h b/tools/play_audio/sdl_wrapper.h deleted file mode 100644 index 9be1df5c..00000000 --- a/tools/play_audio/sdl_wrapper.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <SDL2/SDL.h> -#include <cstdint> - -namespace cfp { - -class SDLLib; - -class SDLAudioDevice { - public: - SDLAudioDevice(SDLAudioDevice&& other); - SDLAudioDevice& operator=(SDLAudioDevice&& other); - - SDLAudioDevice(const SDLAudioDevice&) = delete; - SDLAudioDevice& operator=(const SDLAudioDevice&) = delete; - - ~SDLAudioDevice(); - - int QueueAudio(const void* data, std::uint32_t len); - - private: - friend SDLLib; - explicit SDLAudioDevice(SDL_AudioDeviceID device_id); - void close(); - - SDL_AudioDeviceID device_id_{}; -}; - -class SDLLib { - public: - SDLLib(); - ~SDLLib(); - - SDLLib(const SDLLib&) = delete; - SDLLib& operator=(const SDLLib&) = delete; - - SDLAudioDevice OpenAudioDevice(int freq, std::uint8_t num_channels); -}; - -} // namespace cfp diff --git a/tools/tombstone_to_line.py b/tools/tombstone_to_line.py deleted file mode 100755 index 7320bd56..00000000 --- a/tools/tombstone_to_line.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2018 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. -# -"""Use addr2line to interpret tombstone contents - -The defaults should work if this is run after running lunch. -""" - -from __future__ import print_function -import argparse -import collections -import functools -import multiprocessing -import os -import re -import subprocess -import sys - - -# Patterns of things that we might want to match. - -patterns = [ - (re.compile('(.* pc )([0-9a-f]+) +([^ ]+) .*'), 1, 3, 2), - (re.compile('(.*)#[0-9]+ 0x[0-9a-f]+ +\((.*)\+0x([0-9a-f]+)\)'), 1, 2, 3)] - - -LookupInfo = collections.namedtuple('LookupInfo', - ['line_number', 'details', 'file_name']) - - -def lookup_addr(args, object_path, address): - try: - if object_path[0] == os.path.sep: - object_path = object_path[1:] - parms = [args.addr2line, '-e', - os.path.join(args.symbols, object_path), address] - details = subprocess.check_output(parms).strip().split(':') - return LookupInfo( - line_number=details[-1], - details=details, - file_name=':'.join(details[:-1])) - except subprocess.CalledProcessError: - return None - - -def simple_match(line, info, indent, out_file): - print('{} // From {}:{}'.format( - line, info.file_name, info.line_number), file=out_file) - - -def source_match(line, info, indent, out_file): - source = '' - try: - with open(info.file_name, 'r') as f: - for i in range(int(info.line_number.split(' ')[0])): - source = f.readline() - # Fall back to the simple formatter on any error - except Exception: - simple_match(line, info, indent, out_file) - return - print(line, file=out_file) - print('{}// From {}:{}'.format( - ' ' * indent, info.file_name, info.line_number), file=out_file) - print('{} {}'.format(' ' * indent, ' '.join(source.strip().split())), - file=out_file) - - -def process(in_file, out_file, args): - for line in in_file: - line = line.rstrip() - groups = None - for p in patterns: - groups = p[0].match(line) - if groups: - break - info = None - if groups is not None: - info = lookup_addr(args, groups.group(p[2]), groups.group(p[3])) - if info is None: - print(line, file=out_file) - continue - if args.source: - source_match(line, info, len(groups.group(p[1])), out_file) - else: - simple_match(line, info, len(groups.group(p[1])), out_file) - - -def process_file(path, args): - with open(path + args.suffix, 'w') as out_file: - with open(path, 'r') as in_file: - process(in_file, out_file, args) - - -def common_arg_parser(): - parser = argparse.ArgumentParser(description= - 'Add line information to a tombstone') - parser.add_argument('--addr2line', type=str, - help='Path to addr2line', - default=os.path.join( - os.environ.get('ANDROID_TOOLCHAIN', ''), - 'x86_64-linux-android-addr2line')) - parser.add_argument('files', metavar='FILE', type=str, nargs='+', - help='a list of files to process') - parser.add_argument('--jobs', type=int, default=32, - help='Number of parallel jobs to run') - parser.add_argument('--source', default=False, action='store_true', - help='Attempt to print the source') - parser.add_argument('--suffix', type=str, default='.txt', - help='Suffix to add to the processed file') - return parser - - - -def process_all(args): - multiprocessing.Pool(32).map(functools.partial(process_file, args=args), - args.files) - - -if __name__ == '__main__': - parser = common_arg_parser() - parser.add_argument('--symbols', type=str, - help='Path to the symbols', - default=os.path.join( - os.environ.get('ANDROID_PRODUCT_OUT', ''), 'symbols')) - process_all(parser.parse_args()) diff --git a/tools/upload_to_gce_and_run.py b/tools/upload_to_gce_and_run.py deleted file mode 100755 index 9ceee1fc..00000000 --- a/tools/upload_to_gce_and_run.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python - -"""Upload a local build to Google Compute Engine and run it.""" - -import argparse -import glob -import os -import subprocess - - -def upload_artifacts(args): - dir = os.getcwd() - try: - os.chdir(args.image_dir) - images = glob.glob('*.img') - if len(images) == 0: - raise OSError('File not found: %s' + image_pat) - subprocess.check_call( - 'tar -c -f - --lzop -S ' + ' '.join(images) + - ' | gcloud compute ssh %s@%s -- tar -x -f - --lzop -S' % ( - args.user, - args.instance), - shell=True) - finally: - os.chdir(dir) - - host_package = os.path.join(args.host_dir, 'cvd-host_package.tar.gz') - # host_package - subprocess.check_call( - 'gcloud compute ssh %s@%s -- tar -x -z -f - < %s' % ( - args.user, - args.instance, - host_package), - shell=True) - - -def launch_cvd(args): - if args.data_image: - subprocess.check_call( - 'gcloud compute ssh %s@%s -- bin/launch_cvd --data-image %s ' - '--data-policy create_if_missing --blank-data-image-mb %d' % ( - args.user, - args.instance, - args.data_image, - args.blank_data_image_mb), - shell=True) - else: - subprocess.check_call( - 'gcloud compute ssh %s@%s -- bin/launch_cvd' % ( - args.user, - args.instance), - shell=True) - - -def stop_cvd(args): - subprocess.call( - 'gcloud compute ssh %s@%s -- bin/stop_cvd' % ( - args.user, - args.instance), - shell=True) - - -def main(): - parser = argparse.ArgumentParser( - description='Upload a local build to Google Compute Engine and run it') - parser.add_argument( - '-host_dir', - type=str, - default=os.environ.get('ANDROID_HOST_OUT', '.'), - help='path to the dist directory') - parser.add_argument( - '-image_dir', - type=str, - default=os.environ.get('ANDROID_PRODUCT_OUT', '.'), - help='path to the img files') - parser.add_argument( - '-instance', type=str, required=True, - help='instance to update') - parser.add_argument( - '-user', type=str, default='vsoc-01', - help='user to update on the instance') - parser.add_argument( - '-data-image', type=str, default=None, - help='userdata image file name, this file will be used instead of default one') - parser.add_argument( - '-blank-data-image-mb', type=int, default=4098, - help='custom userdata image size in megabytes') - parser.add_argument( - '-launch', default=False, - action='store_true', - help='launch the device') - args = parser.parse_args() - stop_cvd(args) - upload_artifacts(args) - if args.launch: - launch_cvd(args) - - -if __name__ == '__main__': - main() diff --git a/tools/upload_via_ssh.py b/tools/upload_via_ssh.py deleted file mode 100755 index c20a57fa..00000000 --- a/tools/upload_via_ssh.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/python - -"""Upload a local build to Google Compute Engine and run it.""" - -import argparse -import glob -import os -import subprocess - - -def upload_artifacts(args): - dir = os.getcwd() - try: - os.chdir(args.image_dir) - images = glob.glob('*.img') - if len(images) == 0: - raise OSError('File not found: ' + args.image_dir + '/*.img') - subprocess.check_call( - 'tar -c -f - --lzop -S ' + ' '.join(images) + - ' | ssh %s@%s -- tar -x -f - --lzop -S' % ( - args.user, - args.ip), - shell=True) - finally: - os.chdir(dir) - - host_package = os.path.join(args.host_dir, 'cvd-host_package.tar.gz') - # host_package - subprocess.check_call( - 'ssh %s@%s -- tar -x -z -f - < %s' % ( - args.user, - args.ip, - host_package), - shell=True) - - -def launch_cvd(args): - subprocess.check_call( - 'ssh %s@%s -- bin/launch_cvd %s' % ( - args.user, - args.ip, - ' '.join(args.runner_args) - ), - shell=True) - - -def stop_cvd(args): - subprocess.call( - 'ssh %s@%s -- bin/stop_cvd' % ( - args.user, - args.ip), - shell=True) - - -def main(): - parser = argparse.ArgumentParser( - description='Upload a local build to Google Compute Engine and run it') - parser.add_argument( - '-host_dir', - type=str, - default=os.environ.get('ANDROID_HOST_OUT', '.'), - help='path to the dist directory') - parser.add_argument( - '-image_dir', - type=str, - default=os.environ.get('ANDROID_PRODUCT_OUT', '.'), - help='path to the img files') - parser.add_argument( - '-user', type=str, default='vsoc-01', - help='user to update on the instance') - parser.add_argument( - '-ip', type=str, - help='ip address of the board') - parser.add_argument( - '-launch', default=False, - action='store_true', - help='launch the device') - parser.add_argument('runner_args', nargs='*', help='launch_cvd arguments') - args = parser.parse_args() - stop_cvd(args) - upload_artifacts(args) - if args.launch: - launch_cvd(args) - - -if __name__ == '__main__': - main() diff --git a/tools/vlan_prototype_down.sh b/tools/vlan_prototype_down.sh deleted file mode 100755 index 1db2bf9f..00000000 --- a/tools/vlan_prototype_down.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# Delete the host networks for the VLAN prototype. -# Runs as root. -# Use at your own risk. - -delete_interface() { - bridge="$(printf cvd-v${1}br-%02d $2)" - tap="$(printf cvd-${1}vlan-%02d $2)" - network="${3}.$((4*$2 - 4))/30" - - /sbin/ifconfig "${tap}" down - ip link delete "${tap}" - - if [ -f /var/run/cuttlefish-dnsmasq-"${bridge}".pid ]; then - kill $(cat /var/run/cuttlefish-dnsmasq-"${bridge}".pid) - fi - - iptables -t nat -D POSTROUTING -s "${network}" -j MASQUERADE - - /sbin/ifconfig "${bridge}" down - /sbin/brctl delbr "${bridge}" -} - -delete_interface w 1 192.168.93 -delete_interface m 1 192.168.94 -delete_interface i 1 192.168.95 - -ip link delete cvd-net-01 diff --git a/tools/vlan_prototype_up.sh b/tools/vlan_prototype_up.sh deleted file mode 100755 index fbeef40b..00000000 --- a/tools/vlan_prototype_up.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -# Create the host networks for the VLAN prototype. -# Runs as root. -# Use at your own risk. - -create_interface() { - bridge="$(printf cvd-v${1}br-%02d $2)" - tap="$(printf cvd-${1}vlan-%02d $2)" - gateway="${3}.$((4*$2 - 3))" - network="${3}.$((4*$2 - 4))/30" - netmask="255.255.255.252" - dhcp_range="${3}.$((4*$2 - 2)),${3}.$((4*$2 - 2))" - - /sbin/brctl addbr "${bridge}" - /sbin/brctl stp "${bridge}" off - /sbin/brctl setfd "${bridge}" 0 - /sbin/ifconfig "${bridge}" "${gateway}" netmask "${netmask}" up - - iptables -t nat -A POSTROUTING -s "${network}" -j MASQUERADE - - dnsmasq \ - --strict-order \ - --except-interface=lo \ - --interface="${bridge}" \ - --listen-address="${gateway}" \ - --bind-interfaces \ - --dhcp-range="${dhcp_range}" \ - --conf-file="" \ - --pid-file=/var/run/cuttlefish-dnsmasq-"${bridge}".pid \ - --dhcp-leasefile=/var/run/cuttlefish-dnsmasq-"${bridge}".leases \ - --dhcp-no-override - - ip link add link cvd-net-01 name "${tap}" type vlan id ${4} - /sbin/ifconfig "${tap}" 0.0.0.0 up - /sbin/brctl addif "${bridge}" "${tap}" -} - -ip tuntap add dev cvd-net-01 mode tap group cvdnetwork -ifconfig cvd-net-01 0.0.0.0 up - -create_interface w 1 192.168.93 11 -create_interface m 1 192.168.94 12 -create_interface i 1 192.168.95 13 |