aboutsummaryrefslogtreecommitdiff
path: root/libcontextprovider/context_provider.vala
blob: ead0da3ddc6e88afbe88cc2c4934485d3148c763 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
/*
 * Copyright (C) 2008, 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

using Gee;

namespace ContextProvider {

	// Records whether the context_init function has been called
	internal Manager? manager = null;
	internal dynamic DBus.Object? bus = null;
	/**
	 * context_provider_set_integer:
	 * @key: name of key
	 * @value: new value of key
	 *
	 * Set a key to have an integer value of #value
	 */
	public void set_integer (string key, int value) {
		if (manager == null) {
			critical("Setting a value without a successful init");
			return;
		}

		Value v = Value (typeof(int));
		v.set_int (value);
		manager.property_value_change (remove_context_prefix(key), v);
	}

	/**
	 * context_provider_set_double:
	 * @key: name of key
	 * @value: new value of key
	 *
	 * Set a key to have an floating point value of #value
	 */
	public void set_double (string key, double value) {
		if (manager == null) {
			critical("Setting a value without a successful init");
			return;
		}

		Value v = Value (typeof(double));
		v.set_double (value);
		manager.property_value_change (remove_context_prefix(key), v);
	}

	/**
	 * context_provider_set_boolean:
	 * @key: name of key
	 * @value: new value of key
	 *
	 * Set a key to have an boolean value of #val
	 */
	public void set_boolean (string key, bool value) {
		if (manager == null) {
			critical("Setting a value without a successful init");
			return;
		}

		Value v = Value (typeof(bool));
		v.set_boolean (value);
		manager.property_value_change (remove_context_prefix(key), v);
	}

	/**
	 * context_provider_set_string:
	 * @key: name of key
	 * @value: new value of key
	 *
	 * Set a key to have an boolean value of #val
	 */
	public void set_string (string key, string value) {
		if (manager == null) {
			critical("Setting a value without a successful init");
			return;
		}

		Value v = Value (typeof(string));
		v.set_string (value);
		manager.property_value_change (remove_context_prefix(key), v);
	}

	/**
	 * context_provider_set_null:
	 * @key: name of key
	 *
	 * Marks #key as not having a determinable value.
	 */
	public void set_null (string key) {
		if (manager == null) {
			critical("Setting a value without a successful init");
			return;
		}

		manager.property_value_change (remove_context_prefix(key), null);
	}

	/**
	 * ContextProviderSubscriptionChangedCallback:
	 * @subscribe: TRUE if the group was subscribed to or FALSE if unsubscribed from
	 * @user_data: the user data passed in #context_provider_install
	 *
	 * Type definition for a function that will be called back when
	 * the first key or keys in a group become subscribed or when
	 * all the keys in the group have become unsubscribed.
	 */
	public delegate void SubscriptionChangedCallback(bool subscribe);

	private void log_null(string? log_domain, LogLevelFlags log_levels, string message) {
		/* nop */
	}


	/**
	 * context_provider_init:
	 * @bus_type: which bus to advertise context on
	 * @bus_name: A well-known bus name to register, or NULL if not required.
	 *
	 * Initialise the Context Provider library.
	 *
	 * This sets up the D-Bus connection and optionally requests a well known bus name.
	 * It must be called before using any other context provider functionality.
	 *
	 * Returns: TRUE if successful, FALSE otherwise.
	 */
	public bool init (DBus.BusType bus_type, string? bus_name) {
		// Don't emit debug() messages unless $CONTEXT_DEBUG is defined.
		if (GLib.Environment.get_variable("CONTEXT_DEBUG") == null)
			GLib.Log.set_handler("ContextKit", GLib.LogLevelFlags.LEVEL_DEBUG, log_null);
		try {
			var connection = DBus.Bus.get (bus_type);
			bus = connection.get_object ( "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus");
			if (bus_name != null) {
				// try to register service in session bus
				uint request_name_result = bus.RequestName (bus_name, (uint) 0);

				if (request_name_result != DBus.RequestNameReply.PRIMARY_OWNER) {
					debug ("Unable to register bus name '%s'", bus_name);
					return false;
				}
			}

			debug ("Creating new Manager D-Bus service");

			// Create the Manager object and register it over DBus.
			manager = new Manager (bus_type);
			bus.NameOwnerChanged += manager.on_name_owner_changed;

			debug ("Registering new Manager D-Bus service");
			connection.register_object ("/org/freedesktop/ContextKit/Manager", manager);
		} catch (DBus.Error e) {
			warning ("Unable to register DBus service: %s", e.message);
			manager = null;
			return false;
		}


		return true;
	}

	/**
	 * context_provider_stop:
	 *
	 * Stop providing context and free up all resources.
	 *
	 * Closes down ContextProvider and frees up all resources.
	 */
	public void stop () {
		manager = null;
		bus = null;
	}


	/**
	 * context_provider_install_group:
	 * @key_group: a NULL-terminated array of context key names
	 * @clear_values_on_subscribe: if TRUE then the keys in this group will
	 * be reset to null when the group is first subscribed to after being
	 * unsubscribed from.
	 * @subscription_changed_cb: a #ContextProviderSubscriptionChangedCallback to be called when the subscription status changes on this group
	 * @subscription_changed_cb_target: user data to pass to #subscription_changed_cb
	 * 
	 */
	public void install_group ([CCode (array_length = false, array_null_terminated = true)] string[] key_group, bool clear_values_on_subscribe, SubscriptionChangedCallback? subscription_changed_cb) {
		if (manager == null) {
			critical("Installing keys without a successful init");
			return;
		}
		Group g = new Group(remove_context_prefix_from_array(key_group), clear_values_on_subscribe, subscription_changed_cb);
		manager.group_list.add(g);
	}

	/**
	 * context_provider_install_key:
	 * @key: a context key name
	 * @clear_values_on_subscribe: if TRUE then this key will be reset to null
	 *	when first subscribed to after being unsubscribed from.
	 * @subscription_changed_cb: a #ContextProviderSubscriptionChangedCallback to be called when the subscription status changes on this key
	 * @subscription_changed_cb_target: user data to pass to #subscription_changed_cb
	 *
	 */
	public void install_key(string key, bool clear_values_on_subscribe, SubscriptionChangedCallback? subscription_changed_cb) {
		if (manager == null) {
			critical("Installing keys without a successful init");
			return;
		}
		string[] key_group = {remove_context_prefix(key)};
		Group g = new Group(key_group, clear_values_on_subscribe, subscription_changed_cb);
		manager.group_list.add(g);
	}

	private string remove_context_prefix(string key) {
		if (key.has_prefix("Context.")) {
			return key.substring(8);
		}
		return key;
	}

	private string[] remove_context_prefix_from_array(string[] key_array) {
		string[] to_return = {};
		foreach (var key in key_array) {
			if (key.has_prefix("Context.")) {
				to_return += key.substring(8);
			}
			else {
				to_return += key;
			}
		}
		return to_return;
	}

}