first commit

This commit is contained in:
2025-09-16 15:54:17 +08:00
commit fffe32888c
21 changed files with 1749 additions and 0 deletions

4
.dockerignore Normal file
View File

@@ -0,0 +1,4 @@
**
!/root/**
!/system/**

141
.gitignore vendored Normal file
View File

@@ -0,0 +1,141 @@
# Created by https://www.toptal.com/developers/gitignore/api/C,C++,Linux,macOS,vim
# Edit at https://www.toptal.com/developers/gitignore?templates=C,C++,Linux,macOS,vim
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
### C++ ###
# Prerequisites
# Compiled Object files
*.slo
# Precompiled Headers
# Compiled Dynamic libraries
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
# Executables
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Vim ###
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~

19
Android.mk Normal file
View File

@@ -0,0 +1,19 @@
#
# 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 is distributed on an "AS IS" BASIS,
# WITHOUT 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))

1
README.md Normal file
View File

@@ -0,0 +1 @@
[ReDroid Doc](https://github.com/remote-android/redroid-doc)

7
binder_alloc/Android.bp Normal file
View File

@@ -0,0 +1,7 @@
cc_binary {
name: "binder_alloc",
srcs: ["main.cpp"],
cflags: ["-Wall", "-Werror"],
vendor: true,
}

73
binder_alloc/main.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define BINDERFS_MAX_NAME 255
struct binderfs_device {
char name[BINDERFS_MAX_NAME + 1];
__u32 major;
__u32 minor;
};
#define BINDER_CTL_ADD _IOWR('b', 1, struct binderfs_device)
void usage(char *bin) {
printf("USAGE: %s BINDER-CONTROL-PATH DEVICE1 [DEVICE2 ...]\n", bin);
printf("EXAMPLE: binder_alloc /dev/binderfs/binder-control binder hwbinder vndbinder\n");
}
int main(int argc, char *argv[])
{
int fd, ret;
size_t len;
struct binderfs_device device{};
if (argc < 3) {
usage(basename(argv[0]));
exit(EXIT_FAILURE);
}
fd = open(argv[1], O_RDONLY | O_CLOEXEC);
if (fd < 0) {
printf("%s - Failed to open binder-control device\n", strerror(errno));
exit(EXIT_FAILURE);
}
char *dir = dirname(argv[1]); // "/dev/binderfs"
char *pathname = (char *) malloc(strlen(dir) + BINDERFS_MAX_NAME + 2); // "/dev/binderfs/binder"
for (int i = 2; i < argc; ++i) {
sprintf(pathname, "%s/%s", dir, argv[i]);
if (access(pathname, F_OK) != -1) {
printf("binder device already allocated, path: %s\n", pathname);
chmod(pathname, 0666);
continue;
}
len = strlen(argv[i]);
if (len > BINDERFS_MAX_NAME) exit(EXIT_FAILURE);
memcpy(device.name, argv[i], len);
device.name[len] = '\0';
ret = ioctl(fd, BINDER_CTL_ADD, &device);
if (ret < 0) {
printf("%s - Failed to allocate new binder device\n",
strerror(errno));
exit(EXIT_FAILURE);
}
chmod(pathname, 0666);
printf("Allocated new binder device with major %d, minor %d, and "
"name %s\n", device.major, device.minor,
device.name);
}
free(pathname);
close(fd);
exit(EXIT_SUCCESS);
}

120
gpu_config.sh Normal file
View File

@@ -0,0 +1,120 @@
#!/system/bin/sh
# args: driver
setup_vulkan() {
echo "setup vulkan for driver: $1"
case "$1" in
i915)
setprop ro.hardware.vulkan intel
;;
amdgpu)
setprop ro.hardware.vulkan radeon
;;
virtio_gpu)
setprop ro.hardware.vulkan virtio
;;
v3d|vc4)
setprop ro.hardware.vulkan broadcom
;;
msm_drm)
setprop ro.hardware.vulkan freedreno
;;
panfrost)
setprop ro.hardware.vulkan panfrost
;;
*)
echo "not supported driver: $1"
;;
esac
}
setup_render_node() {
node=$(getprop ro.boot.redroid_gpu_node)
if [ -n "$node" ]; then
echo "force render node: $node"
setprop gralloc.gbm.device "$node"
chmod 666 "$node"
# setup vulkan
driver=$(cut -d' ' -f1 "/sys/kernel/debug/dri/${node#/dev/dri/renderD}/name")
setup_vulkan "$driver"
return 0
fi
cd /sys/kernel/debug/dri || exit
for d in * ; do
if [ "$d" -ge "128" ]; then
driver="$(cut -d' ' -f1 "$d/name")"
echo "DRI node exists, driver: $driver"
setup_vulkan "$driver"
case $driver in
i915|amdgpu|nouveau|virtio_gpu|v3d|vc4|msm_drm|panfrost)
node="/dev/dri/renderD$d"
echo "use render node: $node"
setprop gralloc.gbm.device "$node"
chmod 666 "$node"
return 0
;;
esac
fi
done
echo "NO qualified render node found"
return 1
}
gpu_setup_host() {
echo "use GPU host mode"
setprop ro.hardware.egl mesa
setprop ro.hardware.gralloc gbm
setprop ro.boot.redroid_fps 30
}
gpu_setup_guest() {
echo "use GPU guest mode"
VENDOR_EGL_DIR=/vendor/lib64/egl
SYSTEM_EGL_DIR=/system/lib64
EGL_ANGLE=libEGL_angle.so
EGL_SS=libEGL_swiftshader.so
egl=
if [ -f $VENDOR_EGL_DIR/$EGL_ANGLE ] || [ -f $SYSTEM_EGL_DIR/$EGL_ANGLE ]; then
egl=angle
elif [ -f $VENDOR_EGL_DIR/$EGL_SS ] || [ -f $SYSTEM_EGL_DIR/$EGL_SS ]; then
egl=swiftshader
else
echo "ERROR no SW egl found!!!"
fi
setprop ro.hardware.egl $egl
setprop ro.hardware.gralloc redroid
setprop ro.hardware.vulkan pastel
}
gpu_setup() {
## mode=(auto, host, guest)
## node=(/dev/dri/renderDxxx)
mode=$(getprop ro.boot.redroid_gpu_mode guest)
if [ "$mode" = "host" ]; then
setup_render_node
gpu_setup_host
elif [ "$mode" = "guest" ]; then
gpu_setup_guest
elif [ "$mode" = "auto" ]; then
echo "use GPU auto mode"
if setup_render_node; then
gpu_setup_host
else
gpu_setup_guest
fi
else
echo "unknown mode: $mode"
fi
}
gpu_setup

24
gralloc/Android.bp Normal file
View File

@@ -0,0 +1,24 @@
cc_library_shared {
name: "gralloc.redroid",
vendor: true,
srcs: [
"*.cpp",
],
shared_libs: [
"liblog",
"libcutils",
],
header_libs: [
"libhardware_headers",
],
cflags: [
"-Wall", "-Werror",
"-DLOG_TAG=\"gralloc\"",
],
relative_install_path: "hw",
}

338
gralloc/framebuffer.cpp Normal file
View File

@@ -0,0 +1,338 @@
/*
* Copyright (C) 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.
*/
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <cutils/ashmem.h>
#include <cutils/atomic.h>
#include <log/log.h>
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
#ifdef __ANDROID__
#include <linux/fb.h>
#endif
#include "gralloc_priv.h"
#include "gr.h"
/*****************************************************************************/
// Set TARGET_USE_PAN_DISPLAY to true at compile time if the
// board uses FBIOPAN_DISPLAY to setup page flipping, otherwise
// default ioctl to do page-flipping is FBIOPUT_VSCREENINFO.
#ifndef USE_PAN_DISPLAY
#define USE_PAN_DISPLAY 0
#endif
// numbers of buffers for page flipping
#define NUM_BUFFERS 2
enum {
PAGE_FLIP = 0x00000001,
LOCKED = 0x00000002
};
struct fb_context_t {
framebuffer_device_t device;
};
/*****************************************************************************/
static int fb_setSwapInterval(struct framebuffer_device_t* dev,
int interval)
{
if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
return -EINVAL;
// FIXME: implement fb_setSwapInterval
return 0;
}
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
{
if (private_handle_t::validate(buffer) < 0)
return -EINVAL;
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(buffer);
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
const size_t offset = hnd->base - m->framebuffer->base;
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = offset / m->finfo.line_length;
if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
ALOGE("FBIOPUT_VSCREENINFO failed");
m->base.unlock(&m->base, buffer);
return -errno;
}
m->currentBuffer = buffer;
} else {
// If we can't do the page_flip, just copy the buffer to the front
// FIXME: use copybit HAL instead of memcpy
void* fb_vaddr;
void* buffer_vaddr;
m->base.lock(&m->base, m->framebuffer,
GRALLOC_USAGE_SW_WRITE_RARELY,
0, 0, m->info.xres, m->info.yres,
&fb_vaddr);
m->base.lock(&m->base, buffer,
GRALLOC_USAGE_SW_READ_RARELY,
0, 0, m->info.xres, m->info.yres,
&buffer_vaddr);
memcpy(fb_vaddr, buffer_vaddr, m->finfo.line_length * m->info.yres);
m->base.unlock(&m->base, buffer);
m->base.unlock(&m->base, m->framebuffer);
}
return 0;
}
/*****************************************************************************/
int mapFrameBufferLocked(struct private_module_t* module)
{
// already initialized...
if (module->framebuffer) {
return 0;
}
char const * const device_template[] = {
"/dev/graphics/fb%u",
"/dev/fb%u",
0 };
int fd = -1;
int i=0;
char name[64];
while ((fd==-1) && device_template[i]) {
snprintf(name, 64, device_template[i], 0);
fd = open(name, O_RDWR, 0);
i++;
}
if (fd < 0)
return -errno;
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
return -errno;
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
return -errno;
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
info.xoffset = 0;
info.yoffset = 0;
info.activate = FB_ACTIVATE_NOW;
/*
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
*/
info.yres_virtual = info.yres * NUM_BUFFERS;
uint32_t flags = PAGE_FLIP;
#if USE_PAN_DISPLAY
if (ioctl(fd, FBIOPAN_DISPLAY, &info) == -1) {
ALOGW("FBIOPAN_DISPLAY failed, page flipping not supported");
#else
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
ALOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
#endif
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
}
if (info.yres_virtual < info.yres * 2) {
// we need at least 2 for page-flipping
info.yres_virtual = info.yres;
flags &= ~PAGE_FLIP;
ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
info.yres_virtual, info.yres*2);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
return -errno;
uint64_t refreshQuotient =
(
uint64_t( info.upper_margin + info.lower_margin + info.yres )
* ( info.left_margin + info.right_margin + info.xres )
* info.pixclock
);
/* Beware, info.pixclock might be 0 under emulation, so avoid a
* division-by-0 here (SIGFPE on ARM) */
int refreshRate = refreshQuotient > 0 ? (int)(1000000000000000LLU / refreshQuotient) : 0;
if (refreshRate == 0) {
// bleagh, bad info from the driver
refreshRate = 60*1000; // 60 Hz
}
if (int(info.width) <= 0 || int(info.height) <= 0) {
// the driver doesn't return that information
// default to 160 dpi
info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
}
float xdpi = (info.xres * 25.4f) / info.width;
float ydpi = (info.yres * 25.4f) / info.height;
float fps = refreshRate / 1000.0f;
ALOGI( "using (fd=%d)\n"
"id = %s\n"
"xres = %d px\n"
"yres = %d px\n"
"xres_virtual = %d px\n"
"yres_virtual = %d px\n"
"bpp = %d\n"
"r = %2u:%u\n"
"g = %2u:%u\n"
"b = %2u:%u\n",
fd,
finfo.id,
info.xres,
info.yres,
info.xres_virtual,
info.yres_virtual,
info.bits_per_pixel,
info.red.offset, info.red.length,
info.green.offset, info.green.length,
info.blue.offset, info.blue.length
);
ALOGI( "width = %d mm (%f dpi)\n"
"height = %d mm (%f dpi)\n"
"refresh rate = %.2f Hz\n",
info.width, xdpi,
info.height, ydpi,
fps
);
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
return -errno;
if (finfo.smem_len <= 0)
return -errno;
module->flags = flags;
module->info = info;
module->finfo = finfo;
module->xdpi = xdpi;
module->ydpi = ydpi;
module->fps = fps;
/*
* map the framebuffer
*/
size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual);
module->framebuffer = new private_handle_t(dup(fd), fbSize, 0);
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (vaddr == MAP_FAILED) {
ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
return -errno;
}
module->framebuffer->base = intptr_t(vaddr);
memset(vaddr, 0, fbSize);
return 0;
}
static int mapFrameBuffer(struct private_module_t* module)
{
pthread_mutex_lock(&module->lock);
int err = mapFrameBufferLocked(module);
pthread_mutex_unlock(&module->lock);
return err;
}
/*****************************************************************************/
static int fb_close(struct hw_device_t *dev)
{
fb_context_t* ctx = (fb_context_t*)dev;
if (ctx) {
free(ctx);
}
return 0;
}
int fb_device_open(hw_module_t const* module, const char* name,
hw_device_t** device)
{
int status = -EINVAL;
if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
/* initialize our state here */
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
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 = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post = fb_post;
dev->device.setUpdateRect = 0;
private_module_t* m = (private_module_t*)module;
status = mapFrameBuffer(m);
if (status >= 0) {
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
int format = (m->info.bits_per_pixel == 32)
? (m->info.red.offset ? HAL_PIXEL_FORMAT_BGRA_8888 : HAL_PIXEL_FORMAT_RGBX_8888)
: HAL_PIXEL_FORMAT_RGB_565;
const_cast<uint32_t&>(dev->device.flags) = 0;
const_cast<uint32_t&>(dev->device.width) = m->info.xres;
const_cast<uint32_t&>(dev->device.height) = m->info.yres;
const_cast<int&>(dev->device.stride) = stride;
const_cast<int&>(dev->device.format) = format;
const_cast<float&>(dev->device.xdpi) = m->xdpi;
const_cast<float&>(dev->device.ydpi) = m->ydpi;
const_cast<float&>(dev->device.fps) = m->fps;
const_cast<int&>(dev->device.minSwapInterval) = 1;
const_cast<int&>(dev->device.maxSwapInterval) = 1;
*device = &dev->device.common;
}
}
return status;
}

