core: Initialize LogHander at start-up
[profile/ivi/rygel.git] / src / rygel / rygel-main.vala
1 /*
2  * Copyright (C) 2008 Nokia Corporation.
3  * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>.
4  *
5  * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
6  *
7  * This file is part of Rygel.
8  *
9  * Rygel is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Rygel is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 using CStuff;
25 using Gee;
26 using GUPnP;
27
28 public class Rygel.Main : Object {
29     private PluginLoader plugin_loader;
30     private ContextManager context_manager;
31     private ArrayList <RootDeviceFactory> factories;
32     private ArrayList <RootDevice> root_devices;
33
34     private Configuration config;
35     private LogHandler log_handler;
36
37     private MainLoop main_loop;
38
39     private int exit_code;
40
41     private Main () throws GLib.Error {
42         Environment.set_application_name (_(BuildConfig.PACKAGE_NAME));
43
44         this.log_handler = LogHandler.get_default ();
45         this.config = MetaConfig.get_default ();
46         this.plugin_loader = new PluginLoader ();
47         this.root_devices = new ArrayList <RootDevice> ();
48         this.factories = new ArrayList <RootDeviceFactory> ();
49         this.context_manager = this.create_context_manager ();
50         this.main_loop = new GLib.MainLoop (null, false);
51
52         this.exit_code = 0;
53
54         this.plugin_loader.plugin_available += this.on_plugin_loaded;
55
56         Utils.on_application_exit (this.application_exit_cb);
57     }
58
59     public void exit (int exit_code) {
60         this.exit_code = exit_code;
61         this.main_loop.quit ();
62     }
63
64     private int run () {
65         this.plugin_loader.load_plugins ();
66
67         this.main_loop.run ();
68
69         return this.exit_code;
70     }
71
72     private void application_exit_cb () {
73         this.exit (0);
74     }
75
76     private void on_plugin_loaded (PluginLoader plugin_loader,
77                                    Plugin       plugin) {
78         // We iterate over the copy of the list rather than list itself because
79         // there is high chances of the original list being modified during the
80         // iteration, which is not allowed by libgee.
81         var factories = new ArrayList <RootDeviceFactory> ();
82         foreach (var factory in this.factories) {
83             factories.add (factory);
84         }
85
86         foreach (var factory in factories) {
87             this.create_device (plugin, factory);
88         }
89     }
90
91     private ContextManager create_context_manager () {
92         int port = 0;
93
94         try {
95             port = this.config.get_port ();
96         } catch (GLib.Error err) {}
97
98         var manager = new ContextManager (null, port);
99
100         manager.context_available.connect (this.on_context_available);
101         manager.context_unavailable.connect (this.on_context_unavailable);
102
103         return manager;
104     }
105
106     private void on_context_available (GUPnP.ContextManager manager,
107                                        GUPnP.Context        context) {
108         string iface = null;
109
110         debug ("new network context %s (%s) available.",
111                context.interface,
112                context.host_ip);
113
114         try {
115             iface = this.config.get_interface ();
116         } catch (GLib.Error err) {}
117
118         if (iface == null || iface == context.interface) {
119             var factory = new RootDeviceFactory (context);
120             this.factories.add (factory);
121
122             // See the comment in on_plugin_loaded method
123             var plugins = new ArrayList <Plugin> ();
124             foreach (var plugin in this.plugin_loader.list_plugins ()) {
125                 plugins.add (plugin);
126             }
127
128             foreach (var plugin in plugins) {
129                 this.create_device (plugin, factory);
130             }
131         } else {
132             debug ("Ignoring network context %s (%s).",
133                    context.interface,
134                    context.host_ip);
135         }
136     }
137
138     private void on_context_unavailable (GUPnP.ContextManager manager,
139                                          GUPnP.Context        context) {
140         debug ("Network context %s (%s) now unavailable.",
141                context.interface,
142                context.host_ip);
143
144         var factory_list = new ArrayList <RootDeviceFactory> ();
145         foreach (var factory in this.factories) {
146             if (context == factory.context) {
147                 factory_list.add (factory);
148             }
149         }
150
151         foreach (var factory in factory_list) {
152             this.factories.remove (factory);
153         }
154
155         var device_list = new ArrayList <RootDevice> ();
156         foreach (var device in this.root_devices) {
157             if (context == device.context) {
158                 device_list.add (device);
159             }
160         }
161
162         foreach (var device in device_list) {
163             this.root_devices.remove (device);
164         }
165     }
166
167     private void create_device (Plugin            plugin,
168                                 RootDeviceFactory factory) {
169         try {
170             var device = factory.create (plugin);
171
172             device.available = plugin.available;
173
174             this.root_devices.add (device);
175
176             plugin.notify["available"] += this.on_plugin_notify;
177         } catch (GLib.Error error) {
178             warning ("Failed to create RootDevice for %s. Reason: %s\n",
179                     plugin.name,
180                     error.message);
181         }
182     }
183
184     private void on_plugin_notify (Plugin    plugin,
185                                    ParamSpec spec) {
186         foreach (var device in this.root_devices) {
187             if (device.resource_factory == plugin) {
188                 device.available = plugin.available;
189             }
190         }
191     }
192
193     private static int main (string[] args) {
194         Main main;
195         DBusService service;
196
197         try {
198             // Parse commandline options
199             CmdlineConfig.parse_args (ref args);
200
201             // initialize gstreamer
202             var dummy_args = new string[0];
203             Gst.init (ref dummy_args);
204
205             main = new Main ();
206             service = new DBusService (main);
207         } catch (CmdlineConfigError.VERSION_ONLY err) {
208             return 0;
209         } catch (GLib.Error err) {
210             error ("%s", err.message);
211
212             return -1;
213         }
214
215         int exit_code = main.run ();
216
217         return exit_code;
218     }
219 }
220