first commit
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
**
|
||||||
|
|
||||||
|
!/root/**
|
||||||
|
!/system/**
|
||||||
141
.gitignore
vendored
Normal file
141
.gitignore
vendored
Normal 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
19
Android.mk
Normal 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
1
README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[ReDroid Doc](https://github.com/remote-android/redroid-doc)
|
||||||
7
binder_alloc/Android.bp
Normal file
7
binder_alloc/Android.bp
Normal 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
73
binder_alloc/main.cpp
Normal 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
120
gpu_config.sh
Normal 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
24
gralloc/Android.bp
Normal 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
338
gralloc/framebuffer.cpp
Normal 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
63
gralloc/gr.h
Normal 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
248
gralloc/gralloc.cpp
Normal 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
114
gralloc/gralloc_priv.h
Normal 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
187
gralloc/mapper.cpp
Normal 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
8
ipconfigstore/Android.bp
Normal 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
65
ipconfigstore/data.cc
Normal 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
13
ipconfigstore/data.h
Normal 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
165
ipconfigstore/main.cc
Normal 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
5
post-fs-data.redroid.sh
Normal 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
89
redroid.common.rc
Normal 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
47
redroid.legacy.rc
Normal 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
18
vendor.mk
Normal 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 \
|
||||||
Reference in New Issue
Block a user