63
gralloc/gr.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 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.
*/
#ifndef GR_H_
#define GR_H_
#include <stdint.h>
#include <sys/user.h>
#include <limits.h>
#include <sys/cdefs.h>
#include <hardware/gralloc.h>
#include <pthread.h>
#include <errno.h>
#include <cutils/native_handle.h>
/*****************************************************************************/
struct private_module_t;
struct private_handle_t;
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
inline size_t roundUpToPageSize(size_t x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}
int mapFrameBufferLocked(struct private_module_t* module);
int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
int mapBuffer(gralloc_module_t const* module, private_handle_t* hnd);
/*****************************************************************************/
class Locker {
pthread_mutex_t mutex;
public:
class Autolock {
Locker& locker;
public:
inline explicit Autolock(Locker& locker) : locker(locker) { locker.lock(); }
inline ~Autolock() { locker.unlock(); }
};
inline Locker() { pthread_mutex_init(&mutex, 0); }
inline ~Locker() { pthread_mutex_destroy(&mutex); }
inline void lock() { pthread_mutex_lock(&mutex); }
inline void unlock() { pthread_mutex_unlock(&mutex); }
};
#endif /* GR_H_ */

248
gralloc/gralloc.cpp Normal file
View File

@@ -0,0 +1,248 @@
/*
* Copyright (C) 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.
*/
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cutils/ashmem.h>
#include <cutils/atomic.h>
#include <log/log.h>
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
#include "gralloc_priv.h"
#include "gr.h"
/*****************************************************************************/
struct gralloc_context_t {
alloc_device_t device;
/* our private data here */
};
static int gralloc_alloc_buffer(alloc_device_t* dev,
size_t size, int usage, buffer_handle_t* pHandle);
/*****************************************************************************/
int fb_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
static int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
extern int gralloc_lock(gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int l, int t, int w, int h,
void** vaddr);
extern int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle);
extern int gralloc_register_buffer(gralloc_module_t const* module,
buffer_handle_t handle);
extern int gralloc_unregister_buffer(gralloc_module_t const* module,
buffer_handle_t handle);
/*****************************************************************************/
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,
.version_major = 1,
.version_minor = 0,
.id = GRALLOC_HARDWARE_MODULE_ID,
.name = "Graphics Memory Allocator Module",
.author = "The Android Open Source Project",
.methods = &gralloc_module_methods
},
.registerBuffer = gralloc_register_buffer,
.unregisterBuffer = gralloc_unregister_buffer,
.lock = gralloc_lock,
.unlock = gralloc_unlock,
},
.framebuffer = 0,
.flags = 0,
.numBuffers = 0,
.bufferMask = 0,
.lock = PTHREAD_MUTEX_INITIALIZER,
.currentBuffer = 0,
};
/*****************************************************************************/
static int gralloc_alloc_buffer(alloc_device_t* dev,
size_t size, int /*usage*/, buffer_handle_t* pHandle)
{
int err = 0;
int fd = -1;
size = roundUpToPageSize(size);
fd = ashmem_create_region("gralloc-buffer", size);
if (fd < 0) {
ALOGE("couldn't create ashmem (%s)", strerror(-errno));
err = -errno;
}
if (err == 0) {
private_handle_t* hnd = new private_handle_t(fd, size, 0);
gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
err = mapBuffer(module, hnd);
if (err == 0) {
*pHandle = hnd;
}
}
ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
return err;
}
/*****************************************************************************/
inline size_t align(size_t value, size_t alignment)
{
return ((value + alignment - 1) / alignment) * alignment;
}
static int gralloc_alloc(alloc_device_t* dev,
int width, int height, int format, int usage,
buffer_handle_t* pHandle, int* pStride)
{
if (!pHandle || !pStride)
return -EINVAL;
int bytesPerPixel = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_FP16:
bytesPerPixel = 8;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
bytesPerPixel = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
bytesPerPixel = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_YV12:
bytesPerPixel = 2;
break;
default:
return -EINVAL;
}
const size_t tileWidth = 2;
const size_t tileHeight = 2;
size_t stride = align(width, tileWidth);
size_t size = align(height, tileHeight) * stride * bytesPerPixel + 4;
int err = gralloc_alloc_buffer(dev, size, usage, pHandle);
if (err < 0) {
return err;
}
*pStride = stride;
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);
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
// free this buffer
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
const size_t bufferSize = m->finfo.line_length * m->info.yres;
int index = (hnd->base - m->framebuffer->base) / bufferSize;
m->bufferMask &= ~(1<<index);
} else {
gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
terminateBuffer(module, const_cast<private_handle_t*>(hnd));
}
close(hnd->fd);
delete hnd;
return 0;
}
/*****************************************************************************/
static int gralloc_close(struct hw_device_t *dev)
{
gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
if (ctx) {
/* TODO: keep a list of all buffer_handle_t created, and free them
* all here.
*/
free(ctx);
}
return 0;
}
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)) {
gralloc_context_t *dev;
dev = (gralloc_context_t*)malloc(sizeof(*dev));
/* 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 {
status = fb_device_open(module, name, device);
}
return status;
}

114
gralloc/gralloc_priv.h Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 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.
*/
#ifndef GRALLOC_PRIV_H_
#define GRALLOC_PRIV_H_
#include <stdint.h>
#include <limits.h>
#include <sys/cdefs.h>
#include <hardware/gralloc.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <cutils/native_handle.h>
#include <linux/fb.h>
/*****************************************************************************/
struct private_module_t;
struct private_handle_t;
struct private_module_t {
gralloc_module_t base;
private_handle_t* framebuffer;
uint32_t flags;
uint32_t numBuffers;
uint32_t bufferMask;
pthread_mutex_t lock;
buffer_handle_t currentBuffer;
int pmem_master;
void* pmem_master_base;
struct fb_var_screeninfo info;
struct fb_fix_screeninfo finfo;
float xdpi;
float ydpi;
float fps;
};
/*****************************************************************************/
#ifdef __cplusplus
struct private_handle_t : public native_handle {
#else
struct private_handle_t {
struct native_handle nativeHandle;
#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001
};
// file-descriptors
int fd;
// ints
int magic;
int flags;
int size;
int offset;
// FIXME: the attributes below should be out-of-line
uint64_t base __attribute__((aligned(8)));
int pid;
#ifdef __cplusplus
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 flags) :
fd(fd), magic(sMagic), flags(flags), size(size), offset(0),
base(0), pid(getpid())
{
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 || h->version != sizeof(native_handle) ||
h->numInts != sNumInts() || h->numFds != sNumFds ||
hnd->magic != sMagic)
{
ALOGE("invalid gralloc handle (at %p)", h);
return -EINVAL;
}
return 0;
}
#endif
};
#endif /* GRALLOC_PRIV_H_ */

