core: Move context.host_path call to RootDeviceFactory
[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
36     private MainLoop main_loop;
37
38     private int exit_code;
39
40     public Main () throws GLib.Error {
41         Environment.set_application_name (_(BuildConfig.PACKAGE_NAME));
42
43         this.config = MetaConfig.get_default ();
44         this.plugin_loader = new PluginLoader ();
45         this.root_devices = new ArrayList <RootDevice> ();
46         this.factories = new ArrayList <RootDeviceFactory> ();
47         this.context_manager = this.create_context_manager ();
48         this.main_loop = new GLib.MainLoop (null, false);
49
50         this.exit_code = 0;
51
52         this.plugin_loader.plugin_available += this.on_plugin_loaded;
53
54         Utils.on_application_exit (this.application_exit_cb);
55     }
56
57     public int run () {
58         this.plugin_loader.load_plugins ();
59
60         this.main_loop.run ();
61
62         return this.exit_code;
63     }
64
65     public void exit (int exit_code) {
66         this.exit_code = exit_code;
67         this.main_loop.quit ();
68     }
69
70     private void application_exit_cb () {
71         this.exit (0);
72     }
73
74     private void on_plugin_loaded (PluginLoader plugin_loader,
75                                    Plugin       plugin) {
76         foreach (var factory in this.factories) {
77             this.create_device (plugin, factory);
78         }
79     }
80
81     private ContextManager create_context_manager () {
82         int port = 0;
83
84         try {
85             port = this.config.get_port ();
86         } catch (GLib.Error err) {}
87
88         var manager = new ContextManager (null, port);
89
90         manager.context_available.connect (this.on_context_available);
91         manager.context_unavailable.connect (this.on_context_unavailable);
92
93         return manager;
94     }
95
96     private void on_context_available (GUPnP.ContextManager manager,
97                                        GUPnP.Context        context) {
98         string host_ip = null;
99
100         debug ("new network context %s (%s) available.",
101                context.name,
102                context.host_ip);
103
104         try {
105             host_ip = this.config.get_host_ip ();
106         } catch (GLib.Error err) {}
107
108         if (host_ip == null || host_ip == context.host_ip) {
109             var factory = new RootDeviceFactory (context);
110
111             foreach (var plugin in this.plugin_loader.list_plugins ()) {
112                 this.create_device (plugin, factory);
113             }
114
115             this.factories.add (factory);
116         } else {
117             debug ("Ignoring network context %s (%s).",
118                    context.name,
119                    context.host_ip);
120         }
121     }
122
123     private void on_context_unavailable (GUPnP.ContextManager manager,
124                                          GUPnP.Context        context) {
125         debug ("Network context %s (%s) now unavailable.",
126                context.name,
127                context.host_ip);
128
129         var factory_list = new ArrayList <RootDeviceFactory> ();
130         foreach (var factory in this.factories) {
131             if (context == factory.context) {
132                 factory_list.add (factory);
133             }
134         }
135
136         foreach (var factory in factory_list) {
137             this.factories.remove (factory);
138         }
139
140         var device_list = new ArrayList <RootDevice> ();
141         foreach (var device in this.root_devices) {
142             if (context == device.context) {
143                 device_list.add (device);
144             }
145         }
146
147         foreach (var device in device_list) {
148             device.available = false;
149             this.root_devices.remove (device);
150         }
151     }
152
153     private void create_device (Plugin            plugin,
154                                 RootDeviceFactory factory) {
155         try {
156             var device = factory.create (plugin);
157
158             device.available = plugin.available;
159
160             this.root_devices.add (device);
161
162             plugin.notify["available"] += this.on_plugin_notify;
163         } catch (GLib.Error error) {
164             warning ("Failed to create RootDevice for %s. Reason: %s\n",
165                     plugin.name,
166                     error.message);
167         }
168     }
169
170     private void on_plugin_notify (Plugin    plugin,
171                                    ParamSpec spec) {
172         foreach (var device in this.root_devices) {
173             if (device.resource_factory == plugin) {
174                 device.available = plugin.available;
175             }
176         }
177     }
178
179     public static int main (string[] args) {
180         Main main;
181         DBusService service;
182
183         try {
184             // Parse commandline options
185             CmdlineConfig.parse_args (ref args);
186
187             // initialize gstreamer
188             var dummy_args = new string[0];
189             Gst.init (ref dummy_args);
190
191             main = new Main ();
192             service = new DBusService (main);
193         } catch (CmdlineConfigError.VERSION_ONLY err) {
194             return 0;
195         } catch (GLib.Error err) {
196             error ("%s", err.message);
197
198             return -1;
199         }
200
201         int exit_code = main.run ();
202
203         return exit_code;
204     }
205 }
206