secure_fb_mock_impl: Add mock implementation of secure_fb service
Implement a mock backend for the secure_fb service.
Bug: 175731623
Change-Id: Ide15d2350904d15d3c80f95c2764cd1254f2ff2b
diff --git a/secure_fb_mock_impl/main.cpp b/secure_fb_mock_impl/main.cpp
new file mode 100644
index 0000000..58f5925
--- /dev/null
+++ b/secure_fb_mock_impl/main.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 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.
+ */
+
+#define TLOG_TAG "secure_fb_impl"
+
+#include <lib/secure_fb/srv/dev.h>
+#include <lib/secure_fb/srv/srv.h>
+#include <lib/tipc/tipc.h>
+#include <lk/err_ptr.h>
+#include <lk/macros.h>
+#include <memref.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <trusty_ipc.h>
+#include <trusty_log.h>
+
+#include <tuple>
+
+#define PAGE_SIZE() (getauxval(AT_PAGESZ))
+
+static constexpr const uint32_t kDeviceWidth = 400;
+static constexpr const uint32_t kDeviceHeight = 800;
+static constexpr const uint32_t kFbCount = 1;
+static constexpr const uint32_t kFbId = 0xdeadbeef;
+
+class SecureFbMockImpl {
+private:
+ struct FbDbEntry {
+ secure_fb_info fb_info;
+ handle_t handle;
+ ptrdiff_t offset;
+ };
+
+ FbDbEntry fb_db_[kFbCount];
+
+public:
+ int Init(uint32_t width, uint32_t height) {
+ uint32_t fb_size =
+ round_up(sizeof(uint32_t) * width * height, PAGE_SIZE());
+ /*
+ * Every secure_fb client (of which there can only be one at a time)
+ * gets the same framebuffer memory. We do this so to prevent running
+ * out of memory as the number of connections to secure_fb server grows
+ * over time.
+ */
+ static void* fb_base = memalign(PAGE_SIZE(), fb_size);
+ if (!fb_base) {
+ TLOGE("Failed to allocate framebuffer of size: %u\n", fb_size);
+ return SECURE_FB_ERROR_MEMORY_ALLOCATION;
+ }
+
+ /*
+ * Create a handle for the buffer by which it can be passed to the TUI
+ * app for rendering.
+ */
+ static int handle =
+ memref_create(fb_base, fb_size, PROT_READ | PROT_WRITE);
+ if (handle < 0) {
+ TLOGE("Failed to create memref (%d)\n", handle);
+ free(fb_base);
+ return SECURE_FB_ERROR_SHARED_MEMORY;
+ }
+
+ fb_db_[0] = {
+ .fb_info =
+ {
+ .buffer = (uint8_t*)fb_base,
+ .size = fb_size,
+ .pixel_stride = 4,
+ .line_stride = 4 * width,
+ .width = width,
+ .height = height,
+ .pixel_format = TTUI_PF_RGBA8,
+ },
+ .handle = handle,
+ };
+
+ return SECURE_FB_ERROR_OK;
+ }
+
+ int GetFbs(struct secure_fb_impl_buffers* buffers) {
+ *buffers = {
+ .num_fbs = 1,
+ .fbs[0] =
+ {
+ .buffer_id = kFbId,
+ .handle_index = 0,
+ .fb_info = fb_db_[0].fb_info,
+ },
+ .num_handles = 1,
+ .handles[0] = fb_db_[0].handle,
+ };
+ return SECURE_FB_ERROR_OK;
+ }
+
+ int Display(uint32_t buffer_id) {
+ if (buffer_id != kFbId) {
+ return SECURE_FB_ERROR_INVALID_REQUEST;
+ }
+
+ /* This is a no-op in the mock case. */
+ return SECURE_FB_ERROR_OK;
+ }
+};
+
+secure_fb_handle_t secure_fb_impl_init() {
+ auto sfb = new SecureFbMockImpl();
+ sfb->Init(kDeviceWidth, kDeviceHeight);
+ return sfb;
+}
+
+int secure_fb_impl_get_fbs(secure_fb_handle_t sfb_handle,
+ struct secure_fb_impl_buffers* buffers) {
+ SecureFbMockImpl* sfb = reinterpret_cast<SecureFbMockImpl*>(sfb_handle);
+ return sfb->GetFbs(buffers);
+}
+
+int secure_fb_impl_display_fb(secure_fb_handle_t sfb_handle,
+ uint32_t buffer_id) {
+ SecureFbMockImpl* sfb = reinterpret_cast<SecureFbMockImpl*>(sfb_handle);
+ return sfb->Display(buffer_id);
+}
+
+int secure_fb_impl_release(secure_fb_handle_t sfb_handle) {
+ SecureFbMockImpl* sfb = reinterpret_cast<SecureFbMockImpl*>(sfb_handle);
+ delete sfb;
+ return SECURE_FB_ERROR_OK;
+}
+
+int main(void) {
+ int rc;
+ struct tipc_hset* hset;
+
+ hset = tipc_hset_create();
+ if (IS_ERR(hset)) {
+ TLOGE("failed (%d) to create handle set\n", PTR_ERR(hset));
+ return PTR_ERR(hset);
+ }
+
+ rc = add_secure_fb_service(hset);
+ if (rc != NO_ERROR) {
+ TLOGE("failed (%d) to initialize secure_fb mock service\n", rc);
+ return rc;
+ }
+
+ return tipc_run_event_loop(hset);
+}
diff --git a/secure_fb_mock_impl/manifest.json b/secure_fb_mock_impl/manifest.json
new file mode 100644
index 0000000..b70efdd
--- /dev/null
+++ b/secure_fb_mock_impl/manifest.json
@@ -0,0 +1,5 @@
+{
+ "uuid": "405729b4-c12d-45d9-ae97-0f25aaa204e4",
+ "min_heap": 2097152,
+ "min_stack": 4096
+}
diff --git a/secure_fb_mock_impl/rules.mk b/secure_fb_mock_impl/rules.mk
new file mode 100644
index 0000000..f38f56b
--- /dev/null
+++ b/secure_fb_mock_impl/rules.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MANIFEST := $(LOCAL_DIR)/manifest.json
+
+MODULE_INCLUDES += \
+ $(LOCAL_DIR)/include \
+
+MODULE_SRCS += \
+ $(LOCAL_DIR)/main.cpp \
+
+MODULE_DEPS += \
+ trusty/user/base/lib/libc-trusty \
+ trusty/user/base/lib/libstdc++-trusty \
+ trusty/user/base/lib/tipc \
+ trusty/user/base/lib/secure_fb/srv \
+
+include make/module.mk