187
gralloc/mapper.cpp Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 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.
*/
#include <errno.h>
#include <limits.h>
#include <pthread.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cutils/atomic.h>
#include <log/log.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include "gralloc_priv.h"
/*****************************************************************************/
static int gralloc_map(gralloc_module_t const* /*module*/,
buffer_handle_t handle,
void** vaddr)
{
private_handle_t* hnd = (private_handle_t*)handle;
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
size_t size = hnd->size;
void* mappedAddress = mmap(0, size,
PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);
if (mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap %s", strerror(errno));
return -errno;
}
hnd->base = uintptr_t(mappedAddress) + hnd->offset;
//ALOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
// hnd->fd, hnd->offset, hnd->size, mappedAddress);
}
*vaddr = (void*)hnd->base;
return 0;
}
static int gralloc_unmap(gralloc_module_t const* /*module*/,
buffer_handle_t handle)
{
private_handle_t* hnd = (private_handle_t*)handle;
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
void* base = (void*)hnd->base;
size_t size = hnd->size;
//ALOGD("unmapping from %p, size=%d", base, size);
if (munmap(base, size) < 0) {
ALOGE("Could not unmap %s", strerror(errno));
}
}
hnd->base = 0;
return 0;
}
/*****************************************************************************/
int gralloc_register_buffer(gralloc_module_t const* module,
buffer_handle_t handle)
{
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
// *** WARNING WARNING WARNING ***
//
// If a buffer handle is passed from the process that allocated it to a
// different process, and then back to the allocator process, we will
// create a second mapping of the buffer. If the process reads and writes
// through both mappings, normal memory ordering guarantees may be
// violated, depending on the processor cache implementation*.
//
// If you are deriving a new gralloc implementation from this code, don't
// do this. A "real" gralloc should provide a single reference-counted
// mapping for each buffer in a process.
//
// In the current system, there is one case that needs a buffer to be
// registered in the same process that allocated it. The SurfaceFlinger
// process acts as the IGraphicBufferAlloc Binder provider, so all gralloc
// allocations happen in its process. After returning the buffer handle to
// the IGraphicBufferAlloc client, SurfaceFlinger free's its handle to the
// buffer (unmapping it from the SurfaceFlinger process). If
// SurfaceFlinger later acts as the producer end of the buffer queue the
// buffer belongs to, it will get a new handle to the buffer in response
// to IGraphicBufferProducer::requestBuffer(). Like any buffer handle
// received through Binder, the SurfaceFlinger process will register it.
// Since it already freed its original handle, it will only end up with
// one mapping to the buffer and there will be no problem.
//
// Currently SurfaceFlinger only acts as a buffer producer for a remote
// consumer when taking screenshots and when using virtual displays.
//
// Eventually, each application should be allowed to make its own gralloc
// allocations, solving the problem. Also, this ashmem-based gralloc
// should go away, replaced with a real ion-based gralloc.
//
// * Specifically, associative virtually-indexed caches are likely to have
// problems. Most modern L1 caches fit that description.
private_handle_t* hnd = (private_handle_t*)handle;
ALOGD_IF(hnd->pid == getpid(),
"Registering a buffer in the process that created it. "
"This may cause memory ordering problems.");
void *vaddr;
return gralloc_map(module, handle, &vaddr);
}
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;
if (hnd->base)
gralloc_unmap(module, handle);
return 0;
}
int mapBuffer(gralloc_module_t const* module,
private_handle_t* hnd)
{
void* vaddr;
return gralloc_map(module, hnd, &vaddr);
}
int terminateBuffer(gralloc_module_t const* module,
private_handle_t* hnd)
{
if (hnd->base) {
// this buffer was mapped, unmap it now
gralloc_unmap(module, hnd);
}
return 0;
}
int gralloc_lock(gralloc_module_t const* /*module*/,
buffer_handle_t handle, int /*usage*/,
int /*l*/, int /*t*/, int /*w*/, int /*h*/,
void** vaddr)
{
// this is called when a buffer is being locked for software
// access. in thin implementation we have nothing to do since
// not synchronization with the h/w is needed.
// typically this is used to wait for the h/w to finish with
// this buffer if relevant. the data cache may need to be
// flushed or invalidated depending on the usage bits and the
// hardware.
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
private_handle_t* hnd = (private_handle_t*)handle;
*vaddr = (void*)hnd->base;
return 0;
}
int gralloc_unlock(gralloc_module_t const* /*module*/,
buffer_handle_t handle)
{
// we're done with a software buffer. nothing to do in this
// implementation. typically this is used to flush the data cache.
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
return 0;
}

