VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp@ 37720

Last change on this file since 37720 was 37017, checked in by vboxsync, 14 years ago

VBoxClient: Logging adjustments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/** @file
2 * X11 guest client - host version check.
3 */
4
5/*
6 * Copyright (C) 2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16#include <stdio.h>
17#include <iprt/assert.h>
18#include <iprt/err.h>
19#include <iprt/ldr.h>
20#include <iprt/string.h>
21#include <iprt/thread.h>
22
23#ifdef VBOX_WITH_DBUS
24 #include <VBox/dbus.h>
25#endif
26#include <VBox/log.h>
27#include <VBox/VBoxGuestLib.h>
28
29#include "VBoxClient.h"
30
31class HostVersionService : public VBoxClient::Service
32{
33
34public:
35
36 virtual const char *getPidFilePath()
37 {
38 return ".vboxclient-hostversion.pid";
39 }
40
41 virtual int showNotify(const char *pcHeader, const char *pcBody)
42 {
43 int rc;
44# ifdef VBOX_WITH_DBUS
45 DBusConnection *conn;
46 DBusMessage* msg;
47 conn = dbus_bus_get (DBUS_BUS_SESSON, NULL);
48 if (conn == NULL)
49 {
50 LogRelFlowFunc(("Could not retrieve D-BUS session bus!\n"));
51 rc = VERR_INVALID_HANDLE;
52 }
53 else
54 {
55 msg = dbus_message_new_method_call("org.freedesktop.Notifications",
56 "/org/freedesktop/Notifications",
57 "org.freedesktop.Notifications",
58 "Notify");
59 if (msg == NULL)
60 {
61 LogRel(("Could not create D-BUS message!\n"));
62 rc = VERR_INVALID_HANDLE;
63 }
64 else
65 rc = VINF_SUCCESS;
66 }
67 if (RT_SUCCESS(rc))
68 {
69 uint32_t msg_replace_id = 0;
70 const char *msg_app = "VBoxClient";
71 const char *msg_icon = "";
72 const char *msg_summary = pcHeader;
73 const char *msg_body = pcBody;
74 int32_t msg_timeout = -1; /* Let the notification server decide */
75
76 DBusMessageIter iter;
77 DBusMessageIter array;
78 DBusMessageIter dict;
79 DBusMessageIter value;
80 DBusMessageIter variant;
81 DBusMessageIter data;
82
83 /* Format: UINT32 org.freedesktop.Notifications.Notify
84 * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
85 * ARRAY actions, DICT hints, INT32 expire_timeout)
86 */
87 dbus_message_iter_init_append(msg,&iter);
88 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
89 dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
90 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
91 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
92 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
93 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
94 dbus_message_iter_close_container(&iter,&array);
95 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
96 dbus_message_iter_close_container(&iter,&array);
97 dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
98
99 DBusError err;
100 dbus_error_init(&err);
101
102 DBusMessage *reply;
103 reply = dbus_connection_send_with_reply_and_block(conn, msg,
104 30 * 1000 /* 30 seconds timeout */, &err);
105 if (dbus_error_is_set(&err))
106 {
107 LogRel(("D-BUS returned an error while sending the notification: %s", err.message));
108 }
109 else if (reply)
110 {
111 dbus_connection_flush(conn);
112 dbus_message_unref(reply);
113 }
114 if (dbus_error_is_set(&err))
115 dbus_error_free(&err);
116 }
117 if (msg != NULL)
118 dbus_message_unref(msg);
119# else
120 /* TODO: Implement me */
121 rc = VINF_SUCCESS;
122# endif /* VBOX_WITH_DBUS */
123 return rc;
124 }
125
126 /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
127 notification stuff, since this is very similar to the VBoxTray code. */
128 virtual int run(bool fDaemonised /* = false */)
129 {
130 int rc;
131 LogFlowFunc(("\n"));
132
133 /* Because we need desktop notifications to be displayed, wait
134 * some time to make the desktop environment load (as a work around). */
135 if (fDaemonised)
136 RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
137
138# ifdef VBOX_WITH_DBUS
139 rc = RTDBusLoadLib();
140 if (RT_FAILURE(rc))
141 LogRel(("VBoxClient: D-Bus seems not to be installed; no host version check/notification done.\n"));
142# else
143 rc = VERR_NOT_IMPLEMENTED;
144# endif /* VBOX_WITH_DBUS */
145
146# ifdef VBOX_WITH_GUEST_PROPS
147 uint32_t uGuestPropSvcClientID;
148 if (RT_SUCCESS(rc))
149 {
150 rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
151 if (RT_FAILURE(rc))
152 LogRel(("VBoxClient: Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc));
153 }
154
155 if (RT_SUCCESS(rc))
156 {
157 char *pszHostVersion;
158 char *pszGuestVersion;
159 bool bUpdate;
160
161 rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
162 if (RT_SUCCESS(rc))
163 {
164 if (bUpdate)
165 {
166 char szMsg[256];
167 char szTitle[64];
168
169 /** @todo add some translation macros here */
170 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
171 RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
172 "We recommend updating to the latest version (%s) by choosing the "
173 "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
174 rc = showNotify(szTitle, szMsg);
175 LogRel(("VBoxClient: VirtualBox Guest Additions update available!"));
176 if (RT_FAILURE(rc))
177 LogRel(("VBoxClient: Could not show version notifier tooltip! rc = %d\n", rc));
178 }
179
180 /* Store host version to not notify again */
181 rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
182
183 VbglR3GuestPropReadValueFree(pszHostVersion);
184 VbglR3GuestPropReadValueFree(pszGuestVersion);
185 }
186 VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
187 }
188# endif /* VBOX_WITH_GUEST_PROPS */
189 LogFlowFunc(("returning %Rrc\n", rc));
190 return rc;
191 }
192
193 virtual void cleanup()
194 {
195
196 }
197};
198
199/* Static factory */
200VBoxClient::Service *VBoxClient::GetHostVersionService()
201{
202 return new HostVersionService;
203}
204
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette