Merge "Remove PowerHAL 1.0 from device manifest"
diff --git a/guest/hals/ril/libril/ril_service.cpp b/guest/hals/ril/libril/ril_service.cpp
index 43ccc6f..7349845 100755
--- a/guest/hals/ril/libril/ril_service.cpp
+++ b/guest/hals/ril/libril/ril_service.cpp
@@ -558,6 +558,7 @@
bool preferredForEmergencyCall);
Return<void> setIndicationFilter_1_5(int32_t serial,
hidl_bitfield<::android::hardware::radio::V1_5::IndicationFilter> indicationFilter);
+ Return<void> getBarringInfo(int32_t serial);
};
struct OemHookImpl : public IOemHook {
@@ -3775,6 +3776,14 @@
return Void();
}
+Return<void> RadioImpl_1_5::getBarringInfo(int32_t /* serial */) {
+ // TODO implement
+#if VDBG
+ RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+ return Void();
+}
+
// OEM hook methods:
Return<void> OemHookImpl::setResponseFunctions(
const ::android::sp<IOemHookResponse>& oemHookResponseParam,
@@ -8141,6 +8150,28 @@
return 0;
}
+int radio_1_5::getBarringInfoResponse(int slotId,
+ int responseType, int serial, RIL_Errno e,
+ void *response, size_t responselen) {
+#if VDBG
+ RLOGD("getBarringInfoResponse: serial %d", serial);
+#endif
+
+ if (radioService[slotId]->mRadioResponseV1_5 != NULL) {
+ RadioResponseInfo responseInfo = {};
+ populateResponseInfo(responseInfo, serial, responseType, e);
+ hidl_vec<::android::hardware::radio::V1_5::BarringInfo> barringInfo;
+ Return<void> retStatus
+ = radioService[slotId]->mRadioResponseV1_5->
+ getBarringInfoResponse(responseInfo, barringInfo);
+ radioService[slotId]->checkReturnStatus(retStatus);
+ } else {
+ RLOGE("getBarringInfoResponse: radioService[%d]->mRadioResponse == NULL",
+ slotId);
+ }
+
+ return 0;
+}
/***************************************************************************************************
* INDICATION FUNCTIONS
@@ -9963,7 +9994,7 @@
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);
+ LOG_ALWAYS_FATAL_IF(status != android::OK, "status %d", status);
RLOGD("registerService: OemHook is enabled = %s", kOemHookEnabled ? "true" : "false");
if (kOemHookEnabled) {
diff --git a/guest/hals/ril/libril/ril_service.h b/guest/hals/ril/libril/ril_service.h
index 98ebfa2..7807004 100644
--- a/guest/hals/ril/libril/ril_service.h
+++ b/guest/hals/ril/libril/ril_service.h
@@ -804,6 +804,9 @@
int setIndicationFilterResponse_1_5(int slotId, int responseType, int serial, RIL_Errno e,
void *response, size_t responselen);
+int getBarringInfoResponse(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);
diff --git a/host/frontend/gcastv2/libsource/Android.bp b/host/frontend/gcastv2/libsource/Android.bp
index 569c1c7..671e4ba 100644
--- a/host/frontend/gcastv2/libsource/Android.bp
+++ b/host/frontend/gcastv2/libsource/Android.bp
@@ -16,6 +16,8 @@
name: "libsource",
srcs: [
"AudioSource.cpp",
+ "InputSink.cpp",
+ "KeyboardSink.cpp",
"TouchSink.cpp",
"FrameBufferSource.cpp",
"HostToGuestComms.cpp",
diff --git a/host/frontend/gcastv2/libsource/InputSink.cpp b/host/frontend/gcastv2/libsource/InputSink.cpp
new file mode 100644
index 0000000..e673358
--- /dev/null
+++ b/host/frontend/gcastv2/libsource/InputSink.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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 <source/InputSink.h>
+
+#include <linux/input.h>
+
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glog/logging.h>
+#include <https/SafeCallbackable.h>
+#include <https/Support.h>
+
+namespace android {
+
+namespace {
+
+// TODO de-dup this from vnc server and here
+struct virtio_input_event {
+ uint16_t type;
+ uint16_t code;
+ int32_t value;
+};
+
+template <typename T>
+struct InputEventBufferImpl : public InputEventBuffer {
+ InputEventBufferImpl() {
+ buffer_.reserve(6); // 6 is usually enough even for multi-touch
+ }
+ void addEvent(uint16_t type, uint16_t code, int32_t value) override {
+ buffer_.push_back({.type = type, .code = code, .value = value});
+ }
+ T* data() { return buffer_.data(); }
+ const void* data() const override { return buffer_.data(); }
+ std::size_t size() const override { return buffer_.size() * sizeof(T); }
+
+ private:
+ std::vector<T> buffer_;
+};
+
+} // namespace
+
+InputSink::InputSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
+ bool write_virtio_input)
+ : mRunLoop(runLoop),
+ mServerFd(serverFd),
+ mClientFd(-1),
+ mSendPending(false),
+ mWriteVirtioInput(write_virtio_input) {
+ if (mServerFd >= 0) {
+ makeFdNonblocking(mServerFd);
+ }
+}
+
+InputSink::~InputSink() {
+ if (mClientFd >= 0) {
+ mRunLoop->cancelSocket(mClientFd);
+
+ close(mClientFd);
+ mClientFd = -1;
+ }
+
+ if (mServerFd >= 0) {
+ mRunLoop->cancelSocket(mServerFd);
+
+ close(mServerFd);
+ mServerFd = -1;
+ }
+}
+
+void InputSink::start() {
+ if (mServerFd < 0) {
+ return;
+ }
+
+ mRunLoop->postSocketRecv(
+ mServerFd, makeSafeCallback(this, &InputSink::onServerConnection));
+}
+
+std::unique_ptr<InputEventBuffer> InputSink::getEventBuffer() const {
+ InputEventBuffer* raw_ptr;
+ if (mWriteVirtioInput) {
+ raw_ptr = new InputEventBufferImpl<virtio_input_event>();
+ } else {
+ raw_ptr = new InputEventBufferImpl<input_event>();
+ }
+ return std::unique_ptr<InputEventBuffer>(raw_ptr);
+}
+
+void InputSink::SendEvents(std::unique_ptr<InputEventBuffer> evt_buffer) {
+ sendRawEvents(evt_buffer->data(), evt_buffer->size());
+}
+
+void InputSink::onServerConnection() {
+ int s = accept(mServerFd, nullptr, nullptr);
+
+ if (s >= 0) {
+ if (mClientFd >= 0) {
+ LOG(INFO) << "Rejecting client, we already have one.";
+
+ // We already have a client.
+ close(s);
+ s = -1;
+ } else {
+ LOG(INFO) << "Accepted client socket " << s << ".";
+
+ makeFdNonblocking(s);
+
+ mClientFd = s;
+ }
+ }
+
+ mRunLoop->postSocketRecv(
+ mServerFd, makeSafeCallback(this, &InputSink::onServerConnection));
+}
+
+void InputSink::sendRawEvents(const void* evt_buffer, size_t size) {
+ if (size <= 0) return;
+
+ std::lock_guard autoLock(mLock);
+
+ if (mClientFd < 0) {
+ return;
+ }
+
+ size_t offset = mOutBuffer.size();
+ mOutBuffer.resize(offset + size);
+ memcpy(mOutBuffer.data() + offset, evt_buffer, size);
+
+ if (!mSendPending) {
+ mSendPending = true;
+
+ mRunLoop->postSocketSend(mClientFd,
+ makeSafeCallback(this, &InputSink::onSocketSend));
+ }
+}
+
+void InputSink::onSocketSend() {
+ std::lock_guard autoLock(mLock);
+
+ CHECK(mSendPending);
+ mSendPending = false;
+
+ if (mClientFd < 0) {
+ return;
+ }
+
+ ssize_t n;
+ while (!mOutBuffer.empty()) {
+ do {
+ n = ::send(mClientFd, mOutBuffer.data(), mOutBuffer.size(), 0);
+ } while (n < 0 && errno == EINTR);
+
+ if (n <= 0) {
+ break;
+ }
+
+ mOutBuffer.erase(mOutBuffer.begin(), mOutBuffer.begin() + n);
+ }
+
+ if ((n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || n == 0) {
+ LOG(ERROR) << "Client is gone.";
+
+ // Client is gone.
+ mRunLoop->cancelSocket(mClientFd);
+
+ close(mClientFd);
+ mClientFd = -1;
+ return;
+ }
+
+ if (!mOutBuffer.empty()) {
+ mSendPending = true;
+ mRunLoop->postSocketSend(mClientFd,
+ makeSafeCallback(this, &InputSink::onSocketSend));
+ }
+}
+
+} // namespace android
diff --git a/host/frontend/gcastv2/libsource/KeyboardSink.cpp b/host/frontend/gcastv2/libsource/KeyboardSink.cpp
new file mode 100644
index 0000000..526ade3
--- /dev/null
+++ b/host/frontend/gcastv2/libsource/KeyboardSink.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <source/KeyboardSink.h>
+
+#include <linux/input.h>
+
+#include <glog/logging.h>
+
+namespace android {
+
+KeyboardSink::KeyboardSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
+ bool write_virtio_input)
+ : sink_(
+ std::make_shared<InputSink>(runLoop, serverFd, write_virtio_input)) {}
+
+void KeyboardSink::injectEvent(bool down, uint16_t code) {
+ LOG(VERBOSE)
+ << "Received keyboard (down="
+ << down
+ << ", code="
+ << code;
+ auto buffer = sink_->getEventBuffer();
+ buffer->addEvent(EV_KEY, code, down);
+ buffer->addEvent(EV_SYN, 0, 0);
+ sink_->SendEvents(std::move(buffer));
+}
+
+} // namespace android
+
diff --git a/host/frontend/gcastv2/libsource/TouchSink.cpp b/host/frontend/gcastv2/libsource/TouchSink.cpp
index dc0c309..a66744f 100644
--- a/host/frontend/gcastv2/libsource/TouchSink.cpp
+++ b/host/frontend/gcastv2/libsource/TouchSink.cpp
@@ -22,130 +22,18 @@
#include <android-base/logging.h>
#include <linux/input.h>
-#include <linux/uinput.h>
#include <sys/socket.h>
#include <unistd.h>
namespace android {
-namespace {
-// TODO de-dup this from vnc server and here
-struct virtio_input_event {
- uint16_t type;
- uint16_t code;
- int32_t value;
-};
-
-template <typename T>
-void SendEvent(int32_t x, int32_t y, int32_t down,
- std::function<void(const void*, size_t)> sender) {
- std::vector<T> events = {{.type = EV_ABS, .code = ABS_X, .value = x},
- {.type = EV_ABS, .code = ABS_Y, .value = y},
- {.type = EV_KEY, .code = BTN_TOUCH, .value = down},
- {.type = EV_SYN, .code = 0, .value = 0}};
- sender(events.data(), events.size() * sizeof(T));
-}
-
-template <typename T>
-void SendMTEvent(int32_t /* id */, int32_t x, int32_t y, int32_t initial_down,
- int32_t /* slot */,
- std::function<void(const void*, size_t)> sender) {
- // TODO(b/124121375): multitouch
- SendEvent<T>(x, y, initial_down, sender);
-}
-}
-
TouchSink::TouchSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
bool write_virtio_input)
- : mRunLoop(runLoop),
- mServerFd(serverFd),
- mClientFd(-1),
- mSendPending(false) {
- if (mServerFd >= 0) {
- makeFdNonblocking(mServerFd);
- }
- if (write_virtio_input) {
- send_event_ = [this](int32_t x, int32_t y, bool down) {
- SendEvent<virtio_input_event>(
- x, y, down, [this](const void* b, size_t l) { sendRawEvents(b, l); });
- };
- send_mt_event_ = [this](int32_t id, int32_t x, int32_t y, bool initialDown,
- int32_t slot) {
- SendMTEvent<virtio_input_event>(
- id, x, y, initialDown, slot,
- [this](const void* b, size_t l) { sendRawEvents(b, l); });
- };
- } else {
- send_event_ = [this](int32_t x, int32_t y, bool down) {
- SendEvent<input_event>(
- x, y, down, [this](const void* b, size_t l) { sendRawEvents(b, l); });
- };
- send_mt_event_ = [this](int32_t id, int32_t x, int32_t y, bool initialDown,
- int32_t slot) {
- SendMTEvent<input_event>(
- id, x, y, initialDown, slot,
- [this](const void* b, size_t l) { sendRawEvents(b, l); });
- };
- }
-}
+ : sink_(
+ std::make_shared<InputSink>(runLoop, serverFd, write_virtio_input)) {}
-TouchSink::~TouchSink() {
- if (mClientFd >= 0) {
- mRunLoop->cancelSocket(mClientFd);
-
- close(mClientFd);
- mClientFd = -1;
- }
-
- if (mServerFd >= 0) {
- mRunLoop->cancelSocket(mServerFd);
-
- close(mServerFd);
- mServerFd = -1;
- }
-}
-
-void TouchSink::start() {
- if (mServerFd < 0) {
- return;
- }
-
- mRunLoop->postSocketRecv(
- mServerFd,
- makeSafeCallback(this, &TouchSink::onServerConnection));
-}
-
-void TouchSink::onServerConnection() {
- int s = accept(mServerFd, nullptr, nullptr);
-
- if (s >= 0) {
- if (mClientFd >= 0) {
- LOG(INFO) << "Rejecting client, we already have one.";
-
- // We already have a client.
- close(s);
- s = -1;
- } else {
- LOG(INFO) << "Accepted client socket " << s << ".";
-
- makeFdNonblocking(s);
-
- mClientFd = s;
- }
- }
-
- mRunLoop->postSocketRecv(
- mServerFd,
- makeSafeCallback(this, &TouchSink::onServerConnection));
-}
-
-
-void TouchSink::onAccessUnit(const std::shared_ptr<InputEvent> &accessUnit) {
- bool down = accessUnit->down != 0;
- int x = accessUnit->x;
- int y = accessUnit->y;
-
+void TouchSink::injectTouchEvent(int32_t x, int32_t y, bool down) {
LOG(VERBOSE)
<< "Received touch (down="
<< down
@@ -154,71 +42,18 @@
<< ", y="
<< y;
- send_event_(x, y, down);
+ auto buffer = sink_->getEventBuffer();
+ buffer->addEvent(EV_ABS, ABS_X, x);
+ buffer->addEvent(EV_ABS, ABS_Y, y);
+ buffer->addEvent(EV_KEY, BTN_TOUCH, down);
+ buffer->addEvent(EV_SYN, 0, 0);
+ sink_->SendEvents(std::move(buffer));
}
-void TouchSink::sendRawEvents(const void* evt_buffer, size_t size) {
- if (size <= 0) return;
-
- std::lock_guard autoLock(mLock);
-
- if (mClientFd < 0) {
- return;
- }
-
- size_t offset = mOutBuffer.size();
- mOutBuffer.resize(offset + size);
- memcpy(mOutBuffer.data() + offset, evt_buffer, size);
-
- if (!mSendPending) {
- mSendPending = true;
-
- mRunLoop->postSocketSend(
- mClientFd,
- makeSafeCallback(this, &TouchSink::onSocketSend));
- }
-}
-
-void TouchSink::onSocketSend() {
- std::lock_guard autoLock(mLock);
-
- CHECK(mSendPending);
- mSendPending = false;
-
- if (mClientFd < 0) {
- return;
- }
-
- ssize_t n;
- while (!mOutBuffer.empty()) {
- do {
- n = ::send(mClientFd, mOutBuffer.data(), mOutBuffer.size(), 0);
- } while (n < 0 && errno == EINTR);
-
- if (n <= 0) {
- break;
- }
-
- mOutBuffer.erase(mOutBuffer.begin(), mOutBuffer.begin() + n);
- }
-
- if ((n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) || n == 0) {
- LOG(ERROR) << "Client is gone.";
-
- // Client is gone.
- mRunLoop->cancelSocket(mClientFd);
-
- close(mClientFd);
- mClientFd = -1;
- return;
- }
-
- if (!mOutBuffer.empty()) {
- mSendPending = true;
- mRunLoop->postSocketSend(
- mClientFd,
- makeSafeCallback(this, &TouchSink::onSocketSend));
- }
+void TouchSink::injectMultiTouchEvent(int32_t /*id*/, int32_t /*slot*/,
+ int32_t x, int32_t y, bool initialDown) {
+ // TODO (muntsinger): Enable multitouch
+ return injectTouchEvent(x, y, initialDown);
}
} // namespace android
diff --git a/host/frontend/gcastv2/libsource/include/source/InputSink.h b/host/frontend/gcastv2/libsource/include/source/InputSink.h
new file mode 100644
index 0000000..ba5af91
--- /dev/null
+++ b/host/frontend/gcastv2/libsource/include/source/InputSink.h
@@ -0,0 +1,62 @@
+/*
+ * 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 <array>
+#include <cinttypes>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <https/RunLoop.h>
+
+namespace android {
+
+struct InputEventBuffer {
+ virtual ~InputEventBuffer() = default;
+ virtual void addEvent(uint16_t type, uint16_t code, int32_t value) = 0;
+ virtual size_t size() const = 0;
+ virtual const void* data() const = 0;
+};
+
+struct InputSink : public std::enable_shared_from_this<InputSink> {
+ explicit InputSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
+ bool write_virtio_input);
+ ~InputSink();
+ void start();
+
+ std::unique_ptr<InputEventBuffer> getEventBuffer() const;
+ void SendEvents(std::unique_ptr<InputEventBuffer> evt_buffer);
+
+ private:
+ std::shared_ptr<RunLoop> mRunLoop;
+ int mServerFd;
+
+ int mClientFd;
+
+ std::mutex mLock;
+ std::vector<uint8_t> mOutBuffer;
+ bool mSendPending;
+ bool mWriteVirtioInput;
+
+ void onServerConnection();
+ void onSocketSend();
+
+ void sendRawEvents(const void* evt_buffer, size_t length);
+};
+
+} // namespace android
diff --git a/host/frontend/gcastv2/libsource/include/source/StreamingSink.h b/host/frontend/gcastv2/libsource/include/source/KeyboardSink.h
similarity index 60%
rename from host/frontend/gcastv2/libsource/include/source/StreamingSink.h
rename to host/frontend/gcastv2/libsource/include/source/KeyboardSink.h
index 2d308be..cbc9936 100644
--- a/host/frontend/gcastv2/libsource/include/source/StreamingSink.h
+++ b/host/frontend/gcastv2/libsource/include/source/KeyboardSink.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,21 +19,22 @@
#include <cinttypes>
#include <memory>
+#include <https/RunLoop.h>
+#include <source/InputSink.h>
+
namespace android {
-// TODO(jemoreira): add support for multitouch
-struct InputEvent{
- InputEvent(int32_t down, int32_t x, int32_t y) : down(down), x(x), y(y) {}
- int32_t down;
- int32_t x;
- int32_t y;
-};
+struct KeyboardSink {
+ explicit KeyboardSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
+ bool write_virtio_input);
+ ~KeyboardSink() = default;
-struct StreamingSink {
- explicit StreamingSink() = default;
- virtual ~StreamingSink() = default;
+ void start() {sink_->start();}
- virtual void onAccessUnit(const std::shared_ptr<InputEvent> &accessUnit) = 0;
+ void injectEvent(bool down, uint16_t code);
+
+ private:
+ std::shared_ptr<InputSink> sink_;
};
} // namespace android
diff --git a/host/frontend/gcastv2/libsource/include/source/TouchSink.h b/host/frontend/gcastv2/libsource/include/source/TouchSink.h
index 048b523..d4490f0 100644
--- a/host/frontend/gcastv2/libsource/include/source/TouchSink.h
+++ b/host/frontend/gcastv2/libsource/include/source/TouchSink.h
@@ -17,41 +17,26 @@
#pragma once
#include <https/RunLoop.h>
-#include <source/StreamingSink.h>
-#include <functional>
#include <memory>
-#include <vector>
+
+#include <source/InputSink.h>
namespace android {
-struct TouchSink
- : public StreamingSink, public std::enable_shared_from_this<TouchSink> {
+struct TouchSink {
explicit TouchSink(std::shared_ptr<RunLoop> runLoop, int serverFd,
bool write_virtio_input);
- ~TouchSink() override;
+ ~TouchSink() = default;
- void start();
+ void start() {sink_->start();}
- void onAccessUnit(const std::shared_ptr<InputEvent> &accessUnit) override;
+ void injectTouchEvent(int32_t x, int32_t y, bool down);
+ void injectMultiTouchEvent(int32_t id, int32_t slot, int32_t x, int32_t y,
+ bool initialDown);
-private:
- std::shared_ptr<RunLoop> mRunLoop;
- int mServerFd;
-
- int mClientFd;
-
- std::mutex mLock;
- std::vector<uint8_t> mOutBuffer;
- bool mSendPending;
-
- std::function<void(int32_t, int32_t, bool)> send_event_;
- std::function<void(int32_t, int32_t, int32_t, bool, int32_t)> send_mt_event_;
-
- void onServerConnection();
- void onSocketSend();
-
- void sendRawEvents(const void* evt_buffer, size_t length);
+ private:
+ std::shared_ptr<InputSink> sink_;
};
} // namespace android
diff --git a/host/frontend/gcastv2/webrtc/Android.bp b/host/frontend/gcastv2/webrtc/Android.bp
index c048ff4..85e0644 100644
--- a/host/frontend/gcastv2/webrtc/Android.bp
+++ b/host/frontend/gcastv2/webrtc/Android.bp
@@ -19,6 +19,7 @@
"AdbWebSocketHandler.cpp",
"DTLS.cpp",
"G711Packetizer.cpp",
+ "Keyboard.cpp",
"MyWebSocketHandler.cpp",
"OpusPacketizer.cpp",
"Packetizer.cpp",
diff --git a/host/frontend/gcastv2/webrtc/Keyboard.cpp b/host/frontend/gcastv2/webrtc/Keyboard.cpp
new file mode 100644
index 0000000..052f300
--- /dev/null
+++ b/host/frontend/gcastv2/webrtc/Keyboard.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <webrtc/Keyboard.h>
+
+#include <linux/input.h>
+
+#include <map>
+
+static const std::map<std::string, uint16_t> kDomToLinuxMapping = {
+ {"Backquote", KEY_GRAVE},
+ {"Backslash", KEY_BACKSLASH},
+ {"Backspace", KEY_BACKSPACE},
+ {"BracketLeft", KEY_LEFTBRACE},
+ {"BracketRight", KEY_RIGHTBRACE},
+ {"Comma", KEY_COMMA},
+ {"Digit0", KEY_0},
+ {"Digit1", KEY_1},
+ {"Digit2", KEY_2},
+ {"Digit3", KEY_3},
+ {"Digit4", KEY_4},
+ {"Digit5", KEY_5},
+ {"Digit6", KEY_6},
+ {"Digit7", KEY_7},
+ {"Digit8", KEY_8},
+ {"Digit9", KEY_9},
+ {"Equal", KEY_EQUAL},
+ {"IntlBackslash", KEY_BACKSLASH},
+ {"IntlRo", KEY_RO},
+ {"IntlYen", KEY_BACKSLASH},
+ {"KeyA", KEY_A},
+ {"KeyB", KEY_B},
+ {"KeyC", KEY_C},
+ {"KeyD", KEY_D},
+ {"KeyE", KEY_E},
+ {"KeyF", KEY_F},
+ {"KeyG", KEY_G},
+ {"KeyH", KEY_H},
+ {"KeyI", KEY_I},
+ {"KeyJ", KEY_J},
+ {"KeyK", KEY_K},
+ {"KeyL", KEY_L},
+ {"KeyM", KEY_M},
+ {"KeyN", KEY_N},
+ {"KeyO", KEY_O},
+ {"KeyP", KEY_P},
+ {"KeyQ", KEY_Q},
+ {"KeyR", KEY_R},
+ {"KeyS", KEY_S},
+ {"KeyT", KEY_T},
+ {"KeyU", KEY_U},
+ {"KeyV", KEY_V},
+ {"KeyW", KEY_W},
+ {"KeyX", KEY_X},
+ {"KeyY", KEY_Y},
+ {"KeyZ", KEY_Z},
+ {"Minus", KEY_MINUS},
+ {"Period", KEY_DOT},
+ {"Quote", KEY_APOSTROPHE},
+ {"Semicolon", KEY_SEMICOLON},
+ {"Slash", KEY_SLASH},
+ {"AltLeft", KEY_LEFTALT},
+ {"AltRight", KEY_RIGHTALT},
+ {"CapsLock", KEY_CAPSLOCK},
+ {"ContextMenu", KEY_CONTEXT_MENU},
+ {"ControlLeft", KEY_LEFTCTRL},
+ {"ControlRight", KEY_RIGHTCTRL},
+ {"Enter", KEY_ENTER},
+ {"MetaLeft", KEY_LEFTMETA},
+ {"MetaRight", KEY_RIGHTMETA},
+ {"ShiftLeft", KEY_LEFTSHIFT},
+ {"ShiftRight", KEY_RIGHTSHIFT},
+ {"Space", KEY_SPACE},
+ {"Tab", KEY_TAB},
+ {"Delete", KEY_DELETE},
+ {"End", KEY_END},
+ {"Help", KEY_HELP},
+ {"Home", KEY_HOME},
+ {"Insert", KEY_INSERT},
+ {"PageDown", KEY_PAGEDOWN},
+ {"PageUp", KEY_PAGEUP},
+ {"ArrowDown", KEY_DOWN},
+ {"ArrowLeft", KEY_LEFT},
+ {"ArrowRight", KEY_RIGHT},
+ {"ArrowUp", KEY_UP},
+
+ {"NumLock", KEY_NUMLOCK},
+ {"Numpad0", KEY_KP0},
+ {"Numpad1", KEY_KP1},
+ {"Numpad2", KEY_KP2},
+ {"Numpad3", KEY_KP3},
+ {"Numpad4", KEY_KP4},
+ {"Numpad5", KEY_KP5},
+ {"Numpad6", KEY_KP6},
+ {"Numpad7", KEY_KP7},
+ {"Numpad8", KEY_KP8},
+ {"Numpad9", KEY_KP9},
+ {"NumpadAdd", KEY_KPPLUS},
+ {"NumpadBackspace", KEY_BACKSPACE},
+ {"NumpadClear", KEY_CLEAR},
+ {"NumpadComma", KEY_KPCOMMA},
+ {"NumpadDecimal", KEY_KPDOT},
+ {"NumpadDivide", KEY_KPSLASH},
+ {"NumpadEnter", KEY_KPENTER},
+ {"NumpadEqual", KEY_KPEQUAL},
+ /*
+ {"NumpadClearEntry", },
+ {"NumpadHash", },
+ {"NumpadMemoryAdd", },
+ {"NumpadMemoryClear", },
+ {"NumpadMemoryRecall", },
+ {"NumpadMemoryStore", },
+ {"NumpadMemorySubtract", },
+ */
+ {"NumpadMultiply", KEY_KPASTERISK},
+ {"NumpadParenLeft", KEY_KPLEFTPAREN},
+ {"NumpadParenRight", KEY_KPRIGHTPAREN},
+ {"NumpadStar", KEY_KPASTERISK},
+ {"NumpadSubtract", KEY_KPMINUS},
+
+ {"Escape", KEY_ESC},
+ {"F1", KEY_F1},
+ {"F2", KEY_F2},
+ {"F3", KEY_F3},
+ {"F4", KEY_F4},
+ {"F5", KEY_F5},
+ {"F6", KEY_F6},
+ {"F7", KEY_F7},
+ {"F8", KEY_F8},
+ {"F9", KEY_F9},
+ {"F10", KEY_F10},
+ {"F11", KEY_F11},
+ {"F12", KEY_F12},
+ {"Fn", KEY_FN},
+ /*{"FnLock", },*/
+ {"PrintScreen", KEY_SYSRQ},
+ {"ScrollLock", KEY_SCROLLLOCK},
+ {"Pause", KEY_PAUSE}};
+
+uint16_t DomKeyCodeToLinux(const std::string& dom_KEY_code) {
+ const auto it = kDomToLinuxMapping.find(dom_KEY_code);
+ if (it == kDomToLinuxMapping.end()) {
+ return 0;
+ }
+ return it->second;
+}
diff --git a/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp b/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
index c167197..7faf9af 100644
--- a/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
+++ b/host/frontend/gcastv2/webrtc/MyWebSocketHandler.cpp
@@ -23,7 +23,7 @@
#include <netdb.h>
#include <openssl/rand.h>
-using android::InputEvent;
+#include <webrtc/Keyboard.h>
MyWebSocketHandler::MyWebSocketHandler(
std::shared_ptr<RunLoop> runLoop,
@@ -33,7 +33,8 @@
mServerState(serverState),
mId(handlerId),
mOptions(OptionBits::useSingleCertificateForAllTracks),
- mTouchSink(mServerState->getTouchSink()) {
+ mTouchSink(mServerState->getTouchSink()),
+ mKeyboardSink(mServerState->getKeyboardSink()) {
}
MyWebSocketHandler::~MyWebSocketHandler() {
@@ -242,9 +243,7 @@
LOG(VERBOSE)
<< "set-mouse-position(" << down << ", " << x << ", " << y << ")";
- std::shared_ptr<InputEvent> accessUnit(new InputEvent(down, x, y));
-
- mTouchSink->onAccessUnit(accessUnit);
+ mTouchSink->injectTouchEvent(x, y, down != 0);
} else if (type == "inject-multi-touch") {
CHECK(obj.isMember("id"));
CHECK(obj.isMember("initialDown"));
@@ -269,19 +268,14 @@
<< ", slot="
<< slot;
- std::shared_ptr<InputEvent> accessUnit(new InputEvent(initialDown != 0, x, y));
- accessUnit->down = (initialDown != 0);
- accessUnit->x = x;
- accessUnit->y = y;
- // TODO(jemoreira): revive for multitouch
- // int32_t *data = reinterpret_cast<int32_t *>(accessUnit->data());
- // data[0] = id;
- // data[1] = (initialDown != 0);
- // data[2] = x;
- // data[3] = y;
- // data[4] = slot;
-
- mTouchSink->onAccessUnit(accessUnit);
+ mTouchSink->injectMultiTouchEvent(id, slot, x, y, initialDown);
+ } else if (type == "key-event") {
+ CHECK(obj.isMember("event_type"));
+ auto down = obj["event_type"].asString() == std::string("keydown");
+ CHECK(obj.isMember("keycode"));
+ auto code = DomKeyCodeToLinux(obj["keycode"].asString());
+ CHECK(code);
+ mKeyboardSink->injectEvent(down, code);
}
return 0;
diff --git a/host/frontend/gcastv2/webrtc/ServerState.cpp b/host/frontend/gcastv2/webrtc/ServerState.cpp
index 8f5fbbb..e713135 100644
--- a/host/frontend/gcastv2/webrtc/ServerState.cpp
+++ b/host/frontend/gcastv2/webrtc/ServerState.cpp
@@ -27,6 +27,7 @@
#include <gflags/gflags.h>
+DECLARE_int32(keyboard_fd);
DECLARE_int32(touch_fd);
DECLARE_int32(frame_server_fd);
DECLARE_bool(write_virtio_input);
@@ -84,15 +85,22 @@
});
mAudioComms->start();
-
+
CHECK_GE(FLAGS_touch_fd, 0);
- auto touchSink =
- std::make_shared<android::TouchSink>(mRunLoop, FLAGS_touch_fd, FLAGS_write_virtio_input);
+ auto touchSink = std::make_shared<android::TouchSink>(
+ mRunLoop, FLAGS_touch_fd, FLAGS_write_virtio_input);
touchSink->start();
mTouchSink = touchSink;
+
+ auto keyboardSink = std::make_shared<android::KeyboardSink>(
+ mRunLoop, FLAGS_keyboard_fd, FLAGS_write_virtio_input);
+
+ keyboardSink->start();
+
+ mKeyboardSink = keyboardSink;
}
void ServerState::MonitorScreenConnector() {
@@ -158,6 +166,10 @@
CHECK_EQ(mAllocatedHandlerIds.erase(id), 1);
}
-std::shared_ptr<android::StreamingSink> ServerState::getTouchSink() {
+std::shared_ptr<android::TouchSink> ServerState::getTouchSink() {
return mTouchSink;
}
+
+std::shared_ptr<android::KeyboardSink> ServerState::getKeyboardSink() {
+ return mKeyboardSink;
+}
diff --git a/host/frontend/gcastv2/webrtc/assets/index.html b/host/frontend/gcastv2/webrtc/assets/index.html
index 69995fc..252c98e 100644
--- a/host/frontend/gcastv2/webrtc/assets/index.html
+++ b/host/frontend/gcastv2/webrtc/assets/index.html
@@ -7,6 +7,7 @@
<body>
<button id="receiveButton">Receive Media</button>
+ <button id="keyboardCaptureBtn">Capture Keyboard</button>
<hr>
<section class="noscroll">
<div class="one" >
diff --git a/host/frontend/gcastv2/webrtc/assets/js/receive.js b/host/frontend/gcastv2/webrtc/assets/js/receive.js
index 25b1c71..3e3ab58 100644
--- a/host/frontend/gcastv2/webrtc/assets/js/receive.js
+++ b/host/frontend/gcastv2/webrtc/assets/js/receive.js
@@ -2,6 +2,8 @@
const receiveButton = document.getElementById('receiveButton');
receiveButton.addEventListener('click', onReceive);
+const keyboardCaptureButton = document.getElementById('keyboardCaptureBtn');
+keyboardCaptureButton.addEventListener('click', onKeyboardCaptureClick);
const videoElement = document.getElementById('video');
@@ -47,6 +49,17 @@
console.log('handleDataChannelMessage data="' + event.data + '"');
}
+function onKeyboardCaptureClick(e) {
+ const selectedClass = 'selected';
+ if (keyboardCaptureButton.classList.contains(selectedClass)) {
+ stopKeyboardTracking();
+ keyboardCaptureButton.classList.remove(selectedClass);
+ } else {
+ startKeyboardTracking();
+ keyboardCaptureButton.classList.add(selectedClass);
+ }
+}
+
async function onReceive() {
console.log('onReceive');
receiveButton.disabled = true;
@@ -401,6 +414,16 @@
}
}
+function startKeyboardTracking() {
+ document.addEventListener('keydown', onKeyEvent);
+ document.addEventListener('keyup', onKeyEvent);
+}
+
+function stopKeyboardTracking() {
+ document.removeEventListener('keydown', onKeyEvent);
+ document.removeEventListener('keyup', onKeyEvent);
+}
+
function onStartDrag(e) {
e.preventDefault();
@@ -467,3 +490,7 @@
+ '}');
}
+function onKeyEvent(e) {
+ e.preventDefault();
+ ws.send('{"type": "key-event","keycode": "'+e.code+'", "event_type": "'+e.type+'"}');
+}
\ No newline at end of file
diff --git a/host/frontend/gcastv2/webrtc/assets/style.css b/host/frontend/gcastv2/webrtc/assets/style.css
index 96b27e6..a782b0a 100644
--- a/host/frontend/gcastv2/webrtc/assets/style.css
+++ b/host/frontend/gcastv2/webrtc/assets/style.css
@@ -22,3 +22,8 @@
padding: 10px;
}
+button.selected {
+ background-color: #aaaaaa;
+ border-style: solid;
+ border-color: #aaaaaa;
+}
\ No newline at end of file
diff --git a/host/frontend/gcastv2/webrtc/include/webrtc/Keyboard.h b/host/frontend/gcastv2/webrtc/include/webrtc/Keyboard.h
new file mode 100644
index 0000000..84c4876
--- /dev/null
+++ b/host/frontend/gcastv2/webrtc/include/webrtc/Keyboard.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <cinttypes>
+#include <string>
+
+uint16_t DomKeyCodeToLinux(const std::string& dom_key_code);
diff --git a/host/frontend/gcastv2/webrtc/include/webrtc/MyWebSocketHandler.h b/host/frontend/gcastv2/webrtc/include/webrtc/MyWebSocketHandler.h
index a89b257..fef87cb 100644
--- a/host/frontend/gcastv2/webrtc/include/webrtc/MyWebSocketHandler.h
+++ b/host/frontend/gcastv2/webrtc/include/webrtc/MyWebSocketHandler.h
@@ -23,7 +23,8 @@
#include <https/WebSocketHandler.h>
#include <https/RunLoop.h>
-#include <source/StreamingSink.h>
+#include <source/KeyboardSink.h>
+#include <source/TouchSink.h>
#include <memory>
#include <optional>
@@ -53,7 +54,8 @@
useSingleCertificateForAllTracks = 8,
};
- using StreamingSink = android::StreamingSink;
+ using TouchSink = android::TouchSink;
+ using KeyboardSink = android::KeyboardSink;
std::shared_ptr<RunLoop> mRunLoop;
std::shared_ptr<ServerState> mServerState;
@@ -68,7 +70,8 @@
SDP mOfferedSDP;
std::vector<std::shared_ptr<RTPSocketHandler>> mRTPs;
- std::shared_ptr<StreamingSink> mTouchSink;
+ std::shared_ptr<TouchSink> mTouchSink;
+ std::shared_ptr<KeyboardSink> mKeyboardSink;
std::pair<std::shared_ptr<X509>, std::shared_ptr<EVP_PKEY>>
mCertificateAndKey;
diff --git a/host/frontend/gcastv2/webrtc/include/webrtc/ServerState.h b/host/frontend/gcastv2/webrtc/include/webrtc/ServerState.h
index b56a7f9..a0702f6 100644
--- a/host/frontend/gcastv2/webrtc/include/webrtc/ServerState.h
+++ b/host/frontend/gcastv2/webrtc/include/webrtc/ServerState.h
@@ -22,7 +22,8 @@
#include <source/HostToGuestComms.h>
-#include <source/StreamingSink.h>
+#include <source/KeyboardSink.h>
+#include <source/TouchSink.h>
#include <source/StreamingSource.h>
#include <memory>
@@ -32,7 +33,8 @@
#include <host/libs/screen_connector/screen_connector.h>
struct ServerState {
- using StreamingSink = android::StreamingSink;
+ using TouchSink = android::TouchSink;
+ using KeyboardSink = android::KeyboardSink;
enum class VideoFormat {
VP8,
@@ -43,7 +45,8 @@
std::shared_ptr<Packetizer> getVideoPacketizer();
std::shared_ptr<Packetizer> getAudioPacketizer();
- std::shared_ptr<StreamingSink> getTouchSink();
+ std::shared_ptr<TouchSink> getTouchSink();
+ std::shared_ptr<KeyboardSink> getKeyboardSink();
VideoFormat videoFormat() const { return mVideoFormat; }
@@ -68,7 +71,8 @@
std::shared_ptr<cvd::ScreenConnector> mScreenConnector;
std::shared_ptr<std::thread> mScreenConnectorMonitor;
- std::shared_ptr<StreamingSink> mTouchSink;
+ std::shared_ptr<TouchSink> mTouchSink;
+ std::shared_ptr<KeyboardSink> mKeyboardSink;
std::set<size_t> mAllocatedHandlerIds;
diff --git a/shared/config/manifest.xml b/shared/config/manifest.xml
index 6dc737a..cde4e443 100644
--- a/shared/config/manifest.xml
+++ b/shared/config/manifest.xml
@@ -185,6 +185,15 @@
</hal>
-->
<hal format="hidl">
+ <name>android.hardware.identity</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IIdentityCredentialStore</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
<name>android.hardware.keymaster</name>
<transport>hwbinder</transport>
<version>4.1</version>
diff --git a/shared/device.mk b/shared/device.mk
index 99c9df9..955232a 100644
--- a/shared/device.mk
+++ b/shared/device.mk
@@ -260,6 +260,10 @@
PRODUCT_PACKAGES += \
android.hardware.health.storage@1.0-service.cuttlefish
+# Identity Credential
+PRODUCT_PACKAGES += \
+ android.hardware.identity@1.0-service.example
+
# Input Classifier HAL
PRODUCT_PACKAGES += \
android.hardware.input.classifier@1.0-service.default
diff --git a/shared/sepolicy/vendor/file_contexts b/shared/sepolicy/vendor/file_contexts
index 5000e6f..a5ed5b7 100644
--- a/shared/sepolicy/vendor/file_contexts
+++ b/shared/sepolicy/vendor/file_contexts
@@ -56,10 +56,10 @@
/vendor/bin/hw/libcuttlefish-rild u:object_r:libcuttlefish_rild_exec:s0
/vendor/bin/hw/android\.hardware\.power\.stats@1\.0-service\.mock u:object_r:hal_power_stats_default_exec:s0
/vendor/bin/hw/android\.hardware\.bluetooth@1\.1-service\.sim u:object_r:hal_bluetooth_sim_exec:s0
-/vendor/bin/hw/android\.hardware\.drm@1\.2-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
-/vendor/bin/hw/android\.hardware\.drm@1\.2-service-lazy\.clearkey u:object_r:hal_drm_clearkey_exec:s0
-/vendor/bin/hw/android\.hardware\.drm@1\.2-service\.widevine u:object_r:hal_drm_widevine_exec:s0
-/vendor/bin/hw/android\.hardware\.drm@1\.2-service-lazy\.widevine u:object_r:hal_drm_widevine_exec:s0
+/vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service\.clearkey u:object_r:hal_drm_clearkey_exec:s0
+/vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service-lazy\.clearkey u:object_r:hal_drm_clearkey_exec:s0
+/vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service\.widevine u:object_r:hal_drm_widevine_exec:s0
+/vendor/bin/hw/android\.hardware\.drm@[0-9]+\.[0-9]+-service-lazy\.widevine u:object_r:hal_drm_widevine_exec:s0
/vendor/bin/hw/android\.hardware\.dumpstate@1\.0-service\.cuttlefish u:object_r:hal_dumpstate_impl_exec:s0
/vendor/bin/hw/android\.hardware\.gatekeeper@1\.0-service\.software u:object_r:hal_gatekeeper_default_exec:s0
/vendor/bin/hw/android\.hardware\.health\.storage@1\.0-service\.cuttlefish u:object_r:hal_health_storage_default_exec:s0