2
0
mirror of https://github.com/koreader/koreader synced 2024-10-31 21:20:20 +00:00
The ABS_PRESSURE ABS code is also detected on some KOBO devices
if ABS_PRESSURE events are feeded to handle orientation those devices
will have a unresponsive screen as described in #2219.

This patch registers an event adjustment handler for Kindle Oasis to
adjust the ABS_PRESSURE code to ABS_OASIS_ORIENTATION code so that
it won't affect event handling on other devices.
This commit is contained in:
chrox 2016-08-13 18:47:38 +08:00
parent aa8d4f27ae
commit 7fd6037bb0
3 changed files with 141 additions and 107 deletions

View File

@ -40,9 +40,10 @@ local ABS_MT_POSITION_Y = 54
local ABS_MT_TRACKING_ID = 57 local ABS_MT_TRACKING_ID = 57
local ABS_MT_PRESSURE = 58 local ABS_MT_PRESSURE = 58
-- For device orientation events (ABS.code) -- For Kindle Oasis orientation events (ABS.code)
-- the ABS code of orientation event will be adjusted to -24 from 24(ABS_PRESSURE)
local ABS_PRESSURE = 24 -- as ABS_PRESSURE is also used to detect touch input in KOBO devices.
local ABS_OASIS_ORIENTATION = -24
local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15 local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15
local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17 local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17
local DEVICE_ORIENTATION_PORTRAIT = 19 local DEVICE_ORIENTATION_PORTRAIT = 19
@ -240,6 +241,12 @@ function Input:adjustTouchTranslate(ev, by)
end end
end end
function Input:adjustKindleOasisOrientation(ev)
if ev.type == EV_ABS and ev.code == ABS_PRESSURE then
ev.code = ABS_OASIS_ORIENTATION
end
end
function Input:setTimeout(cb, tv_out) function Input:setTimeout(cb, tv_out)
local item = { local item = {
callback = cb, callback = cb,
@ -463,18 +470,19 @@ function Input:handleTouchEvPhoenix(ev)
end end
end end
function Input:handleOrientationEv(ev) function Input:handleOasisOrientationEv(ev)
if ev.type == EV_ABS then
if ev.code == ABS_PRESSURE then
local rotation_mode, screen_mode local rotation_mode, screen_mode
if ev.value == DEVICE_ORIENTATION_PORTRAIT or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then if ev.value == DEVICE_ORIENTATION_PORTRAIT
or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT
or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then
rotation_mode = framebuffer.ORIENTATION_PORTRAIT rotation_mode = framebuffer.ORIENTATION_PORTRAIT
screen_mode = 'portrait' screen_mode = 'portrait'
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then
rotation_mode = framebuffer.ORIENTATION_LANDSCAPE rotation_mode = framebuffer.ORIENTATION_LANDSCAPE
screen_mode = 'landscape' screen_mode = 'landscape'
elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED
or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT
or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then
rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED
screen_mode = 'portrait' screen_mode = 'portrait'
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then
@ -483,19 +491,17 @@ function Input:handleOrientationEv(ev)
end end
local old_rotation_mode = self.device.screen:getRotationMode() local old_rotation_mode = self.device.screen:getRotationMode()
local old_screen_mode = self.device.screen:getScreenMode(); local old_screen_mode = self.device.screen:getScreenMode()
DEBUG("old_rotation_mode: ", old_rotation_mode) DEBUG:v("old_rotation_mode: ", old_rotation_mode)
DEBUG("new_rotation_mode: ", rotation_mode) DEBUG:v("new_rotation_mode: ", rotation_mode)
DEBUG("old_screen_mode: ", old_screen_mode) DEBUG:v("old_screen_mode: ", old_screen_mode)
DEBUG("new_screen_mode: ", screen_mode) DEBUG:v("new_screen_mode: ", screen_mode)
if rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then if rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then
self.device.screen:setRotationMode(rotation_mode) self.device.screen:setRotationMode(rotation_mode)
local UIManager = require("ui/uimanager") local UIManager = require("ui/uimanager")
UIManager:onRotation() UIManager:onRotation()
end end
end end
end
end
-- helpers for touch event data management: -- helpers for touch event data management:
@ -593,13 +599,14 @@ function Input:waitEvent(timeout_us)
if ok and ev then if ok and ev then
if DEBUG.is_on and ev then if DEBUG.is_on and ev then
DEBUG:logEv(ev) DEBUG:logEv(ev)
DEBUG:v("ev", ev)
end end
self:eventAdjustHook(ev) self:eventAdjustHook(ev)
if ev.type == EV_KEY then if ev.type == EV_KEY then
DEBUG("key ev", ev) DEBUG("key ev", ev)
return self:handleKeyBoardEv(ev) return self:handleKeyBoardEv(ev)
elseif ev.type == EV_ABS and ev.code == ABS_PRESSURE then elseif ev.type == EV_ABS and ev.code == ABS_OASIS_ORIENTATION then
return self:handleOrientationEv(ev) return self:handleOasisOrientationEv(ev)
elseif ev.type == EV_ABS or ev.type == EV_SYN then elseif ev.type == EV_ABS or ev.type == EV_SYN then
return self:handleTouchEv(ev) return self:handleTouchEv(ev)
elseif ev.type == EV_MSC then elseif ev.type == EV_MSC then

View File

@ -349,11 +349,12 @@ function KindleOasis:init()
} }
} }
local lipc = require("liblipclua") local haslipc, lipc = pcall(require, "liblipclua")
if lipc then if haslipc and lipc then
local lipc_handle = lipc.init("com.github.koreader.screen") local lipc_handle = lipc.init("com.github.koreader.screen")
if lipc_handle then if lipc_handle then
local orientation_code = lipc_handle:get_string_property("com.lab126.winmgr", "accelerometer") local orientation_code = lipc_handle:get_string_property(
"com.lab126.winmgr", "accelerometer")
local rotation_mode = 0 local rotation_mode = 0
if orientation_code then if orientation_code then
if orientation_code == "V" then if orientation_code == "V" then
@ -376,9 +377,10 @@ function KindleOasis:init()
end end
end end
Kindle.init(self) Kindle.init(self)
self.input:registerEventAdjustHook(self.input.adjustKindleOasisOrientation)
self.input.open(self.touch_dev) self.input.open(self.touch_dev)
self.input.open("/dev/input/by-path/platform-gpiokey.0-event") self.input.open("/dev/input/by-path/platform-gpiokey.0-event")

