编译Android系统源码中screencap
之前需要在安卓系统上做采集屏幕,第一时间查到的都是使用java
的方案,就想能不能使用纯cpp
就可以实现呢?刚好安卓源码中就有一个自带的截图工具screencap
,是纯cpp
源码实现的。但是要编译出来,还是有些额外的准备工作的。
下载源码
理论上可以把android的所有代码都下载下来,但是没必要。下面只会下载需要用到的部分,使用android10分支。可以从android.googlesource.com下载各模块源码的压缩包。
https://android.googlesource.com/platform/system/core/+archive/refs/heads/android10-release.tar.gz
https://android.googlesource.com/platform/frameworks/native/+archive/refs/heads/android10-release.tar.gz
https://android.googlesource.com/platform/external/skia/+archive/refs/heads/android10-release.tar.gz
https://android.googlesource.com/platform/prebuilts/vndk/v30/+archive/refs/heads/main.tar.gz
然后将对应模块的源码解压到对应的目录。
tree /root/android10/ -L 3
/root/android10/
├── platform
│ ├── external
│ │ └── skia
│ ├── frameworks
│ │ └── native
│ ├── prebuilts
│ │ └── vndk
│ └── system
│ └── core
最后,还需要screencap
的源码,只是单独一个文件。
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/android10-release/cmds/screencap/screencap.cpp
配置项目
创建一个CMake项目。
cmake_minimum_required(VERSION 3.15)
set(CMAKE_CXX_STANDARD 17)
# 获取当前文件夹名
string(REGEX REPLACE ".*/(.*)" "\\1" CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR})
project(${CURRENT_FOLDER})
# ##############################################################################
set(subject ${PROJECT_NAME})
include_directories(${subject} include/
${ANDROID_PLATFORM_DIR}/system/core/include
${ANDROID_PLATFORM_DIR}/system/core/base/include
${ANDROID_PLATFORM_DIR}/frameworks/native/include
${ANDROID_PLATFORM_DIR}/frameworks/native/libs/math/include
${ANDROID_PLATFORM_DIR}/frameworks/native/libs/nativebase/include
${ANDROID_PLATFORM_DIR}/frameworks/native/libs/nativewindow/include
${ANDROID_PLATFORM_DIR}/external/skia/include/core
${ANDROID_PLATFORM_DIR}/external/skia/include/config
${ANDROID_PLATFORM_DIR}/external/skia/include/config/android
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/system/libhidl/base/include
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/hardware/libhardware/include
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/system/libhidl/transport/token/1.0/utils/include
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/graphics/common/1.0/android.hardware.graphics.common@1.0_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/graphics/common/1.1/android.hardware.graphics.common@1.1_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/graphics/common/1.2/android.hardware.graphics.common@1.2_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/graphics/bufferqueue/1.0/android.hardware.graphics.bufferqueue@1.0_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/graphics/bufferqueue/2.0/android.hardware.graphics.bufferqueue@2.0_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/system/libhidl/transport/base/1.0/android.hidl.base@1.0_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/system/libhidl/transport/manager/1.0/android.hidl.manager@1.0_genc++_headers/gen
${ANDROID_PLATFORM_DIR}/prebuilts/vndk/v30/${PREBUILT}/include/generated-headers/hardware/interfaces/media/1.0/android.hardware.media@1.0_genc++_headers/gen
)
link_directories(${subject} lib/${ANDROID_ABI})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/bin/${platform}/${ANDROID_ABI}/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/bin/${platform}/${ANDROID_ABI}/release)
# 查找目录下所有源文件并保存到变量
# aux_source_directory(src SRCS)
# 搜索源码文件保存到变量
FILE(GLOB SRCS src/*.h src/*.cpp)
add_executable(${subject} ${SRCS})
target_compile_options(${subject} PRIVATE
-fno-rtti
-Wno-inconsistent-missing-override
)
target_link_libraries(${subject} log android gui binder utils ui hwui hwbinder)
set_property(TARGET ${subject} PROPERTY DEBUG_POSTFIX _${ANDROID_ABI}_d)
set_property(TARGET ${subject} PROPERTY RELEASE_POSTFIX _${ANDROID_ABI}_r)
# ##############################################################################
项目需要链接gui
、binder
、utils
、ui
、hwui
、hwbinder
这几个库,直接从安卓机上拷贝到lib
目录就好。
使用一个脚本,一键编译。
export ANDROID_NDK_ROOT=/root/android-ndk-r27
export ANDROID_PLATFORM_DIR=/root/android10/platform
export PREBUILT=arm64
export platform=android-29
export abi=arm64-v8a
export BUILDPATH=$(pwd)/build
export INSTALLPATH=$(pwd)/bin
rm -r $BUILDPATH
rm -r $INSTALLPATH
export buildparams="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_ROOT/prebuilt/linux-x86_64/bin/make"
cmake -G "Unix Makefiles" -S . -B $BUILDPATH \
-DANDROID_NDK=$ANDROID_NDK_ROOT $buildparams \
-DCMAKE_BUILD_TYPE=release -DANDROID_ABI=$abi -DANDROID_PLATFORM=$platform \
-DANDROID_PLATFORM_DIR=$ANDROID_PLATFORM_DIR -DPREBUILT=$PREBUILT
cmake --build $BUILDPATH --clean-first --config release --target all -- -j8
整个项目的布局。
tree /root/AnalysisAVP/example/android/capture/screencap/ -L 2
/root/AnalysisAVP/example/android/capture/screencap/
├── build_android.sh
├── CMakeLists.txt
├── lib
│ ├── arm64-v8a
│ └── armeabi-v7a
└── src
└── screencap.cpp
编译运行
root@gongluck:~/AnalysisAVP/example/android/capture/screencap# ./build_android.sh
-- The C compiler identification is Clang 18.0.1
-- The CXX compiler identification is Clang 18.0.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /root/android-ndk-r27/toolchains/llvm/prebuilt/linux-x86_64/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /root/android-ndk-r27/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/AnalysisAVP/example/android/capture/screencap/build
[ 50%] Building CXX object CMakeFiles/screencap.dir/src/screencap.cpp.o
[100%] Linking CXX executable ../bin/arm64-v8a/release/screencap_arm64-v8a_r
[100%] Built target screencap
root@gongluck:~/AnalysisAVP/example/android/capture/screencap# adb push bin/arm64-v8a/release/screencap_arm64-v8a_r /data/local/tmp/
bin/arm64-v8a/release/screencap_arm64-v8a_r: 1 file pushed. 10.4 MB/s (391064 bytes in 0.036s)
root@gongluck:~/AnalysisAVP/example/android/capture/screencap# adb shell "/data/local/tmp/screencap_arm64-v8a_r -p > /data/local/tmp/save.png"
root@gongluck:~/AnalysisAVP/example/android/capture/screencap# adb shell "file /data/local/tmp/save.png"
/data/local/tmp/save.png: PNG image data, 720 x 1280, 8-bit/color RGBA, non-interlaced
完整代码
https://github.com/gongluck/AnalysisAVP/tree/master/example/android/capture/screencap
Last modified on 2024-09-08