8
ipconfigstore/Android.bp Normal file
View File

@@ -0,0 +1,8 @@
cc_binary {
name: "ipconfigstore",
srcs: ["*.cc"],
cflags: ["-Wall", "-Werror"],
shared_libs: ["libbase"],
vendor: true,
}

65
ipconfigstore/data.cc Normal file
View File

@@ -0,0 +1,65 @@
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "data.h"
uint16_t convertBigEndianUInt16(uint16_t value)
{
union { uint16_t value; unsigned char data[2]; } aux = { 0x4142 };
if (aux.data[0] == 0x41)
{
return value;
}
aux.data[0] = (value >> 8) & 0xff;
aux.data[1] = value & 0xff;
return aux.value;
}
uint32_t convertBigEndianUInt32(uint32_t value)
{
union { uint32_t value; unsigned char data[4]; } aux = { 0x41424344 };
if (aux.data[0] == 0x41)
{
return value;
}
aux.data[0] = (value >> 24) & 0xff;
aux.data[1] = (value >> 16) & 0xff;
aux.data[2] = (value >> 8) & 0xff;
aux.data[3] = value & 0xff;
return aux.value;
}
bool writePackedString(const std::string& str, FILE *stream)
{
const char *string = str.c_str();
size_t stringLength = strlen(string);
if (!writePackedUInt16(stringLength, stream))
{
return false;
}
return fwrite(string, stringLength, 1, stream) == 1;
}
bool writePackedUInt16(uint16_t value, FILE *stream)
{
uint16_t buffer = convertBigEndianUInt16(value);
return fwrite(&buffer, sizeof buffer, 1, stream) == 1;
}
bool writePackedUInt32(uint32_t value, FILE *stream)
{
uint32_t buffer = convertBigEndianUInt32(value);
return fwrite(&buffer, sizeof buffer, 1, stream) == 1;
}

