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);
    
    ... ...
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章