with_system_controller = false
+with_amb = false
+verbose = 0
m = murphy.get()
m:info("No domain-control plugin found...")
end
+if m:plugin_exists('glib') then
+ m:load_plugin('glib')
+else
+ m:info("No glib plugin found...")
+end
+
+if m:plugin_exists("gam-resource-manager") then
+
+function get_general_priorities(self)
+ print("*** get_general_priorities\n")
+ return { "USB Headset", "wiredHeadset", "speakers" }
+end
+
+function get_phone_priorities(self)
+ print("*** get_phone_priorities\n")
+ return { "wiredHeadset", "USB Headset" }
+end
+
+m:load_plugin('gam-resource-manager', {
+ config_dir = '/etc/murphy/gam',
+ decision_names = 'gam-wrtApplication-4',
+ max_active = 4,
+ app_mapping = {
+ ['t8j6HTRpuz.MediaPlayer'] = 'wrtApplication',
+ ['pacat'] = 'icoApplication'
+ },
+ app_default = 'icoApplication'
+})
+
+routing_sink_priority {
+ application_class = "player",
+ priority_queue = get_general_priorities
+}
+
+routing_sink_priority {
+ application_class = "game",
+ priority_queue = get_general_priorities
+}
+
+routing_sink_priority {
+ application_class = "implicit",
+ priority_queue = get_general_priorities
+}
+
+routing_sink_priority {
+ application_class = "phone",
+ priority_queue = get_phone_priorities
+}
+
+routing_sink_priority {
+ application_class = "basic",
+ priority_queue = get_phone_priorities
+}
+
+routing_sink_priority {
+ application_class = "event",
+ priority_queue = get_phone_priorities
+}
+end
+
-- load the AMB plugin
if m:plugin_exists('amb') then
- m:load_plugin('amb')
+ m:try_load_plugin('amb')
+
+ if builtin.method.amb_initiate and
+ builtin.method.amb_update
+ then
+ with_amb = true
+ end
else
m:info("No amb plugin found...")
end
-- load the ASM resource plugin
if m:plugin_exists('resource-asm') then
- m:load_plugin('resource-asm', {
+ m:try_load_plugin('resource-asm', {
zone = "driver",
share_mmplayer = "player:AVP,mandatory,exclusive,strict",
ignored_argv0 = "WebProcess"
m:info("No audio session manager plugin found...")
end
-if m:plugin_exists('ivi-resource-manager') and not with_system_controller then
+if m:plugin_exists('system-controller') then
+ with_system_controller = true
+elseif m:plugin_exists('ivi-resource-manager') then
m:load_plugin('ivi-resource-manager')
+ with_system_controller = false
end
-- define application classes
order = "fifo"
}
application_class {
+ name = "system",
+ priority = 52,
+ modal = false,
+ share = true,
+ order = "lifo"
+}
+application_class {
name = "alert",
priority = 51,
modal = false,
-- define resource classes
if not m:plugin_exists('ivi-resource-manager') and
- not with_system_controller
+ not with_system_controller and
+ not m:plugin_exists('gam-resource-manager')
then
resource.class {
name = "audio_playback",
attributes = {
role = { mdb.string, "music", "rw" },
pid = { mdb.string, "<unknown>", "rw" },
- policy = { mdb.string, "relaxed", "rw" }
+ policy = { mdb.string, "relaxed", "rw" },
+ source = { mdb.string, "webkit", "rw" },
+ conn_id = { mdb.unsigned, 0, "rw" }
}
}
end
-resource.class {
- name = "audio_recording",
- shareable = true,
- attributes = {
- role = { mdb.string, "music" , "rw" },
- pid = { mdb.string, "<unknown>", "rw" },
- policy = { mdb.string, "relaxed" , "rw" }
- }
-}
+if not m:plugin_exists('gam-resource-manager') then
+ resource.class {
+ name = "audio_recording",
+ shareable = true,
+ attributes = {
+ role = { mdb.string, "music" , "rw" },
+ pid = { mdb.string, "<unknown>", "rw" },
+ policy = { mdb.string, "relaxed" , "rw" }
+ }
+ }
+end
resource.class {
name = "video_playback",
shareable = false
}
-if not m:plugin_exists('ivi-resource-manager') then
-resource.method.veto = {
- function(zone, rset, grant, owners)
- rset_priority = application_class[rset.application_class].priority
-
- owner_id = owners.audio_playback.resource_set
- rset_id = rset.id
+resource.class {
+ name = "speech_recognition",
+ shareable = true
+}
- if (rset_priority >= 50 and owner_id ~= rset_id) then
- print("*** resource-set "..rset_id.." - veto")
- return false
- end
+resource.class {
+ name = "speech_synthesis",
+ shareable = true
+}
- return true
- end
+-- PulseAudio volume context
+mdb.table {
+ name = "volume_context",
+ index = { "id" },
+ create = true,
+ columns = {
+ { "id", mdb.unsigned },
+ { "value", mdb.string, 64 },
+ }
}
+
+-- put default volume context to the table
+mdb.table.volume_context:insert({ id = 1, value = "default" })
+
+if not m:plugin_exists('ivi-resource-manager') and
+ not with_system_controller
+then
+ resource.method.veto = {
+ function(zone, rset, grant, owners, req_set)
+ return true
+ end
+ }
end
-- test for creating selections
name = "speed2volume",
inputs = { speed = mdb.select.vehicle_speed, param = 9 },
outputs = { mdb.table { name = "speedvol",
- index = {"zone", "device"},
- columns = {{"zone", mdb.string, 16},
- {"device", mdb.string, 16},
- {"value", mdb.floating}},
+ index = {"zone", "device"},
+ columns = {{"zone", mdb.string, 16},
+ {"device", mdb.string, 16},
+ {"value", mdb.floating}},
create = true
- }
- },
+ }
+ },
oldvolume = 0.0,
update = function(self)
speed = self.inputs.speed.single_value
if (diff*diff > self.inputs.param) then
print("*** element "..self.name.." update "..volume)
self.oldvolume = volume
- mdb.table.speedvol:replace({zone = "driver", device = "speakers", value = volume})
- end
- end
+ mdb.table.speedvol:replace({zone = "driver", device = "speakers", value = volume})
+ end
+ end
+}
+
+mdb.select {
+ name = "amb_state",
+ table = "amb_state",
+ columns = { "state" },
+ condition = "id = 0"
}
-- Night mode processing chain
condition = "id = 0"
}
-sink.lua {
- name = "night_mode",
- inputs = { owner = mdb.select.select_night_mode },
- property = "NightMode",
- type = "b",
- initiate = builtin.method.amb_initiate,
- update = builtin.method.amb_update
-}
+if with_amb then
+ sink.lua {
+ name = "night_mode",
+ inputs = { NightMode = mdb.select.select_night_mode,
+ amb_state = mdb.select.amb_state },
+ property = "NightMode",
+ type = "b",
+ initiate = builtin.method.amb_initiate,
+ update = builtin.method.amb_update
+ }
+end
+-- Night mode general handlers
+
+if with_system_controller then
+ sink.lua {
+ name = "nightmode_homescreen",
+ inputs = { owner = mdb.select.select_night_mode },
+ initiate = function(self)
+ -- data = mdb.select.select_night_mode.single_value
+ return true
+ end,
+ update = function(self)
+ send_night_mode_to(homescreen)
+ end
+ }
+end
-- Driving mode processing chain
-
element.lua {
name = "drivingmode",
inputs = { speed = mdb.select.vehicle_speed },
condition = "id = 0"
}
-sink.lua {
- name = "driving_mode",
- inputs = { owner = mdb.select.select_driving_mode },
- property = "DrivingMode",
- type = "u",
- initiate = builtin.method.amb_initiate,
- update = builtin.method.amb_update
-}
+if with_amb then
+ sink.lua {
+ name = "driving_mode",
+ inputs = { DrivingMode = mdb.select.select_driving_mode,
+ amb_state = mdb.select.amb_state },
+ property = "DrivingMode",
+ type = "u",
+ initiate = builtin.method.amb_initiate,
+ update = builtin.method.amb_update
+ }
+end
-- turn signals (left, right)
condition = "key = 'TurnSignal'"
}
+-- define three categories
+
+mdb.select {
+ name = "undefined_applications",
+ table = "aul_applications",
+ columns = { "appid" },
+ condition = "category = '<undefined>'"
+}
+
+mdb.select {
+ name = "basic_applications",
+ table = "aul_applications",
+ columns = { "appid" },
+ condition = "category = 'basic'"
+}
+
+mdb.select {
+ name = "entertainment_applications",
+ table = "aul_applications",
+ columns = { "appid" },
+ condition = "category = 'entertainment'"
+}
+
+function ft(t)
+ -- filter the object garbage out of the tables
+ ret = {}
+
+ for k,v in pairs(t) do
+ if k ~= "userdata" and k ~= "new" then
+ ret[k] = v
+ end
+ end
+
+ return ret
+end
+
+function getApplication(appid)
+ local conf = nil
+
+ -- find the correct local application definition
+
+ for k,v in pairs(ft(application)) do
+ if appid == v.appid then
+ conf = v
+ break
+ end
+ end
+
+ return conf
+end
+
+function regulateApplications(t, regulation)
+ for k,v in pairs(ft(t)) do
+
+ whitelisted = false
+
+ -- our local application config, which takes precedence
+ local conf = getApplication(v.appid)
+
+ if conf then
+ if conf.resource_class ~= "player" then
+ whitelisted = true
+ end
+
+ if conf.requisites and conf.requisites.screen then
+ if conf.requisites.screen.driving then
+ whitelisted = true
+ end
+ end
+ end
+
+ if whitelisted then
+ -- override, don't disable
+ resmgr:disable_screen_by_appid("*", "*", v.appid, false, false)
+ else
+ resmgr:disable_screen_by_appid("*", "*", v.appid, regulation == 1, false)
+ end
+ end
+ resource.method.recalc("driver")
+end
+
-- regulation (on), use "select_driving_mode"
+sink.lua {
+ name = "driving_regulation",
+ inputs = { owner = mdb.select.select_driving_mode },
+ initiate = function(self)
+ -- local data = mdb.select.select_driving_mode.single_value
+ return true
+ end,
+ update = function(self)
+ local data = mdb.select.select_driving_mode.single_value
+
+ if verbose > 1 then
+ print("Driving mode updated: " .. tostring(data))
+ end
+
+ if not sc then
+ return true
+ end
+
+ -- tell homescreen that driving mode was updated
+ send_driving_mode_to(homescreen)
+
+ regulateApplications(ft(mdb.select.entertainment_applications), data)
+ regulateApplications(ft(mdb.select.undefined_applications), data)
+
+ return true
+ end
+}
+--[[
+sink.lua {
+ name = "regulated_app_change",
+ inputs = { undef = mdb.select.undefined_applications,
+ entertainment = mdb.select.entertainment_applications },
+ initiate = function(self)
+ return true
+ end,
+ update = function(self)
+ local data = mdb.select.select_driving_mode.single_value
+
+ if not sc then
+ return
+ end
+
+ if verbose > 1 then
+ print("regulated application list was changed")
+ end
+
+ regulateApplications(ft(mdb.select.entertainment_applications), data)
+ regulateApplications(ft(mdb.select.undefined_applications), data)
+
+ return true
+ end
+}
+--]]
+
-- shift position (parking, reverse, other)
mdb.select {
end
}
--- load the telephony plugin
-m:try_load_plugin('telephony')
-
-
-- system controller test setup
if not with_system_controller then
+ -- ok, we should have 'audio_playback' defined by now
+ m:try_load_plugin('telephony')
return
end
+m:load_plugin('system-controller')
+
+onscreen_counter = 0
+
+window_manager_operation_names = {
+ [1] = "create",
+ [2] = "destroy"
+}
+
+function window_manager_operation_name(oper)
+ local name = window_manager_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
window_operation_names = {
[1] = "create",
[2] = "destroy",
[3] = "name_change",
[4] = "visible",
[5] = "configure",
- [6] = "active"
+ [6] = "active",
+ [7] = "map",
+ [8] = "hint"
}
function window_operation_name(oper)
return "<unknown " .. tostring(oper) .. ">"
end
+layer_operation_names = {
+ [1] = "create",
+ [2] = "destroy",
+ [3] = "visible"
+}
+
+function layer_operation_name(oper)
+ local name = layer_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
+input_manager_operation_names = {
+ [1] = "create",
+ [2] = "destroy",
+ [3] = "ready"
+}
+
+function input_manager_operation_name(oper)
+ local name = input_manager_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
+input_operation_names = {
+ [1] = "create",
+ [2] = "destroy",
+ [3] = "update"
+}
+
+function input_operation_name(oper)
+ local name = input_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
+code_operation_names = {
+ [1] = "create",
+ [2] = "destroy",
+ [3] = "state_change"
+}
+
+function code_operation_name(oper)
+ local name = code_operation_names[oper]
+ if name then return name end
+ return "<unknown " .. tostring(oper) .. ">"
+end
+
command_names = {
[0x00001] = "send_appid",
[0x10001] = "create",
[0x10003] = "show",
[0x10004] = "hide",
[0x10005] = "move",
- [0x10006] = "change_active",
- [0x10007] = "change_layer",
- [0x10008] = "change_attr",
- [0x10009] = "name",
- [0x10011] = "map_thumb",
- [0x10012] = "unmap_thumb",
- [0x10020] = "show layer",
- [0x10021] = "hide_layer",
- [0x10022] = "change_layer_attr",
+ [0x10006] = "animation",
+ [0x10007] = "change_active",
+ [0x10008] = "change_layer",
+ [0x10009] = "change_attr",
+ [0x10010] = "name",
+ [0x10020] = "map_thumb",
+ [0x10021] = "unmap_thumb",
+ [0x10022] = "map_get",
+ [0x10030] = "show layer",
+ [0x10031] = "hide_layer",
+ [0x10032] = "change_layer_attr",
[0x20001] = "add_input",
[0x20002] = "del_input",
- [0x20003] = "send_input"
+ [0x30001] = "change_user",
+ [0x30002] = "get_userlist",
+ [0x30003] = "get_lastinfo",
+ [0x30004] = "set_lastinfo",
+ [0x40001] = "acquire_res",
+ [0x40002] = "release_res",
+ [0x40003] = "deprive_res",
+ [0x40004] = "waiting_res",
+ [0x40005] = "revert_res",
+ [0x40006] = "window_id_res",
+ [0x40011] = "create_res",
+ [0x40012] = "destroy_res",
+ [0x50001] = "set_region",
+ [0x50002] = "unset_region",
+ [0x60001] = "change_state"
}
function command_name(command)
return "<unknown " .. tostring(command) .. ">"
end
-wmgr = window_manager({
+input_layer = {
+ [101] = true, -- input
+ [102] = true, -- touch
+ [103] = true -- cursor
+}
+
+-- some day this should be merged with wmgr.layers
+ico_layer_type = {
+ [1] = 0x1000, -- background
+ [2] = 0x2000, -- application
+ [3] = 0x2000, -- homescreen
+ [4] = 0x2000, -- interrupt application
+ [5] = 0x2000, -- onscreen application
+ [6] = 0xc000, -- startup
+ [7] = 0x3000, -- fullscreen
+ [101] = 0x4000, -- input
+ [102] = 0xa000, -- touch
+ [103] = 0xb000 -- cursor
+}
+
+resmgr = resource_manager {
+ screen_event_handler = function(self, ev)
+ local event = ev.event
+ local surface = ev.surface
+
+ if event == "init" then
+ if verbose > 0 then
+ print("*** init screen resource allocation -- disable all 'player'")
+ end
+ resmgr:disable_audio_by_appid("*", "player", "*", true, false)
+ elseif event == "preallocate" then
+ if verbose > 0 then
+ print("*** preallocate screen resource "..
+ "for '" .. ev.appid .. "' -- enable 'player', if any")
+ end
+ resmgr:disable_audio_by_appid("*", "player", ev.appid, false, false)
+ elseif event == "grant" then
+ if verbose > 0 then
+ print("*** make visible surface "..surface)
+ end
+ local a = animation({})
+ local r = m:JSON({surface = surface,
+ visible = 1,
+ raise = 1})
+ if ev.appid == onscreen then
+ onscreen_counter = onscreen_counter + 1
+ wmgr:layer_request(m:JSON({layer = 5, visible = 1}))
+ end
+
+ wmgr:window_request(r,a,0)
+ elseif event == "revoke" then
+ if verbose > 0 then
+ print("*** hide surface "..surface)
+ end
+ local a = animation({})
+ local r = m:JSON({surface = ev.surface,
+ visible = 0})
+ if ev.appid == onscreen then
+ onscreen_counter = onscreen_counter - 1
+ if onscreen_counter <= 0 then
+ onscreen_counter = 0
+ wmgr:layer_request(m:JSON({layer = 5, visible = 0}))
+ end
+ end
+ wmgr:window_request(r,a,0)
+
+ elseif event == "create" then
+
+ if verbose > 0 then
+ print("*** screen resource event: " ..
+ tostring(ev))
+ end
+
+ local regulation = mdb.select.select_driving_mode.single_value
+
+ if regulation == 1 then
+
+ local blacklisted = false
+
+ -- applications which have their category set to "entertainment"
+ -- or "undefined" are blacklisted, meaning they should be regulated
+
+ for i,v in pairs(ft(mdb.select.undefined_applications)) do
+ if v.appid == ev.appid then
+ if verbose > 0 then
+ print(ev.appid .. " was blacklisted (undefined)")
+ end
+ blacklisted = true
+ break
+ end
+ end
+
+ if not blacklisted then
+ for i,v in pairs(ft(mdb.select.entertainment_applications)) do
+ if v.appid == ev.appid then
+ if verbose > 0 then
+ print(ev.appid .. " was blacklisted (entertainment)")
+ end
+ blacklisted = true
+ break
+ end
+ end
+ end
+
+ -- our local application config, which takes precedence
+ local conf = getApplication(ev.appid)
+
+ if not conf then
+ blacklisted = true
+ else
+ if conf.resource_class == "player" then
+ blacklisted = true
+ end
+
+ -- check the exceptions
+ if conf.requisites and conf.requisites.screen then
+ if conf.requisites.screen.driving then
+ blacklisted = false
+ end
+ end
+ end
+
+ -- disable only non-whitelisted applications
+ if blacklisted then
+ if verbose > 0 then
+ print("disabling screen for " .. ev.appid)
+ end
+ resmgr:disable_screen_by_appid("*", "*", ev.appid, true, true)
+ end
+ end
+
+ elseif event == "destroy" then
+ if verbose > 0 then
+ print("*** screen resource event: " ..
+ tostring(ev))
+ end
+ else
+ if verbose > 0 then
+ print("*** screen resource event: " ..
+ tostring(ev))
+ end
+ end
+ end,
+ audio_event_handler = function(self, ev)
+ local event = ev.event
+ local appid = ev.appid
+ local audioid = ev.audioid
+
+ if event == "grant" then
+ if verbose > 0 then
+ print("*** grant audio to "..appid..
+ " ("..audioid..") in '" ..
+ ev.zone .. "' zone")
+ end
+ elseif event == "revoke" then
+ if verbose > 0 then
+ print("*** revoke audio from "..appid..
+ " ("..audioid..") in '" ..
+ ev.zone .. "' zone")
+ end
+ else
+ if verbose > 0 then
+ print("*** audio resource event: " ..
+ tostring(ev))
+ end
+ end
+ end
+}
+
+resclnt = resource_client {}
+
+wmgr = window_manager {
geometry = function(self, w,h, v)
if type(v) == "function" then
return v(w,h)
return v
end,
- outputs = { { name = "Center",
- id = 0,
- areas = { Status = {
- id = 100,
+ application = function(self, appid)
+ if appid then
+ local app = application_lookup(appid)
+ if not app then
+ app = application_lookup("default")
+ end
+ return app
+ end
+ return { privileges = {screen="none", audio="none"} }
+ end,
+
+ output_order = { 1, 0 },
+
+ outputs = { { name = "Mid",
+ id = 1,
+ zone = "driver",
+ areas = { Full = {
+ id = 20,
pos_x = 0,
pos_y = 0,
width = function(w,h) return w end,
- height = 64
+ height = function(w,h) return h end
+ },
+ Left = {
+ id = 21,
+ pos_x = 0,
+ pos_y = 0,
+ width = 320,
+ height = function(w,h) return h end
},
- Full = {
+ Right = {
+ id = 22,
+ pos_x = function(w,h) return w-320 end,
+ pos_y = 0,
+ width = 320,
+ height = function(w,h) return h end
+ }
+ }
+ },
+ { name = "Center",
+ id = 4,
+ zone = "driver",
+ areas = { Status = {
+ id = 0,
+ pos_x = 0,
+ pos_y = 0,
+ width = function(w,h) return w end,
+ height = 64
+ },
+ Full = {
id = 1,
pos_x = 0,
pos_y = 64,
width = function(w,h) return w end,
height = function(w,h) return h-64-128 end
- },
- Upper = {
+ },
+ Upper = {
id = 2,
pos_x = 0,
pos_y = 64,
width = function(w,h) return w end,
height = function(w,h) return (h-64-128)/2 end
- },
- Lower = {
+ },
+ Lower = {
id = 3,
pos_x = 0,
pos_y = function(w,h) return (h-64-128)/2+64 end,
width = function(w,h) return w end,
height = function(w,h) return (h-64-128)/2 end
- },
- UpperLeft = {
+ },
+ UpperLeft = {
id = 4,
pos_x = 0,
pos_y = 64,
width = function(w,h) return w/2 end,
height = function(w,h) return (h-64-128)/2 end
- },
- UpperRight = {
+ },
+ UpperRight = {
id = 5,
pos_x = function(w,h) return w/2 end,
pos_y = 64,
width = function(w,h) return w/2 end,
height = function(w,h) return (h-64-128)/2 end
- },
- LowerLeft = {
+ },
+ LowerLeft = {
id = 6,
pos_x = 0,
pos_y = function(w,h) return (h-64-128/2)+64 end,
width = function(w,h) return w/2 end,
height = function(w,h) return (h-64-128)/2 end
- },
- LowerRight = {
+ },
+ LowerRight = {
id = 7,
pos_x = function(w,h) return w/2 end,
pos_y = function(w,h) return (h-64-128/2)+64 end,
width = function(w,h) return w/2 end,
height = function(w,h) return (h-64-128)/2 end
- },
- SysApp = {
+ },
+ SysApp = {
id = 8,
pos_x = 0,
pos_y = 64,
width = function(w,h) return w end,
height = function(w,h) return h-64-128 end
- },
- ["SysApp.Left"] = {
+ },
+ ["SysApp.Left"] = {
id = 9,
pos_x = 0,
pos_y = 64,
width = function(w,h) return w/2-181 end,
height = function(w,h) return h-64-128 end
- },
- ["SysApp.Right"] = {
+ },
+ ["SysApp.Right"] = {
id = 10,
pos_x = function(w,h) return w/2+181 end,
pos_y = 64,
width = function(w,h) return w/2-181 end,
height = function(w,h) return h-64-128 end
- },
+ },
+ MobileFull = {
+ id = 11,
+ pos_x = 0,
+ pos_y = 64,
+ width = function(w,h) return w end,
+ height = function(w,h) return h-64-128 end
+ },
+ MobileUpper = {
+ id = 12,
+ pos_x = 0,
+ pos_y = 64,
+ width = function(w,h) return w end,
+ height = function(w,h) return (h-64-128)/2 end
+ },
+ MobileLower = {
+ id = 13,
+ pos_x = 0,
+ pos_y = function(w,h) return (h-64-128)/2+64 end,
+ width = function(w,h) return w end,
+ height = function(w,h) return (h-64-128)/2 end
+ },
+ Control = {
+ id = 14,
+ pos_x = 0,
+ pos_y = function(w,h) return h-128 end,
+ width = function(w,h) return w end,
+ height = 128
+ },
}
- },
- { name = "Mid",
- id = 1
- }
-
+ }
},
- layers = { { 0, "Background" , 1 },
- { 1, "Application" , 2 },
- { 2, "Softkeyboard" , 4 },
- { 3, "HomeScreen" , 2 },
- { 4, "ControlBar" , 2 },
- { 5, "InterruptApp" , 2 },
- { 6, "OnScreen" , 2 },
- { 101, "Input" , 3 },
- { 102, "Touch" , 4 },
- { 103, "Cursor" , 5 },
- { 0x1000, "Background" , 1 },
- { 0x2000, "Normal" , 2 },
- { 0x3000, "Fullscreen" , 2 },
- { 0x4000, "InputPanel" , 3 },
- { 0xA000, "Touch" , 4 },
- { 0xB000, "Cursor" , 5 },
- { 0xC000, "Startup" , 6 }
+ -- id name type output
+ layers = { { 0, "BackGround" , 1, "Center" },
+ { 1, "Application" , 2, "Center" },
+ { 2, "HomeScreen" , 3, "Center" },
+ { 3, "ControlBar" , 3, "Center" },
+ { 4, "InterruptApp" , 4, "Center" },
+ { 5, "OnScreen" , 5, "Center" },
+ { 6, "Touch" , 102, "Center" },
+ { 7, "Cursor" , 103, "Center" }
},
+ manager_update = function(self, oper)
+ if verbose > 0 then
+ print("### <== WINDOW MANAGER UPDATE:" ..
+ window_manager_operation_name(oper))
+ end
+ if oper == 1 then
+ local wumask = window_mask { --raise = true,
+ visible = true,
+ active = true }
+ local wrmask = window_mask { raise = true,
+ active = true,
+ layer = true }
+ local lumask = layer_mask { visible = true }
+ local lrmask = layer_mask { visible = true }
+ local req = m:JSON({
+ passthrough_window_update = wumask:tointeger(),
+ passthrough_window_request = wrmask:tointeger(),
+ passthrough_layer_update = lumask:tointeger(),
+ passthrough_layer_request = lrmask:tointeger()
+ })
+ self:manager_request(req)
+ end
+ end,
+
window_update = function(self, oper, win, mask)
- if (verbose) then
- print("*** WINDOW UPDATE oper:"..window_operation_name(oper).." mask: "..tostring(mask))
- print(win)
+ if verbose > 0 then
+ print("### <== WINDOW UPDATE oper:" ..
+ window_operation_name(oper) ..
+ " mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(win)
+ end
end
local arg = m:JSON({ surface = win.surface,
- winname = win.name,
+ winname = win.name
})
local command = 0
if oper == 1 then -- create
- if win.layertype and win.layertype == 3 then
- print("ignoring input panel window creation")
+ local layertype = win.layertype
+ if layertype and input_layer[layertype] then
+ if verbose > 0 then
+ print("ignoring input panel creation")
+ end
return
end
command = 0x10001
elseif oper == 2 then -- destroy
command = 0x10002
elseif oper == 3 then -- namechange
+ command = 0x10010
+ elseif oper == 4 or oper == 5 then -- visible/configure
command = 0x10009
- elseif oper == 4 or oper == 5 then --visible or configure
- command = 0x10008
arg.zone = win.area
arg.node = win.node
+ if win.layertype then
+ arg.layertype = win.layertype
+ end
arg.layer = win.layer
arg.pos_x = win.pos_x
arg.pos_y = win.pos_y
arg.height = win.height
arg.raise = win.raise
arg.visible = win.visible
- arg.active = win.active
+ if win.active == 0 then
+ arg.active = 0
+ else
+ arg.active = 1
+ end
elseif oper == 6 then -- active
- if false and win.active ~= 0 then
- print("### already active")
+ if win.active == 0 then
+ if verbose > 0 then
+ print("ignoring inactive event")
+ end
+ return
+ end
+ command = 0x10007
+ elseif oper == 7 then -- map
+ local map = win.map
+ if not map then
return
end
- command = 0x10006
+ if win.mapped == 0 then
+ command = 0x10021
+ else
+ command = 0x10020
+ end
+ arg.attr = map.type
+ --arg.name = map.target
+ arg.width = map.width
+ arg.height = map.height
+ arg.stride = map.stride
+ arg.format = map.format
else
- print("### nothing to do")
+ if verbose > 0 then
+ print("### nothing to do")
+ end
return
end
pid = win.pid,
arg = arg
})
- print("### sending window message: " .. command_name(msg.command))
- print(msg)
- sc:send_message(msg.appid, msg)
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(msg.command) ..
+ " window message to '" .. homescreen .. "'")
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ sc:send_message(homescreen, msg)
- if (oper == 1) then -- create
- local a = animation({})
- local r = m:JSON({surface = win.surface,
- visible = 1,
- raise = 1})
- self:window_request(r,a,0)
+ if oper == 1 then -- create
+ local i = input_layer[win.layertype]
+ local p = self:application(win.appid)
+ local s = p.privileges.screen
+
+ if s == "system" then
+ local a = animation({})
+ local r = m:JSON({surface = win.surface,
+ visible = 0,
+ raise = 1})
+ self:window_request(r,a,0)
+ else
+ if i then
+ if verbose > 0 then
+ print("do not make resource for " ..
+ "input window")
+ end
+ else
+ resclnt:resource_set_create("screen",
+ "driver",
+ win.appid,
+ win.surface)
+ special_screen_sets[win.surface] = true
+ end
+ end
+
+ if onscreen and win.appid == onscreen then
+ local resmsg = m:JSON({
+ command = 0x40006, -- window_id_res
+ appid = win.appid,
+ pid = win.pid,
+ res = m:JSON({
+ window = m:JSON({
+ ECU = "",
+ display = "",
+ layer = "",
+ layout = "",
+ area = "",
+ dispatchApp = "",
+ role = win.name,
+ resourceId = win.surface
+ })
+ })
+ })
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(resmsg.command) ..
+ " message to '" .. onscreen .. "'")
+ if verbose > 1 then
+ print(resmsg)
+ end
+ end
+ sc:send_message(onscreen, resmsg);
+ end
+ elseif oper == 2 then -- destroy
+ resclnt:resource_set_destroy("screen", win.surface)
+ special_screen_sets[win.surface] = nil
+ elseif oper == 6 then -- active
+ if win.active then
+ local i = input_layer[win.layertype]
+ local p = self:application(win.appid)
+ local s = p.privileges.screen
+ local surface = win.surface
+ if not i and s ~= "system" then
+ resclnt:resource_set_acquire("screen",surface)
+ resmgr:window_raise(win.appid, surface, 1)
+ end
+ end
end
end,
- layer_update = function(self, oper, j, mask)
- if verbose then
- print("*** LAYER UPDATE oper:"..oper.." mask: "..tostring(mask))
- print(j)
+ layer_update = function(self, oper, layer, mask)
+ if verbose > 0 then
+ print("### LAYER UPDATE:" ..
+ layer_operation_name(oper) ..
+ " mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(layer)
+ end
+ end
+ if oper == 3 then -- visible
+ local command = 0x10008 -- change_layer
+ local msg = m:JSON({
+ command = command,
+ appid = "",
+ arg = m:JSON({layer = layer.id,
+ visible = layer.visible
+ })
+ })
+ if verbose > 0 then
+ print("### <== sending "..command_name(command)..
+ " layer message")
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ sc:send_message(homescreen, msg)
+ else
+ if verbose > 0 then
+ print("### nothing to do")
+ end
end
end,
+
output_update = function(self, oper, out, mask)
local idx = out.index
- if verbose then
- print("*** OUTPUT UPDATE oper:"..oper.." mask: "..tostring(mask))
+ local defidx = self.output_order[idx+1]
+ if verbose > 0 then
+ print("### OUTPUT UPDATE:" .. oper ..
+ " mask: "..tostring(mask))
+ end
+ if not defidx then
+ return
end
print(out)
+ local outdef = self.outputs[defidx+1]
if (oper == 1) then -- create
- local outdef = self.outputs[idx+1]
if outdef then
self:output_request(m:JSON({index = idx,
id = outdef.id,
}))
end
elseif (oper == 5) then -- done
- local ads = self.outputs[idx+1].areas
+ local ads = outdef.areas
+ local on = outdef.name
if ads then
- for name,area in pairs(ads) do
- local a = m:JSON({name=name,output=out.index})
- for fld,val in pairs(area) do
- a[fld] = self:geometry(out.width,out.height,val)
+ for name,ad in pairs(ads) do
+ local can = wmgr:canonical_name(on.."."..name)
+ local a = m:JSON({name = name,
+ output = out.index})
+ for fld,val in pairs(ad) do
+ a[fld] = self:geometry(out.width,
+ out.height,
+ val)
end
self:area_create(a)
+ resmgr:area_create(area[can], outdef.zone)
end
end
end
end
-})
+}
+
+
+imgr = input_manager {
+ inputs = {{ name = "G27 Racing Wheel",
+ id = 0,
+ switch = { [2] = {appid="org.tizen.ico.app-soundsample" },
+ [3] = {appid="org.tizen.ico.homescreen", keycode=1},
+ [4] = {appid="org.tizen.ico.app-soundsample" },
+ [5] = {appid="org.tizen.ico.homescreen", keycode=2}
+ }}
+ },
+ manager_update = function(self, oper)
+ if verbose > 0 then
+ print("### <== INPUT MANAGER UPDATE:" ..
+ input_manager_operation_name(oper))
+ end
+ end,
+
+ input_update = function(self, oper, inp, mask)
+ if verbose > 0 then
+ print("### INPUT UPDATE:" ..
+ input_operation_name(oper) ..
+ " mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(inp)
+ end
+ end
+ end,
+ code_update = function(self, oper, code, mask)
+ if verbose > 0 then
+ print("### CODE UPDATE: mask: " .. tostring(mask))
+ if verbose > 1 then
+ print(code)
+ end
+ end
+ local msg = m:JSON({ command = 1,
+ appid = "org.tizen.ico.homescreen",
+ arg = m:JSON({ device = code.device,
+ time = code.time,
+ input = code.input,
+ code = code.id,
+ state = code.state
+ })
+ })
+ if verbose > 0 then
+ print("### <== sending " ..
+ command_name(msg.command) ..
+ " input message")
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ sc:send_message(homescreen, msg)
+ end
+}
sc = m:get_system_controller()
+-- resource sets
+sets = {}
+
+-- special screen resource sets
+-- TODO: just rewrite screen resource handling to use regular resource API
+
+special_screen_sets = {}
+
+-- user manager
+um = m:UserManager()
+
connected = false
+homescreen = ""
+onscreen = ""
+
+cids = {}
-- these shoud be before wmgr:connect() is called
-print("====== creating applications")
+if verbose > 0 then
+ print("====== creating applications ======")
+end
+application {
+ appid = "default",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
+}
+
+application {
+ appid = "weston",
+ area = "Center.Full",
+ privileges = { screen = "system", audio = "none" },
+ resource_class = "implicit",
+ screen_priority = 30
+}
+
+application {
+ appid = "org.tizen.ico.homescreen",
+ area = "Center.Full",
+ windows = { {'ico_hs_controlbarwindow', 'Center.Control'} },
+ privileges = { screen = "system", audio = "system" },
+ resource_class = "player",
+ screen_priority = 20
+}
+
+application {
+ appid = "org.tizen.ico.statusbar",
+ area = "Center.Status",
+ privileges = { screen = "system", audio = "none" },
+ resource_class = "player",
+ screen_priority = 20
+}
+
+application {
+ appid = "org.tizen.ico.onscreen",
+ area = "Center.Full",
+ privileges = { screen = "system", audio = "system" },
+ resource_class = "player",
+ screen_priority = 20
+}
+
+application {
+ appid = "org.tizen.ico.login",
+ area = "Center.Full",
+ privileges = { screen = "system", audio = "system" },
+ resource_class = "player",
+ screen_priority = 20
+}
+
+application {
+ appid = "org.tizen.ico.camera_left",
+ area = "Center.SysApp.Left",
+ privileges = { screen = "system", audio = "none" },
+ requisites = { screen = "blinker_left", audio = "none" },
+ resource_class = "player",
+ screen_priority = 30
+}
+
+application {
+ appid = "org.tizen.ico.camera_right",
+ area = "Center.SysApp.Right",
+ privileges = { screen = "system", audio = "none" },
+ requisites = { screen = "blinker_right", audio = "none" },
+ resource_class = "player",
+ screen_priority = 30
+}
+
+application {
+ appid = "net.zmap.navi",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ resource_class = "navigator",
+ screen_priority = 30
+}
+
+application {
+ appid = "GV3ySIINq7.GhostCluster",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ resource_class = "system",
+ requisites = { screen = "driving", audio = "none" },
+ screen_priority = 30
+}
+
+application {
+ appid = "MediaPlayer",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ requisites = { screen = "driving", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
+}
+
application {
- appid = "default",
- area = "Center.Full",
- privileges = { screen = "none", audio = "none" }
+ appid = "MyMediaPlayer",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ requisites = { screen = "driving", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
}
application {
- appid = "org.tizen.ico.homescreen",
- area = "Center.Full",
- privileges = { screen = "system", audio = "system" }
+ appid = "MeterWidget",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ requisites = { screen = "driving", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
}
application {
- appid = "org.tizen.ico.statusbar",
- area = "Center.Status",
- privileges = { screen = "system", audio = "none" }
+ appid = "org.tizen.ico.app-soundsample",
+ area = "Center.Full",
+ privileges = { screen = "none", audio = "none" },
+ -- uncomment the next line to make the app exempt from regulation
+ -- requisites = { screen = "driving", audio = "none" },
+ resource_class = "player",
+ screen_priority = 0
}
if sc then
sc.client_handler = function (self, cid, msg)
- print('*** client handler: ' .. tostring(msg))
- if not connected then
- print('Trying to connect to wayland...')
- connected = wmgr:connect()
- else
- print('Window manager already connected...')
+ local command = msg.command
+ local appid = msg.appid
+ if verbose > 0 then
+ print('### ==> client handler:')
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+
+ -- known commands: 1 for SEND_APPID, synthetic command 0xFFFF for
+ -- disconnection
+
+ if command == 0xFFFF then
+ if verbose > 1 then
+ print('client ' .. cid .. ' disconnected')
+ end
+ if msg.appid == homescreen then
+ homescreen = ""
+ for i,v in pairs(special_screen_sets) do
+ resclnt:resource_set_destroy("screen", i)
+ special_screen_sets[i] = nil
+ end
+ end
+ return
+ end
+
+ -- handle the connection to weston
+
+ if appid then
+ if appid == "org.tizen.ico.homescreen" then
+ print('Setting homescreen='..appid)
+ homescreen = appid
+ if command and command == 1 then
+ send_driving_mode_to(homescreen)
+ send_night_mode_to(homescreen)
+ end
+ elseif appid == "org.tizen.ico.onscreen" then
+ onscreen = appid
+ if command and command == 1 then
+ send_driving_mode_to(onscreen)
+ send_night_mode_to(onscreen)
+ end
+ end
+
+ if not connected and appid == "org.tizen.ico.homescreen" then
+ print('Trying to connect to weston...')
+ connected = wmgr:connect()
+ end
+ cids[cid] = appid
end
end
sc.generic_handler = function (self, cid, msg)
- print('*** generic handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> generic handler:')
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
sc.window_handler = function (self, cid, msg)
- print('*** window handler: ' .. command_name(msg.command) .. ' ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> received ' ..
+ command_name(msg.command) .. ' message from ' .. cids[cid])
+ if verbose > 1 then
+ print(tostring(msg))
+ end
+ end
local a = animation({})
+ local nores = false
if msg.command == 0x10003 then -- ico SHOW command
local raise_mask = 0x01000000
local lower_mask = 0x02000000
+ local nores_mask = 0x40000000
+ local time_mask = 0x00ffffff
msg.arg.visible = 1
- if msg.arg and msg.arg.anim_name then
- local time = msg.arg.time
- time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
- time = 200
- if m:AND(msg.arg.anim_time, raise_mask) then
- msg.arg.raise = 1
- elseif m:AND(msg.arg.anim_time, lower_mask) then
- msg.arg.raise = 0
+ if msg.arg then
+ local time = 200
+ if msg.arg.anim_time then
+ local t = msg.arg.anim_time
+ -- the actual time for the animation
+ time = m:AND(t, time_mask)
+ -- flag for ignoring resource control
+ nores = m:AND(t, nores_mask)
+ if m:AND(t, raise_mask) then
+ msg.arg.raise = 1
+ elseif m:AND(t, lower_mask) then
+ msg.arg.raise = 0
+ end
+ end
+ if msg.arg.anim_name then
+ a.show = { msg.arg.anim_name, time }
+ print('time: ' .. tostring(time))
end
- a.show = { msg.arg.anim_name, time }
- print('time: ' .. tostring(a.show[2]))
end
- print('##### SHOW')
- print(tostring(msg.arg))
- wmgr:window_request(msg.arg, a, 0)
+ if not nores then
+ local p = wmgr:application(msg.appid)
+ local s = p.privileges.screen
+ if s == "system" then
+ nores = true
+ if not msg.arg.raise then
+ msg.arg.raise = 1
+ end
+ end
+ end
+ if verbose > 2 then
+ print('### ==> SHOW')
+ print(tostring(msg.arg))
+ end
+ if nores then
+ wmgr:window_request(msg.arg, a, 0)
+ else
+ local surface = msg.arg.surface
+ resclnt:resource_set_acquire("screen", surface)
+ resmgr:window_raise(msg.appid, surface, 1)
+ end
elseif msg.command == 0x10004 then -- ico HIDE command
local raise_mask = 0x01000000
local lower_mask = 0x02000000
+ local nores_mask = 0x40000000
+ local time_mask = 0x00ffffff
msg.arg.visible = 0
- if msg.arg and msg.arg.anim_name then
- local time = msg.arg.time
- time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
- time = 200
- if m:AND(msg.arg.anim_time, raise_mask) then
- msg.arg.raise = 1
+ if msg.arg then
+ local time = 200
+ if msg.arg.anim_time then
+ local t = msg.arg.anim_time
+ -- the actual time for the animation
+ time = m:AND(t, time_mask)
+ -- flag for ignoring resource control
+ nores = m:AND(t, nores_mask)
+ end
+ if msg.arg.anim_name then
+ a.hide = { msg.arg.anim_name, time }
+ print('hide animation time: ' .. tostring(a.hide[2]))
end
- if m:AND(msg.arg.anim_time, lower_mask) then
+ end
+ if not nores then
+ local p = wmgr:application(msg.appid)
+ local s = p.privileges.screen
+ if s == "system" then
+ nores = true
msg.arg.raise = 0
end
- a.hide = { msg.arg.anim_name, time }
- print('hide animation time: ' .. tostring(a.hide[2]))
end
- print('##### HIDE')
- print(tostring(msg.arg))
- wmgr:window_request(msg.arg, a, 0)
+ if verbose > 2 then
+ print('### ==> HIDE REQUEST')
+ print(tostring(msg.arg))
+ end
+ if nores then
+ wmgr:window_request(msg.arg, a, 0)
+ else
+ resmgr:window_raise(msg.appid, msg.arg.surface, -1)
+ end
elseif msg.command == 0x10005 then -- ico MOVE
- print('##### MOVE')
- print(tostring(msg.arg))
+ if verbose > 2 then
+ print('### ==> MOVE REQUEST')
+ print(tostring(msg.arg))
+ end
+ if msg.arg.zone then
+ msg.arg.area = msg.arg.zone
+ end
wmgr:window_request(msg.arg, a, 0)
- elseif msg.command == 0x10006 then -- ico ACTIVE
- print('##### ACTIVE')
+ -- TODO: handle if area changed
+ elseif msg.command == 0x10007 then -- ico CHANGE_ACTIVE
if not msg.arg.active then
- msg.arg.active = 0
+ msg.arg.active = 3 -- pointer + keyboard
+ end
+ if verbose > 2 then
+ print('### ==> CHANGE_ACTIVE REQUEST')
+ print(tostring(msg.arg))
end
- print(tostring(msg.arg))
wmgr:window_request(msg.arg, a, 0)
- elseif msg.command == 0x10007 then -- ico CHANGE_LAYER
- print('##### CHANGE_LAYER')
- print(tostring(msg.arg))
+ elseif msg.command == 0x10008 then -- ico CHANGE_LAYER
+ if verbose > 2 then
+ print('### ==> CHANGE_LAYER REQUEST')
+ print(tostring(msg.arg))
+ end
--[[
if msg.arg.layer ~= 4 or msg.arg.layer ~= 5 then
print("do not change layer for other than cursor or touch")
end
--]]
wmgr:window_request(msg.arg, a, 0)
- elseif msg.command == 0x10011 then -- ico MAP_THUMB
+ elseif msg.command == 0x10020 then -- ico MAP_THUMB
local framerate = msg.arg.framerate
- print('##### MAP_THUMB')
- msg.arg.map = 1
- if not framerate or framerate < 0 then
- framerate = 0
- end
- wmgr:window_request(msg.arg, a, framerate)
- elseif msg.command == 0x10012 then -- ico UNMAP_THUMB
- print('##### UNMAP_THUMB')
- msg.arg.map = 0
+ local animname = msg.arg.anim_name
+ if animname then
+ a.map = { animname, 1 }
+ if not framerate or framerate < 0 then
+ framerate = 5
+ end
+ msg.arg.mapped = 1
+ if verbose > 2 then
+ print('### ==> MAP_THUMB REQUEST')
+ print(msg.arg)
+ print('framerate: '..framerate)
+ end
+ wmgr:window_request(msg.arg, a, framerate)
+ end
+ elseif msg.command == 0x10021 then -- ico UNMAP_THUMB
+ msg.arg.mapped = 0
+ if verbose > 2 then
+ print('### ==> UNMAP_THUMB REQUEST')
+ print(msg.arg)
+ end
wmgr:window_request(msg.arg, a, 0)
- elseif msg.command == 0x10020 then -- ico SHOW_LAYER command
+--[[
+ elseif msg.command == 0x10013 then -- ico MAP_BUFFER command
+ local shmname = msg.arg.anim_name
+ local bufsize = msg.arg.width
+ local bufnum = msg.arg.height
+ if shmname and bufsize and bufnum then
+ if verbose > 2 then
+ print('### ==> MAP_BUFFER REQUEST')
+ print("shmaname='" .. shmname ..
+ "' bufsize='" .. bufsize ..
+ " bufnum=" .. bufnum)
+ end
+ wmgr:buffer_request(shmname, bufsize, bufnum)
+ end
+--]]
+ elseif msg.command == 0x10030 then -- ico SHOW_LAYER command
msg.arg.visible = 1
- print('##### SHOW_LAYER')
+ if verbose > 2 then
+ print('### ==> SHOW_LAYER REQUEST')
+ print(msg.arg)
+ end
+ wmgr:layer_request(msg.arg)
+ elseif msg.command == 0x10031 then -- ico HIDE_LAYER command
+ msg.arg.visible = 0
+ if verbose > 2 then
+ print('### ==> HIDE_LAYER REQUEST')
+ print(msg.arg)
+ end
wmgr:layer_request(msg.arg)
end
end
+
sc.input_handler = function (self, cid, msg)
- print('*** input handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> input handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ if msg.command == 0x20001 then -- add_input
+ msg.arg.appid = msg.appid
+ if verbose > 2 then
+ print('### ==> ADD_INPUT REQUEST')
+ print(tostring(msg.arg))
+ end
+ imgr:input_request(msg.arg)
+ elseif msg.command == 0x20002 then -- del_input
+ msg.arg.appid = ''
+ if verbose > 2 then
+ print('### ==> DEL_INPUT REQUEST')
+ print(tostring(msg.arg))
+ end
+ imgr:input_request(msg.arg)
+ -- elseif msg.command == 0x20003 then -- send_input
+ end
end
+
sc.user_handler = function (self, cid, msg)
- print('*** user handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> user handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+
+ if not um then
+ print("User Manager not initialized")
+ return
+ end
+
+ if msg.command == 0x30001 then -- change_user
+ print("command CHANGE_USER")
+ if not msg.arg then
+ print("invalid message")
+ return
+ end
+
+ username = msg.arg.user
+ passwd = msg.arg.pass
+
+ if not username then
+ username = ""
+ end
+
+ if not passwd then
+ passwd = ""
+ end
+
+ success = um:changeUser(username, passwd)
+
+ if not success then
+ reply = m.JSON({
+ appid = msg.appid,
+ command = cmd
+ })
+ if sc:send_message(msg.appid, reply) then
+ print('*** sent authentication failed message')
+ else
+ print('*** failed to send authentication failed message')
+ end
+ end
+
+ elseif msg.command == 0x30002 then -- get_userlist
+ print("command GET_USERLIST")
+ if not msg.appid then
+ print("invalid message")
+ return
+ end
+
+ users, currentUser = um:getUserList()
+
+ if not users then
+ print("failed to get user list")
+ return
+ end
+
+ nUsers = 0
+
+ for i,v in pairs(users) do
+ nUsers = nUsers + 1
+ end
+
+ if not currentUser then
+ currentUser = ""
+ end
+
+ if verbose > 1 then
+ print("current user: " .. currentUser)
+ print("user list:")
+ for i,v in pairs(users) do
+ print(v)
+ end
+ end
+
+ reply = m.JSON({
+ appid = msg.appid,
+ command = cmd,
+ arg = m.JSON({
+ user_num = nUsers,
+ user_list = users,
+ user_login = currentUser
+ })
+ })
+
+ if verbose > 1 then
+ print("### <== GetUserList reply: " .. tostring(reply))
+ end
+
+ if sc:send_message(msg.appid, reply) then
+ print('*** reply OK')
+ else
+ print('*** reply FAILED')
+ end
+
+ elseif msg.command == 0x30003 then -- get_lastinfo
+ print("command GET_LASTINFO")
+ if not msg.appid then
+ print("invalid message")
+ return
+ end
+
+ lastInfo = um:getLastInfo(msg.appid)
+
+ if not lastInfo then
+ print("failed to get last info for app" .. msg.appid)
+ return
+ end
+
+ reply = m.JSON({
+ appid = msg.appid,
+ command = cmd,
+ arg = m.JSON({
+ lastinfo = lastinfo
+ })
+ })
+
+ if sc:send_message(msg.appid, reply) then
+ print('*** reply OK')
+ else
+ print('*** reply FAILED')
+ end
+
+ elseif msg.command == 0x30004 then -- set_lastinfo
+ print("command SET_LASTINFO")
+ if not msg.arg or not msg.appid then
+ print("invalid message")
+ return
+ end
+
+ lastInfo = um:setLastInfo(msg.appid, msg.arg.lastinfo)
+ end
end
+
sc.resource_handler = function (self, cid, msg)
- print('*** resource handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('### ==> resource handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+
+ getKey = function (msg)
+ -- Field rset.key is an id for distinguishing between rsets. All
+ -- resource types appear to contain a different key. Just pick one
+ -- based on what we have on the message.
+
+ key = nil
+
+ if msg and msg.res then
+ if msg.res.sound then
+ key = msg.res.sound.id
+ elseif msg.res.input then
+ key = msg.res.input.name
+ elseif msg.res.window then
+ -- alarm! this appars to be non-unique?
+ key = msg.res.window.resourceId
+ end
+ end
+
+ return key
+ end
- reply = m.JSON({ command = 'reply to client #' .. tostring(cid) })
+ createResourceSet = function (ctl, client, msg)
+ cb = function(rset)
- if sc:send_message(self, cid, reply) then
- print('*** reply OK')
- else
- print('*** reply FAILED')
+ -- m:info("*** resource_cb: client = '" .. msg.appid .. "'")
+
+ -- type is either basic (0) or interrupt (1)
+ requestType = 0
+ if msg.res.type then
+ requestType = msg.res.type
+ end
+
+ if rset.data.filter_first then
+ rset.data.filter_first = false
+ return
+ end
+
+ if rset.acquired then
+ cmd = 0x00040001 -- acquire
+
+ if msg.appid == onscreen then
+ -- notifications are valid only for a number of seconds
+ rset.timer = m:Timer({
+ interval = 5000,
+ oneshot = true,
+ callback = function (t)
+ m:info("notification timer expired")
+
+ if rset.data then
+ reply.res.window = rset.data.window
+ end
+
+ rset:release()
+ rset.timer = nil
+
+ -- Send a "RELEASE" message to client.
+ -- This triggers the resource deletion
+ -- cycle in OnScreen.
+
+ reply = m.JSON({
+ appid = msg.appid,
+ command = cmd,
+ res = {
+ type = requestType
+ }
+ })
+
+ sc:send_message(client, reply)
+ end
+ })
+ end
+ else
+ cmd = 0x00040002 -- release
+ if rset.timer then
+ rset.timer.callback = nil
+ rset.timer = nil
+ end
+ end
+
+ reply = m.JSON({
+ appid = msg.appid,
+ command = cmd,
+ res = {
+ type = requestType
+ }
+ })
+
+ if rset.data.sound then
+ reply.res.sound = rset.data.sound
+ end
+
+ if rset.data.window then
+ reply.res.window = rset.data.window
+ end
+
+ if rset.data.input then
+ reply.res.input = rset.data.input
+ end
+
+ if rset.acquired then
+ m:info("resource cb: 'acquire' reply to client " .. client)
+ else
+ m:info("resource cb: 'release' reply to client " .. client)
+ end
+
+ if not sc:send_message(client, reply) then
+ m:info('*** reply FAILED')
+ end
+ end
+
+ local rset = m:ResourceSet({
+ application_class = "player",
+ zone = "driver", -- msg.zone ("full")
+ callback = cb
+ })
+
+ rset.data = {
+ cid = cid,
+ ctl = ctl,
+ filter_first = true
+ }
+
+ if msg.res.sound then
+ rset:addResource({
+ resource_name = "audio_playback"
+ })
+ rset.resources.audio_playback.attributes.pid = tostring(msg.pid)
+ rset.resources.audio_playback.attributes.appid = msg.appid
+ print("sound name: " .. msg.res.sound.name)
+ print("sound zone:" .. msg.res.sound.zone)
+ print("sound adjust: " .. tostring(msg.res.sound.adjust))
+
+ rset.data.sound = msg.res.sound
+ end
+
+ if msg.res.input then
+ rset:addResource({
+ resource_name = "input"
+ })
+ rset.resources.input.attributes.pid = tostring(msg.pid)
+ rset.resources.input.attributes.appid = msg.appid
+ print("input name: " .. msg.res.input.name)
+ print("input event:" .. tostring(msg.res.input.event))
+
+ rset.data.input = msg.res.input
+ end
+
+ if msg.res.window then
+ rset:addResource({
+ resource_name = "screen",
+ shared = true
+ })
+ rset.resources.screen.attributes.pid = tostring(msg.pid)
+ rset.resources.screen.attributes.appid = msg.appid
+ rset.resources.screen.attributes.surface = msg.res.window.resourceId
+ complete_area = msg.res.window.display .. '.' .. msg.res.window.area
+ rset.resources.screen.attributes.area = complete_area
+ if msg.appid == onscreen then
+ rset.resources.screen.attributes.classpri = 1
+ else
+ rset.resources.screen.attributes.classpri = 0
+ end
+
+ rset.data.window = msg.res.window
+ end
+
+ rset.key = getKey(msg)
+
+ return rset
+ end
+
+ -- parse the message
+
+ -- fields common to all messages:
+ -- msg.command
+ -- msg.appid
+ -- msg.pid
+
+ if msg.command == 0x40011 then -- create_res
+ print("command CREATE_RES")
+ key = getKey(msg)
+
+ if key then
+ if not sets.cid then
+ sets.cid = {}
+ end
+ sets.cid[key] = createResourceSet(self, cid, msg)
+ end
+
+ elseif msg.command == 0x40012 then -- destroy_res
+ print("command DESTROY_RES")
+ key = getKey(msg)
+
+ if key then
+ if sets.cid and sets.cid[key] then
+ sets.cid[key]:release()
+ sets.cid[key].timer = nil
+ sets.cid[key] = nil -- garbage collecting
+ end
+ end
+
+ elseif msg.command == 0x40001 then -- acquire_res
+ print("command ACQUIRE_RES")
+ key = getKey(msg)
+
+ if key then
+ if not sets.cid then
+ sets.cid = {}
+ end
+ if not sets.cid[key] then
+ sets.cid[key] = createResourceSet(self, cid, msg)
+ end
+ print("acquiring the resource set")
+ sets.cid[key]:acquire()
+ end
+
+ elseif msg.command == 0x40002 then -- release_res
+ print("command RELEASE_RES")
+
+ key = getKey(msg)
+
+ if key then
+ if sets.cid and sets.cid[key] then
+ sets.cid[key]:release()
+
+ if msg.appid == onscreen then
+ -- in case of OnScreen, this actually means that the
+ -- resource set is never used again; let gc do its job
+ sets.cid[key].timer = nil
+ sets.cid[key] = nil -- garbage collecting
+ end
+ end
+ end
+
+ elseif msg.command == 0x40003 then -- deprive_res
+ print("command DEPRIVE_RES")
+
+ elseif msg.command == 0x40004 then -- waiting_res
+ print("command WAITING_RES")
+
+ elseif msg.command == 0x40005 then -- revert_res
+ print("command REVERT_RES")
end
end
+
sc.inputdev_handler = function (self, cid, msg)
- print('*** inputdev handler: ' .. tostring(msg))
+ if verbose > 0 then
+ print('*** inputdev handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
+ end
+
+ sc.notify_handler = function (self, cid, msg)
+ if verbose > 0 then
+ print('### notify handler: ' .. command_name(msg.command))
+ if verbose > 1 then
+ print(msg)
+ end
+ end
end
end
+
+function send_driving_mode_to(client)
+ if client == "" then
+ return
+ end
+
+ local driving_mode = mdb.select.select_driving_mode.single_value
+
+ if not driving_mode then driving_mode = 0 end
+
+ local reply = m:JSON({ command = 0x60001,
+ arg = m:JSON({ stateid = 1,
+ state = driving_mode
+ })
+ })
+
+ if verbose > 0 then
+ print("### <== sending " .. command_name(reply.command) .. " message")
+ if verbose > 1 then
+ print(reply)
+ end
+ end
+
+ sc:send_message(client, reply)
+end
+
+function send_night_mode_to(client)
+ if client == "" then
+ return
+ end
+
+ local night_mode = mdb.select.select_night_mode.single_value
+
+ if not night_mode then night_mode = 0 end
+
+ local reply = m:JSON({ command = 0x60001,
+ arg = m:JSON({ stateid = 2,
+ state = night_mode
+ })
+ })
+
+ if verbose > 0 then
+ print("### <== sending " .. command_name(reply.command) .. " message")
+ if verbose > 1 then
+ print(reply)
+ end
+ end
+
+ sc:send_message(client, reply)
+end
+
+-- we should have 'audio_playback' defined by now
+m:try_load_plugin('telephony')