13
ipconfigstore/data.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <cstdint>
#include <string>
#include <stdio.h>
uint16_t convertBigEndianUInt16(uint16_t value);
uint32_t convertBigEndianUInt32(uint32_t value);
bool writePackedString(const std::string& str, FILE *stream);
bool writePackedUInt16(uint16_t value, FILE *stream);
bool writePackedUInt32(uint32_t value, FILE *stream);

165
ipconfigstore/main.cc Normal file
View File

@@ -0,0 +1,165 @@
#include <sys/types.h>
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <net/route.h>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <set>
#include <android-base/properties.h>
#include "data.h"
using namespace android::base;
struct ipconfig {
uint32_t mask;
char ipv4[16];
char gateway[16];
};
static int get_gateway(char *dev, char *ret) {
FILE *fp;
char buf[256]; // 128 is enough for linux
char iface[16];
unsigned long dest_addr, gate_addr;
fp = fopen("/proc/net/route", "r");
if (fp == NULL) return -1;
/* Skip title line */
fgets(buf, sizeof(buf), fp);
while (fgets(buf, sizeof(buf), fp)) {
if (sscanf(buf, "%s\t%lX\t%lX", iface, &dest_addr, &gate_addr) != 3 || dest_addr != 0 || strcmp(dev, iface)) continue;
inet_ntop(AF_INET, &gate_addr, ret, INET_ADDRSTRLEN);
break;
}
fclose(fp);
return 0;
}
static int bitcount(uint32_t n)
{
int count=0;
while (n) {
count++;
n &= (n - 1);
}
return count;
}
static int get_conf(struct ipconfig *conf) {
struct ifaddrs *ifAddrStruct;
void *tmpAddrPtr=NULL;
getifaddrs(&ifAddrStruct);
while (ifAddrStruct != NULL) {
if (ifAddrStruct->ifa_addr->sa_family==AF_INET && !strcmp("eth0", ifAddrStruct->ifa_name)) {
tmpAddrPtr=&((struct sockaddr_in *)ifAddrStruct->ifa_addr)->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, conf->ipv4, INET_ADDRSTRLEN);
conf->mask = bitcount(((struct sockaddr_in *)ifAddrStruct->ifa_netmask)->sin_addr.s_addr);
break;
}
ifAddrStruct=ifAddrStruct->ifa_next;
}
freeifaddrs(ifAddrStruct);
get_gateway((char *) "eth0", conf->gateway);
return 0;
}
static void write_dns(FILE *fp) {
std::set<std::string> dnsList;
auto ndns = GetIntProperty("ro.boot.redroid_net_ndns", 0);
for (int i = 1; i <= ndns; ++i) {
dnsList.insert(GetProperty("ro.boot.redroid_net_dns" + std::to_string(i), ""));
}
if (dnsList.empty()) dnsList.insert("8.8.8.8");
for (auto& dns: dnsList) {
writePackedString("dns", fp);
writePackedString(dns.c_str(), fp);
}
}
static void write_proxy(FILE *fp) {
// static | pac | none | unassigned
std::string proxy_type = GetProperty("ro.boot.redroid_net_proxy_type", "");
if ("static" == proxy_type) {
writePackedString("proxySettings", fp);
writePackedString("STATIC", fp);
writePackedString("proxyHost", fp);
writePackedString(GetProperty("ro.boot.redroid_net_proxy_host", "").c_str(), fp);
writePackedString("proxyPort", fp);
writePackedUInt32(GetIntProperty("ro.boot.redroid_net_proxy_port", 3128), fp);
writePackedString("exclusionList", fp);
writePackedString(GetProperty("ro.boot.redroid_net_proxy_exclude_list", "").c_str(), fp);
} else if ("pac" == proxy_type) {
writePackedString("proxySettings", fp);
writePackedString("PAC", fp);
writePackedString("proxyPac", fp);
writePackedString(GetProperty("ro.boot.redroid_net_proxy_pac", "").c_str(), fp);
} else if ("none" == proxy_type) {
writePackedString("proxySettings", fp);
writePackedString("NONE", fp);
} else {
// ignored
}
}
static int write_conf(struct ipconfig *conf, uint32_t v) {
FILE *fp = fopen("/data/misc/ethernet/ipconfig.txt", "w+");
writePackedUInt32(v, fp); // version
writePackedString("ipAssignment", fp);
writePackedString("STATIC", fp);
writePackedString("linkAddress", fp);
writePackedString(conf->ipv4, fp);
writePackedUInt32(conf->mask, fp);
writePackedString("gateway", fp);
writePackedUInt32(1, fp); // Default route (dest).
writePackedString("0.0.0.0", fp);
writePackedUInt32(0, fp);
writePackedUInt32(1, fp); // Have a gateway.
writePackedString(conf->gateway, fp);
write_dns(fp);
write_proxy(fp);
writePackedString("id", fp);
if (v == 2) writePackedUInt32(0, fp);
else writePackedString("eth0", fp);
writePackedString("eos", fp);
fclose(fp);
return 0;
}
int main(int argc, char **argv) {
(void)argc;
(void)argv;
uint32_t v = 3;
// use V2 for Android 8.1
if (GetIntProperty("ro.build.version.sdk", 0) <= 27) v = 2;
struct ipconfig conf;
get_conf(&conf);
printf("ipconfig: ipv4: %s, mask: %i, gateway: %s", conf.ipv4, conf.mask, conf.gateway);
write_conf(&conf, v);
return 0;
}

