Android 触摸旋转

USB I2C

Posted by LXG on February 11, 2025

触摸类型对比

对比项 USB 触摸屏 I2C 触摸屏
通信方式 USB HID 协议(标准接口) I2C 总线(私有协议)
数据传输方式 通过 HID 事件发送触摸数据 通过 I2C 读取寄存器数据
驱动层 标准 HID 触摸驱动(hid-multitouch.c),由 Android InputReader 处理 定制 I2C 触摸驱动,厂商自定义协议
事件处理 通过 /dev/input/eventX 直接传输 需要从 I2C 设备读取数据
旋转支持 系统层面支持(可通过 idcInputReader 旋转) 驱动层需要额外适配
旋转方式 通过 idc 配置 swapXYinvertXinvertY 需要修改驱动代码手动调整坐标
框架支持 Android 自带 HID 触摸屏支持,可以通过 InputReader.cpp 处理 不通用,不同 I2C 触摸芯片需要不同适配
是否需要修改驱动 通常不需要,可直接调整 .idc 文件 需要修改内核驱动代码
实现难度 ⭐(简单,修改 .idc 即可) ⭐⭐⭐(复杂,需要改驱动代码)

汇顶I2C触摸旋转


			ctp {
				status = "okay";
				compatible = "allwinner,goodix";
				reg = <0x5d>;
				device_type = "ctp";
				ctp_name = "gt9xxnew_ts";
				ctp_twi_id = <0x1>;
				ctp_twi_addr = <0x5d>;
				ctp_screen_max_x = <1024>;
				ctp_screen_max_y = <600>;
				ctp_revert_x_flag = <1>;
				ctp_revert_y_flag = <1>;
				ctp_exchange_x_y_flag = <0>;
				ctp_int_port = <&pio PH 18 6 0xffffffff 0xffffffff 0>;
				ctp_wakeup = <&pio PH 19 1 0xffffffff 0xffffffff 1>;
				ctp-supply = <&reg_ldoio0>;
				ctp_power_ldo_vol = <3300>;
			};

旋转角度 ctp_revert_x_flag ctp_revert_y_flag ctp_exchange_x_y_flag
0° (默认) 0 0 0
90° 0 1 1
180° 1 1 0
270° 1 0 1

A133 显示方向旋转

首先确定0度显示方向, 然后增加可以修改的显示方向属性


PRODUCT_PROPERTY_OVERRIDES += ro.surface_flinger.primary_display_orientation=ORIENTATION_0

PRODUCT_PROPERTY_OVERRIDES += persist.sys.primary_display_orientation=0

修改framework支持动态旋转

android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp


SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
    ALOGI("SurfaceFlinger is starting");

    auto tmpPrimaryDisplayOrientation = primary_display_orientation(
            SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_0);
    switch (tmpPrimaryDisplayOrientation) {
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_90:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90;
            break;
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_180:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180;
            break;
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_270:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270;
            break;
        default:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
            break;
    }

    // lixiaogang add start
    int32_t user_rotation = property_get_int32("persist.sys.primary_display_orientation", int32_t(0));
    switch (user_rotation) {
        case 90:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90;
            break;
        case 180:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180;
            break;
        case 270:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270;
            break;
        default:
            break;
    }
    // lixiaogang add end

}

触摸随屏幕旋转

framework/native/services/inputflinger/InputReader.cpp


void TouchInputMapper::configureParameters() {

    // Initial downs on external touch devices should wake the device.
    // Normally we don't do this for internal touch screens to prevent them from waking
    // up in your pocket but you can enable it using the input device configuration.
    mParameters.wake = getDevice()->isExternal();
    getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"),
            mParameters.wake);

    // modify by lixiaogang
    // modify ro.input_flinger.primary_touch.rotation to persist.sys.primary_display_orientation
    int rotation = 0;
    if (!(!mParameters.associatedDisplayIsExternal &&
                (rotation = (int)property_get_int32("persist.sys.primary_display_orientation", -1)) != -1)) {
        if (!getDevice()->getConfiguration().tryGetProperty(String8("touch.rotation"), rotation)) {
            rotation = 0;
        }
    }
    switch (rotation) {
        case 90:
            mParameters.rotation = Parameters::ROTATION_90;
            break;
        case 180:
            mParameters.rotation = Parameters::ROTATION_180;
            break;
        case 270:
            mParameters.rotation = Parameters::ROTATION_270;
            break;
        default:
            mParameters.rotation = Parameters::ROTATION_0;
            break;
    }
}