scrcpy可以显示并控制通过 USB (或 TCP/IP) 连接的安卓设备,且不需要任何 root 权限。本程序支持 GNU/Linux, Windows 和 macOS。
app mac/windows/linux客户端
assets
config
data
gradle
prebuilt-deps
scripts
server android 服务端
android 服务端 share/scrcpy/scrcpy-server
本身是个apk,但是
app_process 原理
/data/local/tmp/oat/arm64
scrcpy-server.odex scrcpy-server.vdex
android hook, ActivityManager、SurfaceControl等相关服务
com.genymobile.scrcpy.wrappers
ActivityManager 关心点: 获取settings ContentProvider,等同adb shell settings 操作命令
ClipboardManager 关心点: 获取IClipboard服务;实现了粘贴板功能
ContentProvider 关心点:Settings.java;com.android.shell
DisplayManager 关心点:IDisplayManager获取getDisplayIds
InputManager 关心点:IInputManager获取,和注入app客户端安卓事件
PowerManager 关注点:IPowerManager
ServiceManager 关注点:android.os.ServiceManager,IWindowManager,display...
StatusBarManager 关注点:statusbar,IStatusBarService 控制
SurfaceControl 关注点:android.view.SurfaceControl,setDisplayProjection 投屏
WindowManager 关注点:window,IWindowManager,获取、设置屏幕旋转
Server.java
//对尺寸、码率、裁剪等参数进行解析,初始化Options对象
final Device device = new Device(options); //SERVICE_MANAGER,screenInfo,rotationListener 等关键点
List<CodecOption> codecOptions = CodecOption.parse(options.getCodecOptions());
//adb adb reverse 映射和adb forward 转发
boolean tunnelForward = options.isTunnelForward();
//建立连接通道
DesktopConnection.open(device, tunnelForward)
final Controller controller = new Controller(device, connection);
// 同步屏幕操作; Controller#handleEvent 输入、触摸事件处理
controllerThread = startController(controller);
//controller.DeviceMessageSender 粘贴板的数据通知
deviceMessageSenderThread = startDeviceMessageSender(controller.getSender());
//投屏参数设置和采集发送屏幕流
ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), codecOptions,
options.getEncoderName());
//MediaCodec+createDisplay+createInputSurface ,发送codecBuffer出去
screenEncoder.streamScreen(device, connection.getVideoFd());
总结。
1.push scrcpy-server 文件到/data/local/tmp 。server.c中的execute_server()方法,执行app_process指令将server端运行起来。scrcpy-server.odex scrcpy-server.vdex 那是如何产生的呢
2.连接、接收工作
3.录屏
4.编码发送