5
post-fs-data.redroid.sh Normal file
View File

@@ -0,0 +1,5 @@
#!/system/bin/sh
## enable `memfd` if `ashmem` missing
## memfd is disabled in post-fs-data (init.rc)
[ -c /dev/ashmem ] || setprop sys.use_memfd 1

89
redroid.common.rc Normal file
View File

@@ -0,0 +1,89 @@
on early-init
mount debugfs debugfs /sys/kernel/debug mode=755
# ueventd fix
chmod 0666 /dev/null
chmod 0666 /dev/zero
chmod 0666 /dev/full
chmod 0666 /dev/ptmx
chmod 0666 /dev/pts/ptmx
chmod 0666 /dev/tty
chmod 0666 /dev/random
chmod 0666 /dev/urandom
chmod 0666 /dev/ashmem
chmod 0666 /dev/ion
chmod 0444 /dev/dma_heap/system
chown system system /dev/dma_heap/system
# used to place domain sockets
mkdir /ipc 0777
exec -- /bin/rm -rf /dev/input
# inputflinger require this dir
mkdir /dev/input
# disable codec2 by default, DMA Heap required
setprop debug.stagefright.ccodec 0
# disable some verbose logs
setprop log.tag.libprocessgroup F
# assume GLES 3.2 supported
setprop ro.opengles.version 196610
# setup overlay data partition
on early-init && property:ro.boot.use_redroid_overlayfs=1
trigger use_redroid_overlayfs
on use_redroid_overlayfs
mkdir /data-diff/upper
rmdir /data-diff/work
mkdir /data-diff/work
mount overlay overlay /data lowerdir=/data-base,upperdir=/data-diff/upper,workdir=/data-diff/work
on early-init && property:ro.boot.redroid_dpi=*
setprop ro.sf.lcd_density ${ro.boot.redroid_dpi}
on property:ro.zygote=zygote64_32
write /proc/sys/kernel/pid_max 65535
# use memfd (ashmem removed in 5.18), memfd is disabled in post-fs-data (init.rc)
on post-fs-data && property:ro.boot.use_memfd=*
setprop sys.use_memfd ${ro.boot.use_memfd}
on init
# lxcfs better
write /data/.empty 0
mount none /data/.empty /proc/vmallocinfo bind
# fix suspend host system?
mount none /data/.empty /sys/power/state bind
setprop debug.renderengine.backend gles
# set dpi if missing
setprop ro.sf.lcd_density 320
on post-fs-data
# fix for static IP, must after post-fs-data and before netd
# rm apex config (use legacy path)
rm /data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt
exec - system system -- /vendor/bin/ipconfigstore
# no need to mount, and encryption not supported yet
trigger nonencrypted
exec -- /vendor/bin/post-fs-data.redroid.sh
on early-boot
# before HAL / SurfaceFlinger
exec -- /vendor/bin/gpu_config.sh