View File

@ -1,5 +1,8 @@
describe("device module", function() describe("device module", function()
local mock_fb, mock_input local mock_fb, mock_input
local iopen = io.open
local osgetenv = os.getenv
setup(function() setup(function()
mock_fb = { mock_fb = {
new = function() new = function()
@ -7,48 +10,51 @@ describe("device module", function()
getSize = function() return {w = 600, h = 800} end, getSize = function() return {w = 600, h = 800} end,
getWidth = function() return 600 end, getWidth = function() return 600 end,
getDPI = function() return 72 end, getDPI = function() return 72 end,
setViewport = function() end setViewport = function() end,
getRotationMode = function() return 0 end,
getScreenMode = function() return "portrait" end,
setRotationMode = function() end,
} }
end end
} }
require("commonrequire") require("commonrequire")
end) end)
before_each(function()
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
package.loaded['device/kindle/device'] = nil
package.loaded['device/kobo/device'] = nil
mock_input = require('device/input')
stub(mock_input, "open")
stub(os, "getenv")
stub(os, "execute")
end)
after_each(function()
mock_input.open:revert()
os.getenv:revert()
os.execute:revert()
os.getenv = osgetenv
io.open = iopen
end)
describe("kobo", function() describe("kobo", function()
local TimeVal local TimeVal
setup(function() setup(function()
TimeVal = require("ui/timeval") TimeVal = require("ui/timeval")
mock_fb = {
new = function()
return {
getSize = function() return {w = 600, h = 800} end,
getWidth = function() return 600 end,
getDPI = function() return 72 end,
setViewport = function() end
}
end
}
end) end)
it("should initialize properly on Kobo dahlia", function() it("should initialize properly on Kobo dahlia", function()
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
stub(os, "getenv")
os.getenv.returns("dahlia") os.getenv.returns("dahlia")
local kobo_dev = require("device/kobo/device") local kobo_dev = require("device/kobo/device")
mock_input = require('device/input')
stub(mock_input, "open")
kobo_dev:init() kobo_dev:init()
assert.is.same("Kobo_dahlia", kobo_dev.model) assert.is.same("Kobo_dahlia", kobo_dev.model)
package.loaded['ffi/framebuffer_mxcfb'] = nil
os.getenv:revert()
mock_input.open:revert()
end) end)
it("should setup eventAdjustHooks properly for input in trilogy", function() it("should setup eventAdjustHooks properly for input in trilogy", function()
local saved_getenv = os.getenv
stub(os, "getenv")
os.getenv.invokes(function(key) os.getenv.invokes(function(key)
if key == "PRODUCT" then if key == "PRODUCT" then
return "trilogy" return "trilogy"
@ -56,11 +62,8 @@ describe("device module", function()
return saved_getenv(key) return saved_getenv(key)
end end
end) end)
package.loaded['device/kobo/device'] = nil
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
mock_input = require('device/input')
stub(mock_input, "open")
package.loaded['device/kobo/device'] = nil
local kobo_dev = require("device/kobo/device") local kobo_dev = require("device/kobo/device")
kobo_dev:init() kobo_dev:init()
local Screen = kobo_dev.screen local Screen = kobo_dev.screen
@ -93,17 +96,12 @@ describe("device module", function()
assert.is.same(y, ev_x.value) assert.is.same(y, ev_x.value)
assert.is.same(ABS_Y, ev_x.code) assert.is.same(ABS_Y, ev_x.code)
package.loaded['ffi/framebuffer_mxcfb'] = nil
os.getenv:revert()
mock_input.open:revert()
-- reset eventAdjustHook -- reset eventAdjustHook
kobo_dev.input.eventAdjustHook = function() end kobo_dev.input.eventAdjustHook = function() end
kobo_dev.touch_probe_ev_epoch_time = true kobo_dev.touch_probe_ev_epoch_time = true
end) end)
it("should setup eventAdjustHooks properly for trilogy with non-epoch ev time", function() it("should setup eventAdjustHooks properly for trilogy with non-epoch ev time", function()
local saved_getenv = os.getenv
stub(os, "getenv")
os.getenv.invokes(function(key) os.getenv.invokes(function(key)
if key == "PRODUCT" then if key == "PRODUCT" then
return "trilogy" return "trilogy"
@ -111,11 +109,6 @@ describe("device module", function()
return saved_getenv(key) return saved_getenv(key)
end end
end) end)
package.loaded['device/kobo/device'] = nil
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
mock_input = require('device/input')
stub(mock_input, "open")
local kobo_dev = require("device/kobo/device") local kobo_dev = require("device/kobo/device")
kobo_dev:init() kobo_dev:init()
local Screen = kobo_dev.screen local Screen = kobo_dev.screen
@ -149,9 +142,6 @@ describe("device module", function()
assert.truthy(cur_sec - ev_x.time.sec < 10) assert.truthy(cur_sec - ev_x.time.sec < 10)
assert.truthy(cur_sec - ev_y.time.sec < 10) assert.truthy(cur_sec - ev_y.time.sec < 10)
package.loaded['ffi/framebuffer_mxcfb'] = nil
os.getenv:revert()
mock_input.open:revert()
kobo_dev.input.eventAdjustHook = function() end kobo_dev.input.eventAdjustHook = function() end
end) end)
@ -195,44 +185,44 @@ describe("device module", function()
end) end)
end) end)
describe("kindle #notest #nocov", function() describe("kindle", function()
it("should initialize voyage without error", function() it("should initialize voyage without error", function()
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb io.open = function(filename, mode)
stub(io, "open") if filename == "/proc/usid" then
io.open.returns({ return {
read = function() read = function() return "XX13XX" end,
return "XX13XX"
end,
close = function() end close = function() end
}) }
mock_input = require('device/input') else
stub(mock_input, "open") return iopen(filename, mode)
end
end
local kindle_dev = require("device/kindle/device") local kindle_dev = require('device/kindle/device')
assert.is.same(kindle_dev.model, "KindleVoyage") assert.is.same(kindle_dev.model, "KindleVoyage")
kindle_dev:init() kindle_dev:init()
assert.is.same(kindle_dev.input.event_map[104], "LPgBack") assert.is.same(kindle_dev.input.event_map[104], "LPgBack")
assert.is.same(kindle_dev.input.event_map[109], "LPgFwd") assert.is.same(kindle_dev.input.event_map[109], "LPgFwd")
assert.is.same(kindle_dev.powerd.fl_min, 0) assert.is.same(kindle_dev.powerd.fl_min, 0)
assert.is.same(kindle_dev.powerd.fl_max, 24) assert.is.same(kindle_dev.powerd.fl_max, 24)
io.open:revert()
package.loaded['ffi/framebuffer_mxcfb'] = nil
mock_input.open:revert()
end) end)
it("should toggle frontlight", function() it("should toggle frontlight", function()
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb io.open = function(filename, mode)
stub(io, "open") if filename == "/proc/usid" then
io.open.returns({ return {
read = function() read = function() return "XX13XX" end,
return "12"
end,
close = function() end close = function() end
}) }
mock_input = require('device/input') elseif filename == "/sys/class/backlight/max77696-bl/brightness" then
stub(mock_input, "open") return {
stub(os, "execute") read = function() return "12" end,
close = function() end
}
else
return iopen(filename, mode)
end
end
local kindle_dev = require("device/kindle/device") local kindle_dev = require("device/kindle/device")
kindle_dev:init() kindle_dev:init()
@ -251,11 +241,46 @@ describe("device module", function()
kindle_dev.powerd:toggleFrontlight() kindle_dev.powerd:toggleFrontlight()
assert.stub(os.execute).was_called_with( assert.stub(os.execute).was_called_with(
"echo -n 5 > /sys/class/backlight/max77696-bl/brightness") "echo -n 5 > /sys/class/backlight/max77696-bl/brightness")
end)
io.open:revert() it("oasis should interpret orientation event", function()
package.loaded['ffi/framebuffer_mxcfb'] = nil io.open = function(filename, mode)
mock_input.open:revert() if filename == "/proc/usid" then
os.execute:revert() return {
read = function()
return "XXX0GCXXX"
end,
close = function() end
}
else
return iopen(filename, mode)
end
end
mock_ffi_input = require('ffi/input')
stub(mock_ffi_input, "waitForEvent")
mock_ffi_input.waitForEvent.returns({
type = 3,
time = {
usec = 450565,
sec = 1471081881
},
code = 24,
value = 16
})
local UIManager = require("ui/uimanager")
stub(UIManager, "onRotation")
local kindle_dev = require('device/kindle/device')
assert.is.same("KindleOasis", kindle_dev.model)
kindle_dev:init()
kindle_dev.input:waitEvent()
assert.stub(UIManager.onRotation).was_called()
mock_ffi_input.waitForEvent:revert()
UIManager.onRotation:revert()
end) end)
end) end)
end) end)