ShutdownService implementation
+ * currently registered in the bundle context of the active
+ * OsDependentActivator instance.
+ *
+ * The returned reference to ShutdownService is not being
+ * cached.
+ *
ShutdownService implementation
+ * currently registered in the bundle context of the active
+ * OsDependentActivator instance
+ */
+ private ShutdownService getShutdownService()
+ {
+ return(ShutdownService)context.getService(
+ context.getServiceReference(ShutdownService.class.getName()));
+ }
+
+ /**
+ * Gets a reference to a SystemActivityNotificationsService
+ * implementation currently registered in the bundle context.
+ *
+ * The returned reference to SystemActivityNotificationsService
+ * is not being cached.
+ *
SystemActivityNotificationsService
+ * implementation currently registered in the bundle context.
+ */
+ public static SystemActivityNotificationsService
+ getSystemActivityNotificationsService(BundleContext context)
+ {
+ ServiceReference ref =
+ context.getServiceReference(
+ SystemActivityNotificationsService.class.getName());
+
+ if(ref == null)
+ return null;
+ else
+ return
+ (SystemActivityNotificationsService)
+ context.getService(ref);
+ }
+
+
+ /**
+ * Saves the reference for the service and
+ * add a listener if the desired events are supported. Or start
+ * the checking thread otherwise.
+ * @param newService the service
+ */
+ private void handleNewSystemActivityNotificationsService
+ (SystemActivityNotificationsService newService)
+ {
+ sysActivityService = newService;
+
+ if(newService != null)
+ newService.addSystemActivityChangeListener(
+ new SystemActivityChangeListener()
+ {
+ public void activityChanged(SystemActivityEvent event)
+ {
+ if(event.getEventID()
+ == SystemActivityEvent.EVENT_QUERY_ENDSESSION)
+ {
+ // instruct the shutdown timeout to
+ // wait only 3 secs.
+ System.setProperty(
+ "org.jitsi.shutdown.SHUTDOWN_TIMEOUT",
+ "3000");
+
+ getShutdownService().beginShutdown();
+
+ // just wait a moment, or till we are stopped
+ try
+ {
+ synchronized(this)
+ {
+ synchShutdown.await(1500,
+ TimeUnit.MILLISECONDS);
+ }
+ }
+ catch(Throwable t)
+ {}
+ }
+ else if(event.getEventID()
+ == SystemActivityEvent.EVENT_ENDSESSION)
+ {
+ try
+ {
+ // wait till we are stopped or forced stopped
+ synchShutdown.await();
+ }
+ catch(Throwable t)
+ {}
+ }
+ }
+ });
+ }
+
+ /**
+ * When new SystemActivityNotificationsService
+ * is registered we add needed listeners.
+ *
+ * @param serviceEvent ServiceEvent
+ */
+ public void serviceChanged(ServiceEvent serviceEvent)
+ {
+ ServiceReference serviceRef = serviceEvent.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know we are shutting down
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ {
+ return;
+ }
+
+ Object sService = context
+ .getService(serviceRef);
+
+ if(sService instanceof SystemActivityNotificationsService)
+ {
+ switch (serviceEvent.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ handleNewSystemActivityNotificationsService(
+ (SystemActivityNotificationsService)sService);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ //((SystemActivityNotificationsService)sService)
+ // .removeSystemActivityChangeListener(this);
+ break;
+ }
+
+ return;
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/windowscleanshutdown/cleanshutdown.manifest.mf b/src/net/java/sip/communicator/plugin/windowscleanshutdown/cleanshutdown.manifest.mf
new file mode 100644
index 000000000..25db59ff8
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/windowscleanshutdown/cleanshutdown.manifest.mf
@@ -0,0 +1,12 @@
+Bundle-Activator: net.java.sip.communicator.plugin.windowscleanshutdown.CleanShutdownActivator
+Bundle-Name: CleanShutdownBundle
+Bundle-Description: A bundle that makes sure that when closed Jitsi will exit cleanly.
+Bundle-Vendor: jitsi.org
+Bundle-Version: 0.0.1
+System-Bundle: yes
+Import-Package: org.osgi.framework,
+ org.jitsi.service.configuration,
+ net.java.sip.communicator.service.shutdown,
+ net.java.sip.communicator.service.sysactivity,
+ net.java.sip.communicator.service.sysactivity.event,
+ net.java.sip.communicator.util
diff --git a/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
index 49494b047..36f85b9b0 100644
--- a/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
+++ b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
@@ -86,6 +86,19 @@ public class SystemActivityEvent
*/
public static final int EVENT_DNS_CHANGE = 12;
+ /**
+ * Informing that the machine is logging of or shutting down.
+ */
+ public static final int EVENT_QUERY_ENDSESSION = 13;
+
+ /**
+ * The log off or shutdown is in process for us, no matter
+ * what other process has replied, whether one of them has canceled
+ * or not the current end of session. It's like that cause we have answered
+ * that we will shutdown.
+ */
+ public static final int EVENT_ENDSESSION = 14;
+
/**
* The type of the event.
*/