47
redroid.legacy.rc Normal file
View File

@@ -0,0 +1,47 @@
# convert legacy props
# overlay data
on early-init && property:ro.kernel.redroid.overlay=1
trigger use_redroid_overlayfs
# display
on early-init && property:ro.kernel.redroid.width=*
setprop ro.boot.redroid_width ${ro.kernel.redroid.width}
on early-init && property:ro.kernel.redroid.height=*
setprop ro.boot.redroid_height ${ro.kernel.redroid.height}
on early-init && property:ro.kernel.redroid.fps=*
setprop ro.boot.redroid_fps ${ro.kernel.redroid.fps}
# DNS
on early-init && property:ro.kernel.net.eth0.dns1=*
setprop ro.boot.redroid_net_ndns 1
setprop ro.boot.redroid_net_dns1 ${ro.kernel.net.eth0.dns1}
# network proxy
on early-init && property:ro.kernel.net.eth0.proxy.type=*
setprop ro.boot.redroid_net_proxy_type ${ro.kernel.net.eth0.proxy.type}
on early-init && property:ro.kernel.net.eth0.proxy.host=*
setprop ro.boot.redroid_net_proxy_host ${ro.kernel.net.eth0.proxy.host}
on early-init && property:ro.kernel.net.eth0.proxy.port=*
setprop ro.boot.redroid_net_proxy_port ${ro.kernel.net.eth0.proxy.port}
on early-init && property:ro.kernel.net.eth0.proxy.exclusionList=*
setprop ro.boot.redroid_net_proxy_exclude ${ro.kernel.net.eth0.proxy.exclusionList}
on early-init && property:ro.kernel.net.eth0.proxy.pac=*
setprop ro.boot.redroid_net_proxy_pac ${ro.kernel.net.eth0.proxy.pac}
# GPU
on early-init && property:ro.kernel.redroid.gpu.mode=*
setprop ro.boot.redroid_gpu_mode ${ro.kernel.redroid.gpu.mode}
on early-init && property:ro.kernel.redroid.gpu.node=*
setprop ro.boot.redroid_gpu_node ${ro.kernel.redroid.gpu.node}

18
vendor.mk Normal file
View File

@@ -0,0 +1,18 @@
# skip androidx.window.extensions check
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true
PRODUCT_PACKAGES += \
binder_alloc \
gralloc.redroid \
ipconfigstore \
PRODUCT_COPY_FILES += \
vendor/redroid/gpu_config.sh:$(TARGET_COPY_OUT_VENDOR)/bin/gpu_config.sh \
vendor/redroid/post-fs-data.redroid.sh:$(TARGET_COPY_OUT_VENDOR)/bin/post-fs-data.redroid.sh \
vendor/redroid/redroid.common.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/redroid.common.rc \
vendor/redroid/redroid.legacy.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/redroid.legacy.rc \
PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.touchscreen.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.touchscreen.xml \