Android 副屏相关修改
1、副屏横竖屏调整
对设备显示及物理上方向进行替换,这个操作在一开始加载的时候就会进行,只会进行一次。修改如下
frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
... ...
// For demonstration purposes, allow rotation of the external display.
// In the future we might allow the user to configure this directly.
// 这部分就是旋转的操作
- if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ String rotation = SystemProperties.get("persist.demo.hdmirotation");
+ if ("ROTATION_270".equals(rotation)) {
mInfo.rotation = Surface.ROTATION_270;
+ } else {
+ mInfo.rotation = Surface.ROTATION_90;
}
// For demonstration purposes, allow rotation of the external display
... ...
}
frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
public void updateLocked(List<DisplayDevice> devices) {
... ...
mPrimaryDisplayDeviceInfo = deviceInfo;
mInfo = null;
// 替换副屏的信息
+ if(mDisplayId != Display.DEFAULT_DISPLAY){
+ mBaseDisplayInfo.appWidth = deviceInfo.height;
+ mBaseDisplayInfo.appHeight = deviceInfo.width;
+ mBaseDisplayInfo.logicalWidth = deviceInfo.height;
+ mBaseDisplayInfo.logicalHeight = deviceInfo.width;
+ }
}
public void configureDisplayInTransactionLocked(DisplayDevice device,
boolean isBlanked) {
... ...
mTempDisplayRect.top += mDisplayOffsetY;
mTempDisplayRect.bottom += mDisplayOffsetY;
// 强制界面全屏显示,否则会同步按照主屏分辨率比例去显示,可能会有黑边
+ if(device.getDisplayDeviceInfoLocked().type != Display.TYPE_BUILT_IN){
+ mTempDisplayRect.left = 0;
+ mTempDisplayRect.right = physWidth;
+ mTempDisplayRect.top = 0;
+ mTempDisplayRect.bottom = physHeight;
+ }
+
device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect);
... ...
}
2、副屏TP过滤(异触)
系统上传的触屏event,需要在系统层进行区分,判断是内置TP(主屏tp),还是外接TP(副屏tp)。Event事件都可以在下面这支文件处理。
frameworks/native/services/inputflinger/EventHub.cpp
status_t EventHub::openDeviceLocked(const char *devicePath) {
... ...
// Determine whether the device is external or internal.
- if (isExternalDeviceLocked(device)) {
+ ALOGE("device %d: %d %s\n", device->id, device->fd, device->path.c_str());
+ char buf[256];
+ ioctl(device->fd, EVIOCGNAME(sizeof(buf)), buf);
+ ALOGE("device name: %s", buf);
// 通过TP名称,判断是否是外接设备,达到异触效果
+ if (isExternalDeviceLocked(device) || strcmp(buf, "device_name") == 0) {
device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
}
... ...
}
3、副屏TP方向调整
副显示屏的方向,只能单独去旋转。旋转后,TP也需要跟着旋转下,在input事件上传过程中调整X、Y即可。
frameworks/native/services/inputflinger/InputReader.cpp
+int second_ID; //副屏tp的id
void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
... ...
switch (rawEvent->code) {
// 通过ID过滤TP事件,进行TP方向调整操作
case ABS_MT_POSITION_X:
slot->mInUse = true;
- slot->mAbsMTPositionX = rawEvent->value;
+ if ((second_ID == rawEvent->deviceId)) {
+ slot->mAbsMTPositionY = rawEvent->value;
+ } else {
+ slot->mAbsMTPositionX = rawEvent->value;
+ }
break;
case ABS_MT_POSITION_Y:
slot->mInUse = true;
- slot->mAbsMTPositionY = rawEvent->value;
+ if (second_ID == rawEvent->deviceId) {
+ slot->mAbsMTPositionX = 1280 - rawEvent->value + 1;
+ } else {
+ slot->mAbsMTPositionY = rawEvent->value;
+ }
break;
... ...
}
void MultiTouchInputMapper::configureRawPointerAxes() {
TouchInputMapper::configureRawPointerAxes();
- getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
- getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
// TP的name是固定的,通过getevent可以看到,但是ID不是固定的,所以通过名称判断,然后获取目前ID,后续通过ID过滤TP事件
+ if(strcmp(getDeviceName().string(), "device_name") == 0) {
+ second_ID = getDeviceId();
+ getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.y);
+ } else {
+ getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+ }
getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
... ...
}