1 with_system_controller = false
5 -- try loading the various logging plugins
6 m:try_load_plugin('systemd')
7 m:try_load_plugin('dlog')
9 -- load the console plugin
10 m:try_load_plugin('console')
12 m:try_load_plugin('console.disabled', 'webconsole', {
13 address = 'wsck:127.0.0.1:3000/murphy',
14 httpdir = '/usr/share/murphy/webconsole' });
16 -- load the dbus plugin
17 if m:plugin_exists('dbus') then
21 -- load the native resource plugin
22 if m:plugin_exists('resource-native') then
23 m:load_plugin('resource-native')
24 m:info("native resource plugin loaded")
26 m:info("No native resource plugin found...")
29 -- load the dbus resource plugin
30 m:try_load_plugin('resource-dbus', {
32 dbus_service = "org.Murphy",
34 default_zone = "driver",
35 default_class = "implicit"
38 -- load the domain control plugin
39 if m:plugin_exists('domain-control') then
40 m:load_plugin('domain-control')
42 m:info("No domain-control plugin found...")
45 -- load the AMB plugin
46 if m:plugin_exists('amb') then
49 m:info("No amb plugin found...")
52 -- load the ASM resource plugin
53 if m:plugin_exists('resource-asm') then
54 m:load_plugin('resource-asm', {
56 share_mmplayer = "player:AVP,mandatory,exclusive,strict",
57 ignored_argv0 = "WebProcess"
60 m:info("No audio session manager plugin found...")
63 if m:plugin_exists('ivi-resource-manager') and not with_system_controller then
64 m:load_plugin('ivi-resource-manager')
67 -- define application classes
114 application_class { name="event" , priority=4 , modal=false, share=true , order="fifo" }
115 application_class { name="game" , priority=3 , modal=false, share=false, order="lifo" }
116 --# doesn't need to be created here, ivi-resource-manager creates it if loaded
117 --#application_class { name="basic" , priority=2 , modal=false, share=false, order="lifo" }
118 application_class { name="player" , priority=1 , modal=false, share=true , order="lifo" }
119 application_class { name="implicit" , priority=0 , modal=false, share=false, order="lifo" }
121 -- define zone attributes
123 type = {mdb.string, "common", "rw"},
124 location = {mdb.string, "anywhere", "rw"}
132 location = "front-left"
140 location = "front-right"
148 location = "back-left"
156 location = "back-right"
164 location = "back-left"
169 -- define resource classes
170 if not m:plugin_exists('ivi-resource-manager') and
171 not with_system_controller
174 name = "audio_playback",
177 role = { mdb.string, "music", "rw" },
178 pid = { mdb.string, "<unknown>", "rw" },
179 policy = { mdb.string, "relaxed", "rw" }
185 name = "audio_recording",
188 role = { mdb.string, "music" , "rw" },
189 pid = { mdb.string, "<unknown>", "rw" },
190 policy = { mdb.string, "relaxed" , "rw" }
195 name = "video_playback",
200 name = "video_recording",
204 if not m:plugin_exists('ivi-resource-manager') then
205 resource.method.veto = {
206 function(zone, rset, grant, owners)
207 rset_priority = application_class[rset.application_class].priority
209 owner_id = owners.audio_playback.resource_set
212 if (rset_priority >= 50 and owner_id ~= rset_id) then
213 print("*** resource-set "..rset_id.." - veto")
222 -- test for creating selections
224 name = "audio_owner",
225 table = "audio_playback_owner",
226 columns = {"application_class"},
227 condition = "zone_name = 'driver'"
231 name = "vehicle_speed",
232 table = "amb_vehicle_speed",
234 condition = "key = 'VehicleSpeed'"
238 name = "speed2volume",
239 inputs = { speed = mdb.select.vehicle_speed, param = 9 },
240 outputs = { mdb.table { name = "speedvol",
241 index = {"zone", "device"},
242 columns = {{"zone", mdb.string, 16},
243 {"device", mdb.string, 16},
244 {"value", mdb.floating}},
249 update = function(self)
250 speed = self.inputs.speed.single_value
252 volume = (speed - 144.0) / 7.0
256 diff = volume - self.oldvolume
257 if (diff*diff > self.inputs.param) then
258 print("*** element "..self.name.." update "..volume)
259 self.oldvolume = volume
260 mdb.table.speedvol:replace({zone = "driver", device = "speakers", value = volume})
265 -- Night mode processing chain
268 name = "exterior_brightness",
269 table = "amb_exterior_brightness",
270 columns = { "value" },
271 condition = "key = 'ExteriorBrightness'"
276 inputs = { brightness = mdb.select.exterior_brightness },
280 name = "amb_nightmode",
284 { "id", mdb.unsigned },
285 { "night_mode", mdb.unsigned }
289 update = function(self)
290 -- This is a trivial function to calculate night mode. Later, we will
291 -- need a better threshold value and hysteresis to prevent oscillation.
293 brightness = self.inputs.brightness.single_value
295 if not brightness then
299 print("*** element "..self.name.." update brightness: "..brightness)
301 if brightness > 300 then
307 print("*** resulting mode: ".. mode)
309 if not (mode == self.oldmode) then
310 mdb.table.amb_nightmode:replace({ id = 0, night_mode = mode })
318 name = "select_night_mode",
319 table = "amb_nightmode",
320 columns = { "night_mode" },
326 inputs = { owner = mdb.select.select_night_mode },
327 property = "NightMode",
329 initiate = builtin.method.amb_initiate,
330 update = builtin.method.amb_update
334 -- Driving mode processing chain
338 name = "drivingmode",
339 inputs = { speed = mdb.select.vehicle_speed },
343 name = "amb_drivingmode",
347 { "id", mdb.unsigned },
348 { "driving_mode", mdb.unsigned }
352 update = function(self)
354 speed = self.inputs.speed.single_value
366 if not (mode == self.oldmode) then
367 mdb.table.amb_drivingmode:replace({ id = 0, driving_mode = mode })
375 name = "select_driving_mode",
376 table = "amb_drivingmode",
377 columns = { "driving_mode" },
382 name = "driving_mode",
383 inputs = { owner = mdb.select.select_driving_mode },
384 property = "DrivingMode",
386 initiate = builtin.method.amb_initiate,
387 update = builtin.method.amb_update
390 -- turn signals (left, right)
394 table = "amb_turn_signal",
395 columns = { "value" },
396 condition = "key = 'TurnSignal'"
399 -- regulation (on), use "select_driving_mode"
401 -- shift position (parking, reverse, other)
404 name = "gear_position",
405 table = "amb_gear_position",
406 columns = { "value" },
407 condition = "key = 'GearPosition'"
410 -- cameras (back, front, left, right)
413 name = "camera_state",
414 inputs = { winker = mdb.select.winker, gear = mdb.select.gear_position },
418 name = "target_camera_state",
422 { "id", mdb.unsigned },
423 { "front_camera", mdb.unsigned },
424 { "back_camera", mdb.unsigned },
425 { "right_camera", mdb.unsigned },
426 { "left_camera", mdb.unsigned }
430 update = function(self)
437 if self.inputs.gear == 128 then
439 elseif self.inputs.winker == 1 then
441 elseif self.inputs.winker == 2 then
445 mdb.table.target_camera_state:replace({ id = 0, front_camera = front_camera, back_camera = back_camera, right_camera = right_camera, left_camera = left_camera })
450 -- load the telephony plugin
451 m:try_load_plugin('telephony')
454 -- system controller test setup
456 if not with_system_controller then
460 window_operation_names = {
469 function window_operation_name(oper)
470 local name = window_operation_names[oper]
471 if name then return name end
472 return "<unknown " .. tostring(oper) .. ">"
476 [0x00001] = "send_appid",
477 [0x10001] = "create",
478 [0x10002] = "destroy",
482 [0x10006] = "change_active",
483 [0x10007] = "change_layer",
484 [0x10008] = "change_attr",
486 [0x10011] = "map_thumb",
487 [0x10012] = "unmap_thumb",
488 [0x10020] = "show layer",
489 [0x10021] = "hide_layer",
490 [0x10022] = "change_layer_attr",
491 [0x20001] = "add_input",
492 [0x20002] = "del_input",
493 [0x20003] = "send_input"
496 function command_name(command)
497 local name = command_names[command]
498 if name then return name end
499 return "<unknown " .. tostring(command) .. ">"
502 wmgr = window_manager({
503 geometry = function(self, w,h, v)
504 if type(v) == "function" then
510 outputs = { { name = "Center",
516 width = function(w,h) return w end,
523 width = function(w,h) return w end,
524 height = function(w,h) return h-64-128 end
530 width = function(w,h) return w end,
531 height = function(w,h) return (h-64-128)/2 end
536 pos_y = function(w,h) return (h-64-128)/2+64 end,
537 width = function(w,h) return w end,
538 height = function(w,h) return (h-64-128)/2 end
544 width = function(w,h) return w/2 end,
545 height = function(w,h) return (h-64-128)/2 end
549 pos_x = function(w,h) return w/2 end,
551 width = function(w,h) return w/2 end,
552 height = function(w,h) return (h-64-128)/2 end
557 pos_y = function(w,h) return (h-64-128/2)+64 end,
558 width = function(w,h) return w/2 end,
559 height = function(w,h) return (h-64-128)/2 end
563 pos_x = function(w,h) return w/2 end,
564 pos_y = function(w,h) return (h-64-128/2)+64 end,
565 width = function(w,h) return w/2 end,
566 height = function(w,h) return (h-64-128)/2 end
572 width = function(w,h) return w end,
573 height = function(w,h) return h-64-128 end
579 width = function(w,h) return w/2-181 end,
580 height = function(w,h) return h-64-128 end
584 pos_x = function(w,h) return w/2+181 end,
586 width = function(w,h) return w/2-181 end,
587 height = function(w,h) return h-64-128 end
596 layers = { { 0, "Background" , 1 },
597 { 1, "Application" , 2 },
598 { 2, "Softkeyboard" , 4 },
599 { 3, "HomeScreen" , 2 },
600 { 4, "ControlBar" , 2 },
601 { 5, "InterruptApp" , 2 },
602 { 6, "OnScreen" , 2 },
603 { 101, "Input" , 3 },
604 { 102, "Touch" , 4 },
605 { 103, "Cursor" , 5 },
606 { 0x1000, "Background" , 1 },
607 { 0x2000, "Normal" , 2 },
608 { 0x3000, "Fullscreen" , 2 },
609 { 0x4000, "InputPanel" , 3 },
610 { 0xA000, "Touch" , 4 },
611 { 0xB000, "Cursor" , 5 },
612 { 0xC000, "Startup" , 6 }
616 window_update = function(self, oper, win, mask)
618 print("*** WINDOW UPDATE oper:"..window_operation_name(oper).." mask: "..tostring(mask))
622 local arg = m:JSON({ surface = win.surface,
627 if oper == 1 then -- create
628 if win.layertype and win.layertype == 3 then
629 print("ignoring input panel window creation")
633 elseif oper == 2 then -- destroy
635 elseif oper == 3 then -- namechange
637 elseif oper == 4 or oper == 5 then --visible or configure
641 arg.layer = win.layer
642 arg.pos_x = win.pos_x
643 arg.pos_y = win.pos_y
644 arg.width = win.width
645 arg.height = win.height
646 arg.raise = win.raise
647 arg.visible = win.visible
648 arg.active = win.active
649 elseif oper == 6 then -- active
650 if false and win.active ~= 0 then
651 print("### already active")
656 print("### nothing to do")
660 local msg = m:JSON({ command = command,
665 print("### sending window message: " .. command_name(msg.command))
667 sc:send_message(msg.appid, msg)
669 if (oper == 1) then -- create
670 local a = animation({})
671 local r = m:JSON({surface = win.surface,
674 self:window_request(r,a,0)
678 layer_update = function(self, oper, j, mask)
680 print("*** LAYER UPDATE oper:"..oper.." mask: "..tostring(mask))
684 output_update = function(self, oper, out, mask)
685 local idx = out.index
687 print("*** OUTPUT UPDATE oper:"..oper.." mask: "..tostring(mask))
690 if (oper == 1) then -- create
691 local outdef = self.outputs[idx+1]
693 self:output_request(m:JSON({index = idx,
698 elseif (oper == 5) then -- done
699 local ads = self.outputs[idx+1].areas
701 for name,area in pairs(ads) do
702 local a = m:JSON({name=name,output=out.index})
703 for fld,val in pairs(area) do
704 a[fld] = self:geometry(out.width,out.height,val)
714 sc = m:get_system_controller()
718 -- these shoud be before wmgr:connect() is called
719 print("====== creating applications")
722 area = "Center.Full",
723 privileges = { screen = "none", audio = "none" }
727 appid = "org.tizen.ico.homescreen",
728 area = "Center.Full",
729 privileges = { screen = "system", audio = "system" }
733 appid = "org.tizen.ico.statusbar",
734 area = "Center.Status",
735 privileges = { screen = "system", audio = "none" }
740 sc.client_handler = function (self, cid, msg)
741 print('*** client handler: ' .. tostring(msg))
742 if not connected then
743 print('Trying to connect to wayland...')
744 connected = wmgr:connect()
746 print('Window manager already connected...')
750 sc.generic_handler = function (self, cid, msg)
751 print('*** generic handler: ' .. tostring(msg))
754 sc.window_handler = function (self, cid, msg)
755 print('*** window handler: ' .. command_name(msg.command) .. ' ' .. tostring(msg))
757 local a = animation({})
758 if msg.command == 0x10003 then -- ico SHOW command
759 local raise_mask = 0x01000000
760 local lower_mask = 0x02000000
762 if msg.arg and msg.arg.anim_name then
763 local time = msg.arg.time
764 time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
766 if m:AND(msg.arg.anim_time, raise_mask) then
768 elseif m:AND(msg.arg.anim_time, lower_mask) then
771 a.show = { msg.arg.anim_name, time }
772 print('time: ' .. tostring(a.show[2]))
775 print(tostring(msg.arg))
776 wmgr:window_request(msg.arg, a, 0)
777 elseif msg.command == 0x10004 then -- ico HIDE command
778 local raise_mask = 0x01000000
779 local lower_mask = 0x02000000
781 if msg.arg and msg.arg.anim_name then
782 local time = msg.arg.time
783 time = m:AND(time, m:NEG(m:OR(raise_mask, lower_mask)))
785 if m:AND(msg.arg.anim_time, raise_mask) then
788 if m:AND(msg.arg.anim_time, lower_mask) then
791 a.hide = { msg.arg.anim_name, time }
792 print('hide animation time: ' .. tostring(a.hide[2]))
795 print(tostring(msg.arg))
796 wmgr:window_request(msg.arg, a, 0)
797 elseif msg.command == 0x10005 then -- ico MOVE
799 print(tostring(msg.arg))
800 wmgr:window_request(msg.arg, a, 0)
801 elseif msg.command == 0x10006 then -- ico ACTIVE
802 print('##### ACTIVE')
803 if not msg.arg.active then
806 print(tostring(msg.arg))
807 wmgr:window_request(msg.arg, a, 0)
808 elseif msg.command == 0x10007 then -- ico CHANGE_LAYER
809 print('##### CHANGE_LAYER')
810 print(tostring(msg.arg))
812 if msg.arg.layer ~= 4 or msg.arg.layer ~= 5 then
813 print("do not change layer for other than cursor or touch")
817 wmgr:window_request(msg.arg, a, 0)
818 elseif msg.command == 0x10011 then -- ico MAP_THUMB
819 local framerate = msg.arg.framerate
820 print('##### MAP_THUMB')
822 if not framerate or framerate < 0 then
825 wmgr:window_request(msg.arg, a, framerate)
826 elseif msg.command == 0x10012 then -- ico UNMAP_THUMB
827 print('##### UNMAP_THUMB')
829 wmgr:window_request(msg.arg, a, 0)
830 elseif msg.command == 0x10020 then -- ico SHOW_LAYER command
832 print('##### SHOW_LAYER')
833 wmgr:layer_request(msg.arg)
836 sc.input_handler = function (self, cid, msg)
837 print('*** input handler: ' .. tostring(msg))
839 sc.user_handler = function (self, cid, msg)
840 print('*** user handler: ' .. tostring(msg))
842 sc.resource_handler = function (self, cid, msg)
843 print('*** resource handler: ' .. tostring(msg))
845 reply = m.JSON({ command = 'reply to client #' .. tostring(cid) })
847 if sc:send_message(self, cid, reply) then
848 print('*** reply OK')
850 print('*** reply FAILED')
853 sc.inputdev_handler = function (self, cid, msg)
854 print('*** inputdev handler: ' .. tostring(msg))