config: dynamically check whether ico-homescreen support is available.
[profile/ivi/murphy.git] / packaging.in / murphy.lua
1 with_system_controller = false
2 with_amb = false
3 verbose = 0
4
5 m = murphy.get()
6
7 -- try loading the various logging plugins
8 m:try_load_plugin('systemd')
9 m:try_load_plugin('dlog')
10
11 -- load the console plugin
12 m:try_load_plugin('console')
13
14 m:try_load_plugin('console.disabled', 'webconsole', {
15                   address = 'wsck:127.0.0.1:3000/murphy',
16                   httpdir = '/usr/share/murphy/webconsole' });
17
18 -- load the dbus plugin
19 if m:plugin_exists('dbus') then
20     m:load_plugin('dbus')
21 end
22
23 -- load the native resource plugin
24 if m:plugin_exists('resource-native') then
25     m:load_plugin('resource-native')
26     m:info("native resource plugin loaded")
27 else
28     m:info("No native resource plugin found...")
29 end
30
31 -- load the dbus resource plugin
32 m:try_load_plugin('resource-dbus', {
33     dbus_bus = "system",
34     dbus_service = "org.Murphy",
35     dbus_track = true,
36     default_zone = "driver",
37     default_class = "implicit"
38 })
39
40 -- load the domain control plugin
41 if m:plugin_exists('domain-control') then
42     m:load_plugin('domain-control')
43 else
44     m:info("No domain-control plugin found...")
45 end
46
47 -- load the AMB plugin
48 if m:plugin_exists('amb') then
49     m:try_load_plugin('amb')
50
51     if builtin.method.amb_initiate and
52        builtin.method.amb_update
53     then
54         with_amb = true
55     end
56 else
57     m:info("No amb plugin found...")
58 end
59
60 -- load the ASM resource plugin
61 if m:plugin_exists('resource-asm') then
62     m:try_load_plugin('resource-asm', {
63         zone = "driver",
64         share_mmplayer = "player:AVP,mandatory,exclusive,strict",
65         ignored_argv0 = "WebProcess"
66     })
67 else
68     m:info("No audio session manager plugin found...")
69 end
70
71 if m:plugin_exists('system-controller') then
72     with_system_controller = true
73 elseif m:plugin_exists('ivi-resource-manager') then
74     m:load_plugin('ivi-resource-manager')
75     with_system_controller = false
76 end
77
78 -- define application classes
79 application_class {
80     name     = "interrupt",
81     priority = 99,
82     modal    = true ,
83     share    = false,
84     order    = "fifo"
85 }
86
87 application_class {
88     name     = "emergency",
89     priority = 80,
90     modal    = false,
91     share    = false,
92     order    = "fifo"
93 }
94 application_class {
95     name     = "alert",
96     priority = 51,
97     modal    = false,
98     share    = false,
99     order    = "fifo"
100 }
101
102 application_class {
103     name     = "navigator",
104     priority = 50,
105     modal    = false,
106     share    = true,
107     order    = "fifo"
108 }
109
110 application_class {
111     name     = "phone",
112     priority = 6 ,
113     modal    = false,
114     share    = true ,
115     order    = "lifo"
116 }
117 application_class {
118     name     = "camera",
119     priority = 5,
120     modal    = false,
121     share    = false,
122     order    = "lifo"
123 }
124
125 application_class { name="event"    , priority=4 , modal=false, share=true , order="fifo" }
126 application_class { name="game"     , priority=3 , modal=false, share=false, order="lifo" }
127 --# doesn't need to be created here, ivi-resource-manager creates it if loaded
128 --#application_class { name="basic"    , priority=2 , modal=false, share=false, order="lifo" }
129 application_class { name="player"   , priority=1 , modal=false, share=true , order="lifo" }
130 application_class { name="implicit" , priority=0 , modal=false, share=false, order="lifo" }
131
132 -- define zone attributes
133 zone.attributes {
134     type = {mdb.string, "common", "rw"},
135     location = {mdb.string, "anywhere", "rw"}
136 }
137
138 -- define zones
139 zone {
140      name = "driver",
141      attributes = {
142          type = "common",
143          location = "front-left"
144      }
145 }
146
147 zone {
148      name = "passanger1",
149      attributes = {
150          type = "private",
151          location = "front-right"
152      }
153 }
154
155 zone {
156      name = "passanger2",
157      attributes = {
158          type = "private",
159          location = "back-left"
160      }
161 }
162
163 zone {
164      name = "passanger3",
165      attributes = {
166          type = "private",
167          location = "back-right"
168      }
169 }
170
171 zone {
172      name = "passanger4",
173      attributes = {
174          type = "private",
175          location = "back-left"
176      }
177 }
178
179
180 -- define resource classes
181 if not m:plugin_exists('ivi-resource-manager') and
182    not with_system_controller
183 then
184    resource.class {
185         name = "audio_playback",
186         shareable = true,
187         attributes = {
188             role = { mdb.string, "music", "rw" },
189             pid = { mdb.string, "<unknown>", "rw" },
190             policy = { mdb.string, "relaxed", "rw" }
191         }
192    }
193 end
194
195 resource.class {
196      name = "audio_recording",
197      shareable = true,
198      attributes = {
199          role   = { mdb.string, "music"    , "rw" },
200          pid    = { mdb.string, "<unknown>", "rw" },
201          policy = { mdb.string, "relaxed"  , "rw" }
202      }
203 }
204
205 resource.class {
206      name = "video_playback",
207      shareable = false,
208 }
209
210 resource.class {
211      name = "video_recording",
212      shareable = false
213 }
214
215 if not m:plugin_exists('ivi-resource-manager') and
216    not with_system_controller
217 then
218     resource.method.veto = {
219         function(zone, rset, grant, owners, req_set)
220             return true
221          end
222     }
223 end
224
225 -- test for creating selections
226 mdb.select {
227            name = "audio_owner",
228            table = "audio_playback_owner",
229            columns = {"application_class"},
230            condition = "zone_name = 'driver'"
231 }
232
233 mdb.select {
234            name = "vehicle_speed",
235            table = "amb_vehicle_speed",
236            columns = {"value"},
237            condition = "key = 'VehicleSpeed'"
238 }
239
240 element.lua {
241    name    = "speed2volume",
242    inputs  = { speed = mdb.select.vehicle_speed, param = 9 },
243    outputs = {  mdb.table { name = "speedvol",
244                             index = {"zone", "device"},
245                             columns = {{"zone", mdb.string, 16},
246                                        {"device", mdb.string, 16},
247                                        {"value", mdb.floating}},
248                             create = true
249                            }
250              },
251    oldvolume = 0.0,
252    update  = function(self)
253                 speed = self.inputs.speed.single_value
254                 if (speed) then
255                     volume = (speed - 144.0) / 7.0
256                 else
257                     volume = 0.0
258                 end
259                 diff = volume - self.oldvolume
260                 if (diff*diff > self.inputs.param) then
261                     print("*** element "..self.name.." update "..volume)
262                     self.oldvolume = volume
263                     mdb.table.speedvol:replace({zone = "driver", device = "speakers", value = volume})
264                 end
265              end
266 }
267
268 -- Night mode processing chain
269
270 mdb.select {
271     name = "exterior_brightness",
272     table = "amb_exterior_brightness",
273     columns = { "value" },
274     condition = "key = 'ExteriorBrightness'"
275 }
276
277 element.lua {
278     name    = "nightmode",
279     inputs  = { brightness = mdb.select.exterior_brightness },
280     oldmode = -1;
281     outputs = {
282         mdb.table {
283             name = "amb_nightmode",
284             index = { "id" },
285             create = true,
286             columns = {
287                 { "id", mdb.unsigned },
288                 { "night_mode", mdb.unsigned }
289             }
290         }
291     },
292     update = function(self)
293         -- This is a trivial function to calculate night mode. Later, we will
294         -- need a better threshold value and hysteresis to prevent oscillation.
295
296         brightness = self.inputs.brightness.single_value
297
298         if not brightness then
299             return
300         end
301
302         print("*** element "..self.name.." update brightness: "..brightness)
303
304         if brightness > 300 then
305             mode = 0
306         else
307             mode = 1
308         end
309
310         print("*** resulting mode: ".. mode)
311
312         if not (mode == self.oldmode) then
313             mdb.table.amb_nightmode:replace({ id = 0, night_mode = mode })
314         end
315
316         self.oldmode = mode
317     end
318 }
319
320 mdb.select {
321     name = "select_night_mode",
322     table = "amb_nightmode",
323     columns = { "night_mode" },
324     condition = "id = 0"
325 }
326
327 if with_amb then
328     sink.lua {
329         name = "night_mode",
330         inputs = { owner = mdb.select.select_night_mode },
331         property = "NightMode",
332         type = "b",
333         initiate = builtin.method.amb_initiate,
334         update = builtin.method.amb_update
335     }
336 end
337
338 -- Night mode general handlers
339
340 sink.lua {
341     name = "nightmode_homescreen",
342     inputs = { owner = mdb.select.select_night_mode },
343     initiate = function(self)
344         data = mdb.select.select_night_mode.single_value
345         print("Night mode initiated: " .. tostring(data))
346         return true
347     end,
348     update = function(self)
349         data = mdb.select.select_night_mode.single_value
350         print("Night mode updated: " .. tostring(data))
351
352         -- tell homescreen that night mode was updated
353         sc:send_message(homescreen, m:JSON({command=0x60001,arg=m:JSON({stateid=2,state=data})}))
354         return true
355     end
356 }
357
358 -- Driving mode processing chain
359
360 element.lua {
361     name    = "drivingmode",
362     inputs  = { speed = mdb.select.vehicle_speed },
363     oldmode = -1;
364     outputs = {
365         mdb.table {
366             name = "amb_drivingmode",
367             index = { "id" },
368             create = true,
369             columns = {
370                 { "id", mdb.unsigned },
371                 { "driving_mode", mdb.unsigned }
372             }
373         }
374     },
375     update = function(self)
376
377         speed = self.inputs.speed.single_value
378
379         if not speed then
380             return
381         end
382
383         if speed == 0 then
384             mode = 0
385         else
386             mode = 1
387         end
388
389         if not (mode == self.oldmode) then
390             mdb.table.amb_drivingmode:replace({ id = 0, driving_mode = mode })
391         end
392
393         self.oldmode = mode
394     end
395 }
396
397 mdb.select {
398     name = "select_driving_mode",
399     table = "amb_drivingmode",
400     columns = { "driving_mode" },
401     condition = "id = 0"
402 }
403
404 if with_amb then
405     sink.lua {
406         name = "driving_mode",
407         inputs = { owner = mdb.select.select_driving_mode },
408         property = "DrivingMode",
409         type = "u",
410         initiate = builtin.method.amb_initiate,
411         update = builtin.method.amb_update
412     }
413 end
414
415 -- turn signals (left, right)
416
417 mdb.select {
418     name = "winker",
419     table = "amb_turn_signal",
420     columns = { "value" },
421     condition = "key = 'TurnSignal'"
422 }
423
424 -- regulation (on), use "select_driving_mode"
425
426 sink.lua {
427     name = "driving_regulation",
428     inputs = { owner = mdb.select.select_driving_mode },
429     initiate = function(self)
430         data = mdb.select.select_driving_mode.single_value
431         print("Driving mode initiated: " .. tostring(data))
432         return true
433     end,
434     update = function(self)
435         data = mdb.select.select_driving_mode.single_value
436         print("Driving mode updated: " .. tostring(data))
437
438         -- tell homescreen that driving mode was updated
439         sc:send_message(homescreen, m:JSON({command=0x60001,arg=m:JSON({stateid=1,state=data})}))
440         return true
441     end
442 }
443
444 -- shift position (parking, reverse, other)
445
446 mdb.select {
447     name = "gear_position",
448     table = "amb_gear_position",
449     columns = { "value" },
450     condition = "key = 'GearPosition'"
451 }
452
453 -- cameras (back, front, left, right)
454
455 element.lua {
456     name    = "camera_state",
457     inputs  = { winker = mdb.select.winker, gear = mdb.select.gear_position },
458     oldmode = -1;
459     outputs = {
460         mdb.table {
461             name = "target_camera_state",
462             index = { "id" },
463             create = true,
464             columns = {
465                 { "id", mdb.unsigned },
466                 { "front_camera", mdb.unsigned },
467                 { "back_camera", mdb.unsigned },
468                 { "right_camera", mdb.unsigned },
469                 { "left_camera", mdb.unsigned }
470             }
471         }
472     },
473     update = function(self)
474
475         front_camera = 0
476         back_camera = 0
477         right_camera = 0
478         left_camera = 0
479
480         if self.inputs.gear == 128 then
481             back_camera = 1
482         elseif self.inputs.winker == 1 then
483             right_camera = 1
484         elseif self.inputs.winker == 2 then
485             left_camera = 1
486         end
487
488         mdb.table.target_camera_state:replace({ id = 0, front_camera = front_camera, back_camera = back_camera, right_camera = right_camera, left_camera = left_camera })
489
490     end
491 }
492
493 -- load the telephony plugin
494 m:try_load_plugin('telephony')
495
496
497 -- system controller test setup
498
499 if not with_system_controller then
500    return
501 end
502
503 m:load_plugin('system-controller')
504
505 window_manager_operation_names = {
506     [1] = "create",
507     [2] = "destroy"
508 }
509
510 function window_manager_operation_name(oper)
511     local name = window_manager_operation_names[oper]
512     if name then return name end
513     return "<unknown " .. tostring(oper) .. ">"
514 end
515
516 window_operation_names = {
517     [1] = "create",
518     [2] = "destroy",
519     [3] = "name_change",
520     [4] = "visible",
521     [5] = "configure",
522     [6] = "active"
523 }
524
525 function window_operation_name(oper)
526     local name = window_operation_names[oper]
527     if name then return name end
528     return "<unknown " .. tostring(oper) .. ">"
529 end
530
531 layer_operation_names = {
532     [1] = "create",
533     [2] = "destroy",
534     [3] = "visible"
535 }
536
537 function layer_operation_name(oper)
538     local name = layer_operation_names[oper]
539     if name then return name end
540     return "<unknown " .. tostring(oper) .. ">"
541 end
542
543 input_manager_operation_names = {
544     [1] = "create",
545     [2] = "destroy",
546     [3] = "ready"
547 }
548
549 function input_manager_operation_name(oper)
550     local name = input_manager_operation_names[oper]
551     if name then return name end
552     return "<unknown " .. tostring(oper) .. ">"
553 end
554
555 input_operation_names = {
556     [1] = "create",
557     [2] = "destroy",
558     [3] = "update"
559 }
560
561 function input_operation_name(oper)
562     local name = input_operation_names[oper]
563     if name then return name end
564     return "<unknown " .. tostring(oper) .. ">"
565 end
566
567 code_operation_names = {
568     [1] = "create",
569     [2] = "destroy",
570     [3] = "state_change"
571 }
572
573 function code_operation_name(oper)
574     local name = code_operation_names[oper]
575     if name then return name end
576     return "<unknown " .. tostring(oper) .. ">"
577 end
578
579 command_names = {
580     [0x00001] = "send_appid",
581     [0x10001] = "create",
582     [0x10002] = "destroy",
583     [0x10003] = "show",
584     [0x10004] = "hide",
585     [0x10005] = "move",
586     [0x10006] = "change_active",
587     [0x10007] = "change_layer",
588     [0x10008] = "change_attr",
589     [0x10009] = "name",
590     [0x10011] = "map_thumb",
591     [0x10012] = "unmap_thumb",
592     [0x10020] = "show layer",
593     [0x10021] = "hide_layer",
594     [0x10022] = "change_layer_attr",
595     [0x20001] = "add_input",
596     [0x20002] = "del_input",
597     [0x20003] = "send_input",
598     [0x40001] = "acquire_res",
599     [0x40002] = "release_res",
600     [0x40003] = "deprive_res",
601     [0x40004] = "waiting_res",
602     [0x40005] = "revert_res",
603     [0x40011] = "create_res",
604     [0x40012] = "destroy_res",
605     [0x50001] = "set_region",
606     [0x50002] = "unset_region",
607     [0x60001] = "change_state"
608 }
609
610 function command_name(command)
611     local name = command_names[command]
612     if name then return name end
613     return "<unknown " .. tostring(command) .. ">"
614 end
615
616 input_layer = {
617    [3] = true, -- input
618    [4] = true, -- touch
619    [5] = true  -- cursor
620 }
621
622 resmgr = resource_manager {
623   screen_event_handler = function(self, ev)
624                              local event = ev.event
625                              local surface = ev.surface
626
627                              if event == "grant" then
628                                  if verbose > 0 then
629                                     print("*** make visible surface "..surface)
630                                  end
631                                  local a = animation({})
632                                  local r = m:JSON({surface = surface,
633                                                    visible = 1,
634                                                    raise   = 1})
635                                  wmgr:window_request(r,a,0)
636                                  elseif event == "revoke" then
637                                  if verbose > 0 then
638                                     print("*** hide surface "..surface)
639                                  end
640                                  local a = animation({})
641                                  local r = m:JSON({surface = ev.surface,
642                                                    visible = 0})
643                                  wmgr:window_request(r,a,0)
644                              else
645                                  if verbose > 0 then
646                                     print("*** screen resource event: " ..
647                                           tostring(ev))
648                                  end
649                              end
650                          end,
651   audio_event_handler = function(self, ev)
652                              local event = ev.event
653                              local appid = ev.appid
654                              local audioid = ev.audioid
655
656                              if event == "grant" then
657                                  if verbose > 0 or true then
658                                     print("*** grant audio to "..appid..
659                                           " ("..audioid..") in '" ..
660                                           ev.zone .. "' zone")
661                                  end
662                              elseif event == "revoke" then
663                                  if verbose > 0 or true then
664                                     print("*** revoke audio from "..appid..
665                                           " ("..audioid..") in '" ..
666                                           ev.zone .. "' zone")
667                                  end
668                              else
669                                  if verbose > 0 or true then
670                                     print("*** audio resource event: " ..
671                                           tostring(ev))
672                                  end
673                              end
674                         end
675 }
676
677 resclnt = resource_client {}
678
679 wmgr = window_manager {
680   geometry = function(self, w,h, v)
681                   if type(v) == "function" then
682                       return v(w,h)
683                   end
684                   return v
685              end,
686
687   application = function(self, appid)
688                      if appid then
689                          local app = application_lookup(appid)
690                          if not app then
691                              app = application_lookup("default")
692                          end
693                          return app
694                      end
695                      return { privileges = {screen="none", audio="none"} }
696                 end,
697
698   outputs = { { name  = "Center",
699                 id    = 0,
700                 zone  = "driver",
701                 areas = { Status = {
702                               id     = 0,
703                               pos_x  = 0,
704                               pos_y  = 0,
705                               width  = function(w,h) return w end,
706                               height = 64
707                           },
708                           Full = {
709                               id     = 1,
710                               pos_x  = 0,
711                               pos_y  = 64,
712                               width  = function(w,h) return w end,
713                               height = function(w,h) return h-64-128 end
714                           },
715                           Upper = {
716                               id     = 2,
717                               pos_x  = 0,
718                               pos_y  = 64,
719                               width  = function(w,h) return w end,
720                               height = function(w,h) return (h-64-128)/2 end
721                           },
722                           Lower = {
723                               id     = 3,
724                               pos_x  = 0,
725                               pos_y  = function(w,h) return (h-64-128)/2+64 end,
726                               width  = function(w,h) return w end,
727                               height = function(w,h) return (h-64-128)/2 end
728                           },
729                           UpperLeft = {
730                               id     = 4,
731                               pos_x  = 0,
732                               pos_y  = 64,
733                               width  = function(w,h) return w/2 end,
734                               height = function(w,h) return (h-64-128)/2 end
735                           },
736                           UpperRight = {
737                               id     = 5,
738                               pos_x  = function(w,h) return w/2 end,
739                               pos_y  = 64,
740                               width  = function(w,h) return w/2 end,
741                               height = function(w,h) return (h-64-128)/2 end
742                           },
743                           LowerLeft = {
744                               id     = 6,
745                               pos_x  = 0,
746                               pos_y  = function(w,h) return (h-64-128/2)+64 end,
747                               width  = function(w,h) return w/2 end,
748                               height = function(w,h) return (h-64-128)/2 end
749                           },
750                           LowerRight = {
751                               id     = 7,
752                               pos_x  = function(w,h) return w/2 end,
753                               pos_y  = function(w,h) return (h-64-128/2)+64 end,
754                               width  = function(w,h) return w/2 end,
755                               height = function(w,h) return (h-64-128)/2 end
756                           },
757                           SysApp = {
758                               id     = 8,
759                               pos_x  = 0,
760                               pos_y  = 64,
761                               width  = function(w,h) return w end,
762                               height = function(w,h) return h-64-128 end
763                           },
764                           ["SysApp.Left"] = {
765                               id     = 9,
766                               pos_x  = 0,
767                               pos_y  = 64,
768                               width  = function(w,h) return w/2-181 end,
769                               height = function(w,h) return h-64-128 end
770                           },
771                           ["SysApp.Right"] = {
772                               id     = 10,
773                               pos_x  = function(w,h) return w/2+181 end,
774                               pos_y  = 64,
775                               width  = function(w,h) return w/2-181 end,
776                               height = function(w,h) return h-64-128 end
777                           },
778                         }
779                },
780                { name  = "Mid",
781                  zone  = "driver",
782                  id    = 1
783                }
784
785   },
786   layers = { {      0, "Background"   , 1 },
787              {      1, "Application"  , 2 },
788              {      2, "Softkeyboard" , 4 },
789              {      3, "HomeScreen"   , 2 },
790              {      4, "ControlBar"   , 2 },
791              {      5, "InterruptApp" , 2 },
792              {      6, "OnScreen"     , 2 },
793              {    101, "Input"        , 3 },
794              {    102, "Cursor"       , 5 },
795              {    103, "Startup"      , 6 },
796              { 0x1000, "Background"   , 1 },
797              { 0x2000, "Normal"       , 2 },
798              { 0x3000, "Fullscreen"   , 2 },
799              { 0x4000, "InputPanel"   , 3 },
800              { 0xA000, "Touch"        , 4 },
801              { 0xB000, "Cursor"       , 5 },
802              { 0xC000, "Startup"      , 6 }
803   },
804
805
806   manager_update = function(self, oper)
807                        if verbose > 0 then
808                            print("### <== WINDOW MANAGER UPDATE:" ..
809                                  window_manager_operation_name(oper))
810                        end
811                        if oper == 1 then
812                            local umask = window_mask { raise   = true,
813                                                        visible = true,
814                                                        active  = true }
815                            local rmask = window_mask { active  = true }
816                            local req = m:JSON({
817                                        passthrough_update  = umask:tointeger(),
818                                        passthrough_request = rmask:tointeger()
819                            })
820                            self:manager_request(req)
821                        end
822                    end,
823
824   window_update = function(self, oper, win, mask)
825                       if verbose > 0 then
826                           print("### <== WINDOW UPDATE oper:" ..
827                                 window_operation_name(oper) ..
828                                 " mask: " .. tostring(mask))
829                           if verbose > 1 then
830                               print(win)
831                           end
832                       end
833
834                       local arg = m:JSON({ surface = win.surface,
835                                            winname = win.name,
836                       })
837                       local command = 0
838
839                       if oper == 1 then -- create
840                            local layertype = win.layertype
841                            if layertype and input_layer[layertype] then
842                                if verbose > 0 then
843                                    print("ignoring input panel creation")
844                                end
845                                return
846                            end
847                            command     = 0x10001
848                       elseif oper == 2 then -- destroy
849                            command     = 0x10002
850                       elseif oper == 3 then  -- namechange
851                            command     = 0x10009
852                       elseif oper == 4 or oper == 5 then --visible or configure
853                            command     = 0x10008
854                            arg.zone    = win.area
855                            arg.node    = win.node
856                            arg.layer   = win.layer
857                            arg.pos_x   = win.pos_x
858                            arg.pos_y   = win.pos_y
859                            arg.width   = win.width
860                            arg.height  = win.height
861                            arg.raise   = win.raise
862                            arg.visible = win.visible
863                            arg.active  = win.active
864                       elseif oper == 6 then -- active
865                            command     = 0x10006
866                            arg.active  = win.active
867                       else
868                            if verbose > 0 then
869                                print("### nothing to do")
870                            end
871                            return
872                       end
873
874                       local msg = m:JSON({ command = command,
875                                            appid   = win.appid,
876                                            pid     = win.pid,
877                                            arg     = arg
878                       })
879                       if verbose > 0 then
880                           print("### <== sending " ..
881                                 command_name(msg.command) ..
882                                 " window message to '" .. win.name .. "'")
883                           if verbose > 1 then
884                               print(msg)
885                           end
886                       end
887                       sc:send_message(homescreen, msg)
888
889                       if oper == 1 then -- create
890                           local i = input_layer[win.layertype]
891                           local p = self:application(win.appid)
892                           local s = p.privileges.screen
893
894                           if s == "system" then
895                               local a = animation({})
896                               local r = m:JSON({surface = win.surface,
897                                                 visible = 1,
898                                                 raise   = 1})
899                               self:window_request(r,a,0)
900                           else
901                               if i then
902                                   if verbose > 0 then
903                                       print("do not make resource for " ..
904                                             "input window")
905                                   end
906                               else
907                                   resclnt:resource_set_create("screen",
908                                                                "driver",
909                                                                win.appid,
910                                                                win.surface)
911                               end
912                           end
913                       elseif oper == 2 then -- destroy
914                           resclnt:resource_set_destroy("screen", win.surface)
915                       elseif oper == 6 then -- active
916                           if win.active then
917                               local i = input_layer[win.layertype]
918                               local p = self:application(win.appid)
919                               local s = p.privileges.screen
920                               local surface = win.surface
921                               if not i and s ~= "system" then
922                                  resclnt:resource_set_acquire("screen",surface)
923                                  resmgr:window_raise(win.appid, surface, 1)
924                               end
925                           end
926                       end
927                   end,
928
929   layer_update = function(self, oper, layer, mask)
930                       if verbose > 0 then
931                           print("### LAYER UPDATE:" ..
932                                 layer_operation_name(oper) ..
933                                 " mask: " .. tostring(mask))
934                           if verbose > 1 then
935                               print(layer)
936                           end
937                       end
938                       if oper == 3 then -- visible
939                          local command = 0x10022
940                          local msg = m:JSON({
941                                          command = command,
942                                          appid = "",
943                                          arg = m:JSON({layer = layer.id,
944                                                        visible = layer.visible
945                                          })
946                                 })
947                          if verbose > 0 then
948                             print("### <== sending "..command_name(command)..
949                                   " layer message")
950                             if verbose > 1 then
951                                 print(msg)
952                             end
953                          end
954                          sc:send_message(homescreen, msg)
955                       else
956                            if verbose > 0 then
957                                print("### nothing to do")
958                            end
959                       end
960                  end,
961
962   output_update = function(self, oper, out, mask)
963                       local idx = out.index
964                       if verbose > 0 then
965                           print("### OUTPUT UPDATE:" .. oper ..
966                                 " mask: "..tostring(mask))
967                       end
968                       print(out)
969                       local outdef = self.outputs[idx+1]
970                       if (oper == 1) then -- create
971                           if outdef then
972                               self:output_request(m:JSON({index = idx,
973                                                           id    = outdef.id,
974                                                           name  = outdef.name
975                                                           }))
976                           end
977                       elseif (oper == 5) then -- done
978                           local ads = outdef.areas
979                           local on = outdef.name
980                           if ads then
981                               for name,ad in pairs(ads) do
982                                   local can = wmgr:canonical_name(on.."."..name)
983                                   local a = m:JSON({name   = name,
984                                                     output = out.index})
985                                   for fld,val in pairs(ad) do
986                                       a[fld] = self:geometry(out.width,
987                                                              out.height,
988                                                              val)
989                                    end
990                                    self:area_create(a)
991                                    resmgr:area_create(area[can], outdef.zone)
992                               end
993                           end
994                       end
995                   end
996 }
997
998
999 imgr = input_manager {
1000   inputs = {{ name = "G27 Racing Wheel",
1001               id = 0,
1002               switch = { [2] = {appid="org.tizen.ico.app-soundsample"      },
1003                          [3] = {appid="org.tizen.ico.homescreen", keycode=1},
1004                          [4] = {appid="org.tizen.ico.app-soundsample"      },
1005                          [5] = {appid="org.tizen.ico.homescreen", keycode=2}
1006              }}
1007   },
1008
1009   manager_update = function(self, oper)
1010                        if verbose > 0 then
1011                            print("### <== INPUT MANAGER UPDATE:" ..
1012                                  input_manager_operation_name(oper))
1013                        end
1014                    end,
1015
1016   input_update = function(self, oper, inp, mask)
1017                      if verbose > 0 then
1018                          print("### INPUT UPDATE:" .. 
1019                                 input_operation_name(oper) ..
1020                                 " mask: " .. tostring(mask))
1021                           if verbose > 1 then
1022                               print(inp)
1023                           end
1024                       end
1025                  end,
1026   code_update  = function(self, oper, code, mask)
1027                      if verbose > 0 then
1028                          print("### CODE UPDATE: mask: " .. tostring(mask))
1029                          if verbose > 1 then
1030                              print(code)
1031                          end
1032                      end
1033                      local msg = m:JSON({ command = 1,
1034                                           appid = "org.tizen.ico.homescreen",
1035                                           arg = m:JSON({ device = code.device,
1036                                                          time = code.time,
1037                                                          input = code.input,
1038                                                          code = code.id,
1039                                                          state = code.state
1040                                            })
1041                      })
1042                      if verbose > 0 then
1043                          print("### <== sending " ..
1044                                command_name(msg.command) ..
1045                                " input message")
1046                          if verbose > 1 then
1047                              print(msg)
1048                          end
1049                      end
1050                      sc:send_message(homescreen, msg)
1051                  end
1052 }
1053
1054 sc = m:get_system_controller()
1055
1056 -- resource sets
1057 sets = {}
1058
1059 -- user manager
1060 um = m:UserManager()
1061
1062 connected = false
1063 homescreen = ""
1064
1065 -- these shoud be before wmgr:connect() is called
1066 if verbose > 0 then
1067    print("====== creating applications ======")
1068 end
1069 application {
1070     appid          = "default",
1071     area           = "Center.Full",
1072     privileges     = { screen = "none", audio = "none" },
1073     resource_class = "player",
1074     screen_priority = 0
1075 }
1076
1077 application {
1078     appid           = "weston",
1079     area            = "Center.Full",
1080     privileges      = { screen = "system", audio = "none" },
1081     resource_class  = "implicit",
1082     screen_priority = 30
1083 }
1084
1085 application {
1086     appid           = "org.tizen.ico.homescreen",
1087     area            = "Center.Full",
1088     privileges      = { screen = "system", audio = "system" },
1089     resource_class  = "player",
1090     screen_priority = 20
1091 }
1092
1093 application {
1094     appid           = "org.tizen.ico.statusbar",
1095     area            = "Center.Status",
1096     privileges      = { screen = "system", audio = "none" },
1097     resource_class  = "player",
1098     screen_priority = 20
1099 }
1100
1101 application {
1102     appid           = "org.tizen.ico.login",
1103     area            = "Center.Full",
1104     privileges      = { screen = "system", audio = "system" },
1105     resource_class  = "player",
1106     screen_priority = 20
1107 }
1108
1109
1110 if sc then
1111     sc.client_handler = function (self, cid, msg)
1112         local command = msg.command
1113         if verbose > 0 then
1114             print('### ==> client handler:')
1115             if verbose > 1 then
1116                 print(msg)
1117             end
1118         end
1119         if not connected then
1120             print('Setting homescreen='..msg.appid)
1121             homescreen = msg.appid
1122             print('Trying to connect to wayland...')
1123             connected = wmgr:connect()
1124         end
1125         if connected and command then
1126             if command == 1 then -- send_appid
1127                 local driving_mode = mdb.select.select_driving_mode.single_value
1128                 local night_mode = mdb.select.select_night_mode.single_value
1129
1130                 if not driving_mode then driving_mode = 0 end
1131                 if not night_mode then night_mode = 0 end
1132
1133                 local reply = m:JSON({ command = 0x60001,
1134                                        arg     = m:JSON({ stateid = 1,
1135                                                           state   = driving_mode})
1136                                      })
1137                  if verbose > 0 then
1138                      print("### <== sending " ..
1139                            command_name(command) .. " message")
1140                      if verbose > 1 then
1141                          print(reply)
1142                      end
1143                  end
1144                  sc:send_message(homescreen, reply)
1145
1146                  reply = m:JSON({ command = 0x60001,
1147                                   arg     = m:JSON({ stateid = 2,
1148                                                      state   = night_mode})
1149                                 })
1150                  if verbose > 0 then
1151                      print("### <== sending " ..
1152                            command_name(command) .. " message")
1153                      if verbose > 1 then
1154                          print(reply)
1155                      end
1156                  end
1157                  sc:send_message(homescreen, reply)
1158             end
1159         end
1160     end
1161
1162     sc.generic_handler = function (self, cid, msg)
1163         if verbose > 0 then
1164             print('### ==> generic handler:')
1165             if verbose > 1 then
1166                print(msg)
1167             end
1168         end
1169     end
1170
1171     sc.window_handler = function (self, cid, msg)
1172         if verbose > 0 then
1173             print('### ==> received ' ..
1174                    command_name(msg.command) .. ' message')
1175             if verbose > 1 then
1176                 print(tostring(msg))
1177             end
1178         end
1179
1180         local a = animation({})
1181         local nores = false
1182         if msg.command == 0x10003 then       -- ico SHOW command
1183             local raise_mask = 0x01000000
1184             local lower_mask = 0x02000000
1185             local nores_mask = 0x40000000
1186             local time_mask  = 0x00ffffff
1187             msg.arg.visible = 1
1188             if msg.arg then
1189                 local time = 200
1190                 if  msg.arg.anim_time then
1191                     local t = msg.arg.anim_time
1192                     time = m:AND(t, time_mask)
1193                     nores = m:AND(t, nores_mask)
1194                     if m:AND(t, raise_mask) then
1195                         msg.arg.raise = 1
1196                     elseif m:AND(t, lower_mask) then
1197                         msg.arg.raise = 0
1198                     end
1199                 end
1200                 if msg.arg.anim_name then
1201                     a.show = { msg.arg.anim_name, time }
1202                     print('time: ' .. tostring(a.show[2]))
1203                 end
1204             end
1205             if not nores then
1206                 local p = wmgr:application(msg.appid)
1207                 local s = p.privileges.screen
1208                 if s == "system" then
1209                     nores = true
1210                 end
1211             end
1212             if verbose > 2 then
1213                 print('### ==> SHOW')
1214                 print(tostring(msg.arg))
1215             end
1216             if nores then
1217                 wmgr:window_request(msg.arg, a, 0)
1218             else
1219                 local surface = msg.arg.surface
1220                 resclnt:resource_set_acquire("screen", surface)
1221                 resmgr:window_raise(msg.appid, surface, 1)
1222             end
1223         elseif msg.command == 0x10004 then   -- ico HIDE command
1224             local raise_mask = 0x01000000
1225             local lower_mask = 0x02000000
1226             local nores_mask = 0x40000000
1227             local time_mask  = 0x00ffffff
1228             msg.arg.visible = 0
1229             if msg.arg then
1230                 local time = 200
1231                 if msg.arg.anim_time then
1232                     local t = msg.arg.anim_time
1233                     time = m:AND(t, time_mask)
1234                     nores = m:AND(t, nores_mask)
1235                 end
1236                 if msg.arg.anim_name then
1237                     a.hide = { msg.arg.anim_name, time }
1238                     print('hide animation time: ' .. tostring(a.hide[2]))
1239                 end
1240             end
1241             if not nores then
1242                 local p = wmgr:application(msg.appid)
1243                 local s = p.privileges.screen
1244                 if s == "system" then
1245                     nores = true
1246                 end
1247             end
1248             if verbose > 2 then
1249                 print('### ==> HIDE REQUEST')
1250                 print(tostring(msg.arg))
1251             end
1252             if nores then
1253                 wmgr:window_request(msg.arg, a, 0)
1254             else
1255                 resmgr:window_raise(msg.appid, msg.arg.surface, -1)
1256             end
1257         elseif msg.command == 0x10005 then   -- ico MOVE
1258             if verbose > 2 then
1259                 print('### ==> MOVE REQUEST')
1260                 print(tostring(msg.arg))
1261             end
1262             wmgr:window_request(msg.arg, a, 0)
1263             -- TODO: handle if area changed
1264         elseif msg.command == 0x10006 then   -- ico ACTIVE
1265             if not msg.arg.active then
1266                 msg.arg.active = 3 -- pointer + keyboard
1267             end
1268             if verbose > 2 then
1269                 print('### ==> ACTIVE REQUEST')
1270                 print(tostring(msg.arg))
1271             end
1272             wmgr:window_request(msg.arg, a, 0)
1273         elseif msg.command == 0x10007 then   -- ico CHANGE_LAYER
1274             if verbose > 2 then
1275                 print('### ==> CHANGE_LAYER REQUEST')
1276                 print(tostring(msg.arg))
1277             end
1278             --[[
1279             if msg.arg.layer ~= 4 or msg.arg.layer ~= 5 then
1280                 print("do not change layer for other than cursor or touch")
1281                 return
1282             end
1283             --]]
1284             wmgr:window_request(msg.arg, a, 0)
1285         elseif msg.command == 0x10011 then   -- ico MAP_THUMB
1286             local framerate = msg.arg.framerate
1287             if not framerate or framerate < 0 then
1288                 framerate = 0
1289             end
1290             msg.arg.map = 1
1291             if verbose > 2 then
1292                 print('### ==> MAP_THUMB REQUEST')
1293                 print(msg.arg)
1294                 print('framerate: '..framerate)
1295             end
1296             wmgr:window_request(msg.arg, a, framerate)
1297         elseif msg.command == 0x10012 then   -- ico UNMAP_THUMB
1298             msg.arg.map = 0
1299             if verbose > 2 then
1300                 print('### ==> UNMAP_THUMB REQUEST')
1301                 print(msg.arg)
1302             end
1303             wmgr:window_request(msg.arg, a, 0)
1304         elseif msg.command == 0x10020 then   -- ico SHOW_LAYER command
1305             msg.arg.visible = 1
1306             if verbose > 2 then
1307                 print('### ==> SHOW_LAYER REQUEST')
1308                 print(msg.arg)
1309             end
1310             wmgr:layer_request(msg.arg)
1311         elseif msg.command == 0x10021 then   -- ico HIDE_LAYER command
1312             msg.arg.visible = 0
1313             if verbose > 2 then
1314                 print('### ==> HIDE_LAYER REQUEST')
1315                 print(msg.arg)
1316             end
1317             wmgr:layer_request(msg.arg)
1318         end
1319     end
1320
1321     sc.input_handler = function (self, cid, msg)
1322         if verbose > 0 then
1323             print('### ==> input handler: ' .. command_name(msg.command))
1324             if verbose > 1 then
1325                 print(msg)
1326             end
1327         end
1328         if msg.command == 0x20001 then -- add_input
1329             msg.arg.appid = msg.appid
1330             if verbose > 2 then
1331                 print('### ==> ADD_INPUT REQUEST')
1332                 print(tostring(msg.arg))
1333             end
1334             imgr:input_request(msg.arg)
1335         elseif msg.command == 0x20002 then -- del_input
1336             msg.arg.appid = ''
1337             if verbose > 2 then
1338                 print('### ==> DEL_INPUT REQUEST')
1339                 print(tostring(msg.arg))
1340             end
1341             imgr:input_request(msg.arg)
1342         elseif msg.command == 0x20003 then -- send_input
1343         end
1344     end
1345
1346     sc.user_handler = function (self, cid, msg)
1347         if verbose > 0 then
1348             print('### ==> user handler: ' .. command_name(msg.command))
1349             if verbose > 1 then
1350                 print(msg)
1351             end
1352         end
1353
1354         if not um then
1355             print("User Manager not initialized")
1356             return
1357         end
1358
1359         if msg.command == 0x00030001 then -- MSG_CMD_CHANGE_USER
1360             print("command CHANGE_USER")
1361             if not msg.arg then
1362                 print("invalid message")
1363                 return
1364             end
1365
1366             username = msg.arg.user
1367             passwd = msg.arg.pass
1368
1369             if not username then
1370                 username = ""
1371             end
1372
1373             if not passwd then
1374                 passwd = ""
1375             end
1376
1377             success = um:changeUser(username, passwd)
1378
1379             if not success then
1380                 reply = m.JSON({
1381                     appid = msg.appid,
1382                     command = cmd
1383                 })
1384                 if sc:send_message(msg.appid, reply) then
1385                     print('*** sent authentication failed message')
1386                 else
1387                     print('*** failed to send authentication failed message')
1388                 end
1389             end
1390
1391         elseif msg.command == 0x00030002 then -- MSG_CMD_GET_USERLIST
1392             print("command GET_USERLIST")
1393             if not msg.appid then
1394                 print("invalid message")
1395                 return
1396             end
1397
1398             users, currentUser = um:getUserList()
1399
1400             if not users then
1401                 print("failed to get user list")
1402                 return
1403             end
1404
1405             nUsers = 0
1406
1407             for i,v in pairs(users) do
1408                 nUsers = nUsers + 1
1409             end
1410
1411             if not currentUser then
1412                 currentUser = ""
1413             end
1414
1415             if verbose > 1 then
1416                 print("current user: " .. currentUser)
1417                 print("user list:")
1418                 for i,v in pairs(users) do
1419                     print(v)
1420                 end
1421             end
1422
1423             reply = m.JSON({
1424                 appid = msg.appid,
1425                 command = cmd,
1426                 arg = m.JSON({
1427                     user_num = nUsers,
1428                     user_list = users,
1429                     user_login = currentUser
1430                 })
1431             })
1432
1433             if verbose > 1 then
1434                 print("### <== GetUserList reply: " .. tostring(reply))
1435             end
1436
1437             if sc:send_message(msg.appid, reply) then
1438                 print('*** reply OK')
1439             else
1440                 print('*** reply FAILED')
1441             end
1442
1443         elseif msg.command == 0x00030003 then -- MSG_CMD_GET_LASTINFO
1444             print("command GET_LASTINFO")
1445             if not msg.appid then
1446                 print("invalid message")
1447                 return
1448             end
1449
1450             lastInfo = um:getLastInfo(msg.appid)
1451
1452             if not lastInfo then
1453                 print("failed to get last info for app" .. msg.appid)
1454                 return
1455             end
1456
1457             reply = m.JSON({
1458                 appid = msg.appid,
1459                 command = cmd,
1460                 arg = m.JSON({
1461                     lastinfo = lastinfo
1462                 })
1463             })
1464
1465             if sc:send_message(msg.appid, reply) then
1466                 print('*** reply OK')
1467             else
1468                 print('*** reply FAILED')
1469             end
1470
1471         elseif msg.command == 0x00030004 then -- MSG_CMD_SET_LASTINFO
1472             print("command SET_LASTINFO")
1473             if not msg.arg or not msg.appid then
1474                 print("invalid message")
1475                 return
1476             end
1477
1478             lastInfo = um:setLastInfo(msg.appid, msg.arg.lastinfo)
1479         end
1480     end
1481
1482     sc.resource_handler = function (self, cid, msg)
1483         if verbose > 0 then
1484             print('### ==> resource handler: ' .. command_name(msg.command))
1485             if verbose > 1 then
1486                 print(msg)
1487             end
1488         end
1489
1490         createResourceSet = function (ctl, client, msg)
1491             cb = function(rset, data)
1492                 print("> resource callback")
1493
1494                 -- type is either basic (0) or interrupt (1)
1495                 requestType = 0
1496                 if msg.res.type then
1497                     requestType = msg.res.type
1498                 end
1499
1500                 if rset.acquired then
1501                     cmd = 0x00040001 -- acquire
1502                 else
1503                     cmd = 0x00040002 -- release
1504                 end
1505
1506                 reply = m.JSON({
1507                         appid = data.client,
1508                         command = cmd,
1509                         res = {
1510                             type = requestType
1511                         }
1512                     })
1513
1514                 if rset.resources.audio_playback then
1515                     reply.res.sound = {
1516                         zone = "driver",
1517                         name = msg.appid,
1518                         adjust = 0,
1519                         -- id = "0"
1520                     }
1521                 end
1522
1523                 if rset.resources.display then
1524                     reply.res.window = {
1525                         zone = "driver",
1526                         name = msg.appid,
1527                         -- id = "0"
1528                     }
1529                 end
1530
1531                 if rset.resources.input then
1532                     reply.res.input = {
1533                         name = msg.appid,
1534                         event = 0
1535                     }
1536                 end
1537                 print("sending message to client: " .. data.client)
1538
1539                 if sc:send_message(data.client, reply) then
1540                     print('*** reply OK')
1541                 else
1542                     print('*** reply FAILED')
1543                 end
1544             end
1545
1546             rset = m:ResourceSet({
1547                     application_class = "player",
1548                     zone = "driver", -- msg.zone ("full")
1549                     callback = cb
1550                 })
1551
1552             rset.data = {
1553                 cid = cid,
1554                 ctl = ctl
1555             }
1556
1557             if msg.res.sound then
1558                 rset:addResource({
1559                         resource_name = "audio_playback"
1560                     })
1561                 rset.resources.audio_playback.attributes.pid = tostring(msg.pid)
1562                 rset.resources.audio_playback.attributes.appid = msg.appid
1563                 print("sound name: " .. msg.res.sound.name)
1564                 print("sound zone:" .. msg.res.sound.zone)
1565                 print("sound adjust: " .. tostring(msg.res.sound.adjust))
1566                 if msg.res.sound.id then
1567                     print("sound id: " .. msg.res.sound.id)
1568                 end
1569             end
1570
1571             if msg.res.input then
1572                 rset:addResource({
1573                         resource_name = "input"
1574                     })
1575                 rset.resources.input.attributes.pid = tostring(msg.pid)
1576                 rset.resources.input.attributes.appid = msg.appid
1577                 print("input name: " .. msg.res.sound.name)
1578                 print("input event:" .. tostring(msg.res.input.event))
1579             end
1580
1581             if msg.res.window then
1582                 rset:addResource({
1583                         resource_name = "display"
1584                     })
1585                 rset.resources.display.attributes.pid = tostring(msg.pid)
1586                 rset.resources.display.attributes.appid = msg.appid
1587                 print("display name: " .. msg.res.display.name)
1588                 print("display zone:" .. msg.res.display.zone)
1589                 if msg.res.display.id then
1590                     print("display id: " .. msg.res.display.id)
1591                 end
1592             end
1593
1594             return rset
1595         end
1596
1597         -- parse the message
1598
1599         -- fields common to all messages:
1600         --      msg.command
1601         --      msg.appid
1602         --      msg.pid
1603
1604         if msg.command == 0x00040011 then -- MSG_CMD_CREATE_RES
1605             print("command CREATE")
1606
1607             if not sets.cid then
1608                 sets.cid = createResourceSet(self, cid, msg)
1609             end
1610
1611         elseif msg.command == 0x00040012 then -- MSG_CMD_DESTORY_RES
1612             print("command DESTROY")
1613
1614             if sets.cid then
1615                 sets.cid:release()
1616             end
1617
1618             sets.cid = nil -- garbage collecting
1619
1620         elseif msg.command == 0x00040001 then -- MSG_CMD_ACQUIRE_RES
1621             print("command ACQUIRE")
1622
1623             if not sets.cid then
1624                 sets.cid = createResourceSet(self, cid, msg)
1625             end
1626
1627             sets.cid:acquire()
1628
1629         elseif msg.command == 0x00040002 then -- MSG_CMD_RELEASE_RES
1630             print("command RELEASE")
1631
1632             if sets.cid then
1633                 sets.cid:release()
1634             end
1635
1636         elseif msg.command == 0x00040003 then -- MSG_CMD_DEPRIVE_RES
1637             print("command DEPRIVE")
1638
1639         elseif msg.command == 0x00040004 then -- MSG_CMD_WAITING_RES
1640             print("command WAITING")
1641
1642         elseif msg.command == 0x00040005 then -- MSG_CMD_REVERT_RES
1643             print("command REVERT")
1644         end
1645     end
1646
1647     sc.inputdev_handler = function (self, cid, msg)
1648         if verbose > 0 then
1649             print('*** inputdev handler: ' .. command_name(msg.command))
1650             if verbose > 1 then
1651                 print(msg)
1652             end
1653         end
1654     end
1655 end