diff --git a/build.xml b/build.xml
index f126f4934..ee88b82dc 100644
--- a/build.xml
+++ b/build.xml
@@ -908,6 +908,7 @@
bundle-version,bundle-version-impl,bundle-shutdown-timeout,
bundle-growlnotification,bundle-swingnotification,bundle-galagonotification,
bundle-sparkle, bundle-plugin-branding,
+ bundle-systemactivitynotifications,
bundle-osdependent,bundle-browserlauncher,
bundle-zeroconf,bundle-plugin-zeroconfaccregwizz,
bundle-pluginmanager,bundle-skinmanager,bundle-notification,
@@ -2687,4 +2688,17 @@ javax.swing.event, javax.swing.border"/>
prefix="net/java/sip/communicator/plugin/dnsconfig" />
+
+
+
+
+
+
+
+
+
+
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index d1fe5058e..fde1911fa 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -75,5 +75,8 @@
+
+
+
diff --git a/ide/nbproject/project.xml b/ide/nbproject/project.xml
index 2650b231c..8b252d0a3 100644
--- a/ide/nbproject/project.xml
+++ b/ide/nbproject/project.xml
@@ -122,7 +122,7 @@
src
- lib/felix.jar:lib/jdic-all.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/aclibico-2.1.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/concurrent.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/httpclient-4.1.1.jar:lib/installer-exclude/httpcore-4.1.jar:lib/installer-exclude/httpmime-4.1.1.jar:lib/installer-exclude/ice4j.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jcalendar-1.3.2.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jdom.jar:lib/installer-exclude/jfontchooser-1.0.5.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmf.jar:lib/installer-exclude/jml-1.0b5.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-20090723.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libphonenumber-2.4.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/rome-0.9.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/transparency.jar:lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar:lib/installer-exclude/ymsg_network_v0_67.jar:lib/installer-exclude/zrtp4j-light.jar:lib/os-specific/linux/installer-exclude/jmf.jar:lib/os-specific/linux/jdic_stub.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/jdic_stub.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar:lib/os-specific/mac/installer-exclude/jmf.jar:lib/os-specific/solaris/jdic_stub.jar:lib/os-specific/solaris/installer-exclude/jmf.jar:lib/os-specific/windows/jdic_stub.jar:lib/os-specific/windows/installer-exclude/jmf.jar:lib/os-specific/windows/installer-exclude/jna-platform-win32.jar:lib/os-specific/windows/installer-exclude/sound.jar
+ lib/felix.jar:lib/jdic-all.jar:lib/bundle/commons-logging.jar:lib/bundle/junit.jar:lib/bundle/log4j.jar:lib/installer-exclude/aclibico-2.1.jar:lib/installer-exclude/apache-ant-1.7.0.jar:lib/installer-exclude/concurrent.jar:lib/installer-exclude/dhcp4java-1.00.jar:lib/installer-exclude/dict4j.jar:lib/installer-exclude/dnsjava.jar:lib/installer-exclude/fmj.jar:lib/installer-exclude/forms-1.2.1.jar:lib/installer-exclude/gdata-client-1.0.jar:lib/installer-exclude/gdata-client-meta-1.0.jar:lib/installer-exclude/gdata-contacts-3.0.jar:lib/installer-exclude/gdata-contacts-meta-3.0.jar:lib/installer-exclude/gdata-core-1.0.jar:lib/installer-exclude/google-collect-1.0-rc1.jar:lib/installer-exclude/httpclient-4.1.1.jar:lib/installer-exclude/httpcore-4.1.jar:lib/installer-exclude/httpmime-4.1.1.jar:lib/installer-exclude/ice4j.jar:lib/installer-exclude/jain-sdp.jar:lib/installer-exclude/jain-sip-api.jar:lib/installer-exclude/jain-sip-ri.jar:lib/installer-exclude/jcalendar-1.3.2.jar:lib/installer-exclude/jdic_misc.jar:lib/installer-exclude/jdom.jar:lib/installer-exclude/jfontchooser-1.0.5.jar:lib/installer-exclude/jmdns.jar:lib/installer-exclude/jmf.jar:lib/installer-exclude/jml-1.0b5.jar:lib/installer-exclude/jmyspell-core.jar:lib/installer-exclude/jna.jar:lib/installer-exclude/jnsapi.jar:lib/installer-exclude/joscar-client.jar:lib/installer-exclude/joscar-common.jar:lib/installer-exclude/joscar-protocol.jar:lib/installer-exclude/jsch-0.1.36.jar:lib/installer-exclude/jsocks-klea.jar:lib/installer-exclude/json-20090723.jar:lib/installer-exclude/jspeex.jar:lib/installer-exclude/junit.jar:lib/installer-exclude/laf-widget.jar:lib/installer-exclude/lcrypto-jdk16-143.jar:lib/installer-exclude/libphonenumber-2.4.jar:lib/installer-exclude/log4j-1.2.8.jar:lib/installer-exclude/lti-civil-no_s_w_t.jar:lib/installer-exclude/mac_widgets-0.9.5.jar:lib/installer-exclude/nist-sdp-1.0.jar:lib/installer-exclude/otr4j.jar:lib/installer-exclude/pircbot.jar:lib/installer-exclude/profiler4j-1.0-beta3-SC.jar:lib/installer-exclude/rome-0.9.jar:lib/installer-exclude/smack.jar:lib/installer-exclude/smackx.jar:lib/installer-exclude/swing-worker-1.2.jar:lib/installer-exclude/transparency.jar:lib/installer-exclude/weupnp-0.1.2-SNAPSHOT.jar:lib/installer-exclude/ymsg_network_v0_67.jar:lib/installer-exclude/zrtp4j-light.jar:lib/os-specific/linux/installer-exclude/jmf.jar:lib/os-specific/linux/jdic_stub.jar:lib/os-specific/mac/growl4j.jar:lib/os-specific/mac/jdic_stub.jar:lib/os-specific/mac/OrangeExtensions.jar:lib/os-specific/mac/installer-exclude/dock.jar:lib/os-specific/mac/installer-exclude/jmf.jar:lib/os-specific/solaris/jdic_stub.jar:lib/os-specific/solaris/installer-exclude/jmf.jar:lib/os-specific/windows/jdic_stub.jar:lib/os-specific/windows/installer-exclude/jmf.jar:lib/os-specific/windows/installer-exclude/jna-platform-win32.jar:lib/os-specific/windows/installer-exclude/sound.jar:lib/installer-exclude/libdbus-java-2.7.jar:lib/installer-exclude/hexdump-0.2.jar:lib/installer-exclude/unix-0.5.jar
classes
1.5
diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties
index f2ee6d40b..eff2f69f9 100644
--- a/lib/felix.client.run.properties
+++ b/lib/felix.client.run.properties
@@ -48,6 +48,7 @@ felix.auto.start.40= \
reference:file:sc-bundles/resourcemanager.jar \
reference:file:sc-bundles/jfontchooserlib.jar \
reference:file:sc-bundles/netaddr.jar \
+ reference:file:sc-bundles/sysactivitynotifications.jar \
reference:file:sc-bundles/browserlauncher.jar \
reference:file:sc-bundles/updateservice.jar
diff --git a/lib/installer-exclude/hexdump-0.2.jar b/lib/installer-exclude/hexdump-0.2.jar
new file mode 100644
index 000000000..4fb5ee14a
Binary files /dev/null and b/lib/installer-exclude/hexdump-0.2.jar differ
diff --git a/lib/installer-exclude/libdbus-java-2.7.jar b/lib/installer-exclude/libdbus-java-2.7.jar
new file mode 100644
index 000000000..e58e513ed
Binary files /dev/null and b/lib/installer-exclude/libdbus-java-2.7.jar differ
diff --git a/lib/installer-exclude/unix-0.5.jar b/lib/installer-exclude/unix-0.5.jar
new file mode 100644
index 000000000..d9810d98b
Binary files /dev/null and b/lib/installer-exclude/unix-0.5.jar differ
diff --git a/lib/native/linux-64/libsysactivitynotifications.so b/lib/native/linux-64/libsysactivitynotifications.so
new file mode 100644
index 000000000..711763688
Binary files /dev/null and b/lib/native/linux-64/libsysactivitynotifications.so differ
diff --git a/lib/native/linux-64/libunix-java.so b/lib/native/linux-64/libunix-java.so
new file mode 100644
index 000000000..8c4e92c46
Binary files /dev/null and b/lib/native/linux-64/libunix-java.so differ
diff --git a/lib/native/linux/libsysactivitynotifications.so b/lib/native/linux/libsysactivitynotifications.so
new file mode 100644
index 000000000..c2fb161bf
Binary files /dev/null and b/lib/native/linux/libsysactivitynotifications.so differ
diff --git a/lib/native/linux/libunix-java.so b/lib/native/linux/libunix-java.so
new file mode 100644
index 000000000..f4d916591
Binary files /dev/null and b/lib/native/linux/libunix-java.so differ
diff --git a/lib/native/mac/libsysactivitynotifications.jnilib b/lib/native/mac/libsysactivitynotifications.jnilib
new file mode 100644
index 000000000..668bea125
Binary files /dev/null and b/lib/native/mac/libsysactivitynotifications.jnilib differ
diff --git a/lib/native/windows-64/sysactivitynotifications.dll b/lib/native/windows-64/sysactivitynotifications.dll
new file mode 100644
index 000000000..c762f8875
Binary files /dev/null and b/lib/native/windows-64/sysactivitynotifications.dll differ
diff --git a/lib/native/windows/sysactivitynotifications.dll b/lib/native/windows/sysactivitynotifications.dll
new file mode 100644
index 000000000..3571b34b5
Binary files /dev/null and b/lib/native/windows/sysactivitynotifications.dll differ
diff --git a/src/native/build.xml b/src/native/build.xml
index 8277ac30f..42b94a9e5 100644
--- a/src/native/build.xml
+++ b/src/native/build.xml
@@ -801,6 +801,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.c b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.c
new file mode 100644
index 000000000..00319a972
--- /dev/null
+++ b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.c
@@ -0,0 +1,86 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h"
+
+#include
+#include
+#include
+#include
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: setDelegate
+ * Signature: (Lnet/java/sip/communicator/impl/sysactivity/SystemActivityNotifications/NotificationsDelegate;)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_setDelegate
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr, jobject m_delegate)
+{
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: allocAndInit
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_allocAndInit
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ return -1;
+}
+
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_release
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: getLastInput
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_getLastInput
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ static XScreenSaverInfo *mit_info = NULL;
+ static int has_extension = -1;
+ int event_base, error_base;
+
+ if(GDK_DISPLAY())
+ has_extension = XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base);
+
+ if (has_extension != -1)
+ {
+ mit_info = XScreenSaverAllocInfo();
+
+ XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
+
+ return (mit_info->idle);
+ }
+ else
+ return 0;
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: start
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_start
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: stop
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_stop
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+}
diff --git a/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.cpp b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.cpp
new file mode 100644
index 000000000..a2017f532
--- /dev/null
+++ b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.cpp
@@ -0,0 +1,462 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h"
+
+/**
+ * \def WIN32_LEAN_AND_MEAN
+ * \brief Exclude not commonly used headers from win32 API.
+ *
+ * It excludes some unused stuff from windows headers and
+ * by the way code compiles faster.
+ */
+#define WIN32_LEAN_AND_MEAN
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// cache for the JavaVM* pointer
+JavaVM *jvm;
+
+// cache for the a generic pointer
+jobject delegateObject;
+
+// thread id
+UINT uThreadId;
+
+// cache for the instance handle
+HINSTANCE hInstance;
+
+void RegisterWindowClassW();
+LRESULT CALLBACK WndProcW(HWND, UINT, WPARAM, LPARAM);
+HRESULT callback(UINT Msg, WPARAM wParam, LPARAM lParam);
+
+void notify(int notificationType);
+void notifyNetwork(int family,
+ long luidIndex,
+ char* name,
+ long type,
+ bool connected);
+
+typedef void (WINAPI *NIpIfaceChange)(ADDRESS_FAMILY,
+ PIPINTERFACE_CHANGE_CALLBACK,
+ PVOID,
+ BOOLEAN,
+ HANDLE);
+typedef NETIO_STATUS (*FnConvertInterfaceLuidToNameA)(
+ const NET_LUID *,
+ PSTR,
+ SIZE_T);
+typedef NETIO_STATUS (*FnGetIpInterfaceEntry)(
+ PMIB_IPINTERFACE_ROW);
+
+OVERLAPPED overlap;
+
+/*static HHOOK hhookSysMsg;
+
+static LRESULT CALLBACK msghook(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ if(nCode < 0)
+ {
+ CallNextHookEx(hhookSysMsg, nCode, wParam, lParam);
+ return 0;
+ }
+
+ LPMSG msg = (LPMSG)lParam;
+
+ if(msg->message == WM_SYSCOMMAND)
+ {
+ if(wParam == SC_SCREENSAVE)
+ {
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_START);
+ }
+ else if(wParam == SC_MONITORPOWER)
+ {
+ if(lParam == -1)
+ {
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_WAKE);
+ }
+ else if(lParam == 2)
+ {
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_SLEEP);
+ }
+ }
+ }
+
+ return CallNextHookEx(hhookSysMsg, nCode, wParam, lParam);
+}
+*/
+
+unsigned WINAPI CreateWndThreadW(LPVOID pThreadParam)
+{
+ hInstance = GetModuleHandle (NULL);
+ RegisterWindowClassW();
+
+ /*
+ hhookSysMsg = SetWindowsHookEx(
+ WH_MSGFILTER,
+ (HOOKPROC)msghook,
+ hInstance,
+ GetCurrentThreadId());
+ if(hhookSysMsg == NULL)
+ {
+ fprintf(stderr, "Failed to create hoook %i\n", GetLastError() );
+ fflush(stderr);
+ }
+ */
+
+ HWND hWnd = CreateWindowW( L"Jitsi Window Hook", NULL, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL, hInstance, NULL);
+ if( hWnd == NULL)
+ {
+ fprintf(stderr, "Failed to create window\n" );
+ fflush(stderr);
+
+ return( 0 );
+
+ }else
+ {
+ MSG Msg;
+
+ while(GetMessageW(&Msg, hWnd, 0, 0)) {
+
+ TranslateMessage(&Msg);
+
+ DispatchMessageW(&Msg);
+ }
+
+ return Msg.wParam;
+ }
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: setDelegate
+ * Signature: (Lnet/java/sip/communicator/impl/sysactivity/SystemActivityNotifications/NotificationsDelegate;)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_setDelegate
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr, jobject m_delegate)
+{
+ if (delegateObject)
+ {
+ if (!jniEnv)
+ jvm->AttachCurrentThread((void **)&jniEnv, NULL);
+ jniEnv->DeleteGlobalRef(delegateObject);
+ delegateObject = NULL;
+ jvm = NULL;
+ }
+
+ if (m_delegate)
+ {
+ m_delegate = jniEnv->NewGlobalRef(m_delegate);
+ if (m_delegate)
+ {
+ jniEnv->GetJavaVM(&(jvm));
+ delegateObject = m_delegate;
+ }
+ }
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: allocAndInit
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_allocAndInit
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ HANDLE hThread;
+
+ hThread = (HANDLE)_beginthreadex(NULL, 0, &CreateWndThreadW, NULL, 0, &uThreadId);
+
+ if(!hThread)
+ {
+ //throwException( env, "_beginthreadex", "initialisation failed" );
+ }
+
+ return (jlong)hThread;
+}
+
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_release
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ if (!jniEnv)
+ jvm->AttachCurrentThread((void **)&jniEnv, NULL);
+ jniEnv->DeleteGlobalRef(delegateObject);
+ delegateObject = NULL;
+ jvm = NULL;
+}
+
+static void InterfaceChangeCallback(
+ PVOID CallerContext,
+ PMIB_IPINTERFACE_ROW Row,
+ MIB_NOTIFICATION_TYPE NotificationType)
+{
+ if(Row)
+ {
+ FnGetIpInterfaceEntry getIpIfaceEntry;
+ getIpIfaceEntry = (FnGetIpInterfaceEntry)GetProcAddress(
+ GetModuleHandle(TEXT("Iphlpapi.dll")),
+ "GetIpInterfaceEntry");
+
+ if(getIpIfaceEntry && getIpIfaceEntry(Row) == NO_ERROR)
+ {
+ FnConvertInterfaceLuidToNameA convertName;
+ convertName = (FnConvertInterfaceLuidToNameA)GetProcAddress(
+ GetModuleHandle(TEXT("Iphlpapi.dll")),
+ "ConvertInterfaceLuidToNameA");
+
+ char interfaceName[MAX_PATH];
+ if (convertName &&
+ convertName(&(Row->InterfaceLuid),
+ interfaceName,
+ sizeof(interfaceName))
+ == NO_ERROR)
+ {
+ //fprintf( stderr, "Interface LUID Name : %s\n", interfaceName);
+ }
+
+ notifyNetwork(
+ Row->Family,
+ Row->InterfaceLuid.Info.NetLuidIndex,
+ interfaceName,
+ Row->InterfaceLuid.Info.IfType,
+ Row->Connected);
+ }
+ }
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: getLastInput
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_getLastInput
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ DWORD result = 0;
+
+ LASTINPUTINFO lii;
+ memset(&lii, 0, sizeof(lii));
+ lii.cbSize = sizeof(LASTINPUTINFO);
+ if (GetLastInputInfo(&lii))
+ {
+ return GetTickCount() - lii.dwTime;
+ }
+
+ return -1;
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: start
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_start
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ OSVERSIONINFOEX osVersionInfoEx;
+ memset( &osVersionInfoEx, 0, sizeof(OSVERSIONINFOEX) );
+ osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ GetVersionEx((OSVERSIONINFO*) &osVersionInfoEx );
+
+ if( osVersionInfoEx.dwMajorVersion == 5)
+ {
+ // XP
+ while(true)
+ {
+ HANDLE hand = NULL;
+ DWORD ret, bytes;
+
+ hand = NULL;
+ ZeroMemory(&overlap, sizeof(overlap));
+ overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ ret = NotifyAddrChange(&hand, &overlap);
+
+ if(ret != ERROR_IO_PENDING )
+ {
+ //fprintf(stderr, "NotifyAddrChange returned %d,
+ // expected ERROR_IO_PENDING \n", ret);fflush(stderr);
+
+ // break in case of error.
+ break;
+ }
+
+ BOOL success = GetOverlappedResult(hand, &overlap, &bytes, TRUE);
+
+ if(!success)
+ break;
+
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_NETWORK_CHANGE);
+ }
+ }
+ else if( osVersionInfoEx.dwMajorVersion > 5)
+ {
+ // Vista, 7, ....
+ NIpIfaceChange nIpIfaceChange;
+ nIpIfaceChange = (NIpIfaceChange)GetProcAddress(
+ GetModuleHandle(TEXT("Iphlpapi.dll")),
+ "NotifyIpInterfaceChange");
+
+ if(nIpIfaceChange)
+ {
+ ADDRESS_FAMILY family = AF_UNSPEC;
+ HANDLE hNotification;
+
+ nIpIfaceChange(
+ family,
+ (PIPINTERFACE_CHANGE_CALLBACK)InterfaceChangeCallback,
+ NULL,
+ FALSE,
+ &hNotification);
+ }
+ }
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: stop
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_stop
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ CancelIPChangeNotify(&overlap);
+}
+
+void RegisterWindowClassW()
+{
+ WNDCLASSEXW wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEXW);
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = WndProcW;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = 0;
+ wcex.hCursor = 0;
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = L"Jitsi Window Hook";
+ wcex.hIconSm = 0;
+
+ RegisterClassExW(&wcex);
+}
+
+LRESULT CALLBACK WndProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ long res = callback( Msg, wParam, lParam );
+
+ if ( res != -1 )
+ {
+ return( res );
+ }
+
+ return DefWindowProcW(hWnd, Msg, wParam, lParam);
+}
+
+HRESULT callback(UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ JNIEnv *env;
+
+ if ( jvm->AttachCurrentThread((void **)&env, NULL ))
+ {
+ fprintf( stderr, "failed to attach current thread to JVM\n" );fflush(stderr);
+
+ return( -1 );
+ }
+
+ jlong result = -1;
+
+ if (Msg == WM_POWERBROADCAST)
+ {
+ if (wParam == PBT_APMSUSPEND)
+ {
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SLEEP);
+ return TRUE;
+ }
+ else if (wParam == PBT_APMRESUMESUSPEND)
+ {
+ notify(net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_WAKE);
+ return TRUE;
+ }
+ }
+
+ jvm->DetachCurrentThread();
+
+ return((HRESULT)result );
+}
+
+void notify(int notificationType)
+{
+ JNIEnv *jniEnv;
+ jclass delegateClass = NULL;
+
+ if (!delegateObject)
+ return;
+
+ if (0 != jvm->AttachCurrentThreadAsDaemon( (void **)&jniEnv, NULL))
+ return;
+
+ delegateClass = jniEnv->GetObjectClass(delegateObject);
+ if(delegateClass)
+ {
+ jmethodID methodid = NULL;
+
+ methodid = jniEnv->GetMethodID(delegateClass,"notify", "(I)V");
+ if(methodid)
+ {
+ jniEnv->CallVoidMethod(delegateObject, methodid, notificationType);
+ }
+ }
+ jniEnv->ExceptionClear();
+}
+
+void notifyNetwork(int family,
+ long luidIndex,
+ char* name,
+ long type,
+ bool connected)
+{
+ JNIEnv *jniEnv;
+ jclass delegateClass = NULL;
+
+ if (!delegateObject)
+ return;
+
+ if (0 != jvm->AttachCurrentThreadAsDaemon( (void **)&jniEnv, NULL))
+ return;
+
+ delegateClass = jniEnv->GetObjectClass(delegateObject);
+ if(delegateClass)
+ {
+ jmethodID methodid = NULL;
+
+ methodid = jniEnv->GetMethodID(delegateClass,
+ "notifyNetworkChange",
+ "(IJLjava/lang/String;JZ)V");
+
+ if(methodid)
+ {
+ jniEnv->CallVoidMethod(delegateObject, methodid,
+ family,
+ luidIndex,
+ name ? jniEnv->NewStringUTF(name) : NULL,
+ type,
+ connected);
+ }
+ }
+ jniEnv->ExceptionClear();
+}
+
diff --git a/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h
new file mode 100644
index 000000000..8b586b859
--- /dev/null
+++ b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h
@@ -0,0 +1,83 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications */
+
+#ifndef _Included_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+#define _Included_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SLEEP
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SLEEP 0L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_WAKE
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_WAKE 1L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_SLEEP
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_SLEEP 2L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_WAKE
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_WAKE 3L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_START
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_START 4L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_WILL_STOP
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_WILL_STOP 5L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_STOP
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_STOP 6L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_LOCKED
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_LOCKED 7L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_UNLOCKED
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_UNLOCKED 8L
+#undef net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_NETWORK_CHANGE
+#define net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_NETWORK_CHANGE 9L
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: allocAndInit
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_allocAndInit
+ (JNIEnv *, jclass);
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: release
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_release
+ (JNIEnv *, jclass, jlong);
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: setDelegate
+ * Signature: (JLnet/java/sip/communicator/impl/sysactivity/SystemActivityNotifications/NotificationsDelegate;)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_setDelegate
+ (JNIEnv *, jclass, jlong, jobject);
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: start
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_start
+ (JNIEnv *, jclass, jlong);
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: stop
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_stop
+ (JNIEnv *, jclass, jlong);
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: getLastInput
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_getLastInput
+ (JNIEnv *, jclass);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.m b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.m
new file mode 100644
index 000000000..20ee383f3
--- /dev/null
+++ b/src/native/sysactivity/net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.m
@@ -0,0 +1,394 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+#include "net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications.h"
+
+#import
+#import
+#import
+#import
+#import
+#import
+
+@interface AISleepNotification: NSObject
+{
+@private
+ jobject delegateObject;
+ JavaVM *vm;
+}
+
+-(void)dealloc;
+-(id)init;
+-(void)clean;
+-(void)start;
+-(void)stop;
+
+-(void) receiveSleepNote: (NSNotification *) notification;
+-(void) receiveWakeNote: (NSNotification *) notification;
+-(void) receiveDisplaySleepNote: (NSNotification *) notification;
+-(void) receiveDisplayWakeNote: (NSNotification *) notification;
+-(void) screenIsLocked: (NSNotification *) notification;
+-(void) screenIsUnlocked: (NSNotification *) notification;
+-(void) screensaverStart: (NSNotification *) notification;
+-(void) screensaverWillStop: (NSNotification *) notification;
+-(void) screensaverStop: (NSNotification *) notification;
+-(void) netChange: (NSNotification *) notification;
+
+-(void) setDelegate:(jobject)delegate inJNIEnv:(JNIEnv *)jniEnv;
+
+-(void) notify: (int) notificationType;
+
+
+@end
+
+
+@implementation AISleepNotification
+CFRunLoopRef loopRef;
+/** Our run loop source for notification used
+ for network notifications. */
+static CFRunLoopSourceRef rlSrc;
+
+-(void) notify: (int) notificationType
+{
+ jobject delegate;
+ JNIEnv *jniEnv;
+ jclass delegateClass = NULL;
+
+ delegate = self->delegateObject;
+ if (!delegate)
+ return;
+
+ vm = self->vm;
+ if (0 != (*vm)->AttachCurrentThreadAsDaemon(vm, (void **)&jniEnv, NULL))
+ return;
+
+ delegateClass = (*jniEnv)->GetObjectClass(jniEnv, delegate);
+ if(delegateClass)
+ {
+ jmethodID methodid = NULL;
+
+ methodid = (*jniEnv)->GetMethodID(jniEnv, delegateClass,"notify", "(I)V");
+ if(methodid)
+ {
+ (*jniEnv)->CallVoidMethod(jniEnv, delegate, methodid, notificationType);
+ }
+ }
+ (*jniEnv)->ExceptionClear(jniEnv);
+}
+
+- (void)receiveSleepNote: (NSNotification *) note
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SLEEP];
+}
+
+- (void)receiveWakeNote: (NSNotification *) note
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_WAKE];
+}
+
+-(void) receiveDisplaySleepNote: (NSNotification *) note
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_SLEEP];
+}
+
+-(void) receiveDisplayWakeNote: (NSNotification *) note
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_DISPLAY_WAKE];
+}
+
+-(void)screenIsLocked: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_LOCKED];
+}
+- (void) screenIsUnlocked: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREEN_UNLOCKED];
+}
+
+-(void) screensaverStart: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_START];
+}
+
+-(void) screensaverWillStop: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_WILL_STOP];
+}
+
+-(void) screensaverStop: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_SCREENSAVER_STOP];
+}
+
+-(void) netChange: (NSNotification *) notification
+{
+ [self notify:net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_NOTIFY_NETWORK_CHANGE];
+}
+
+void scCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
+{
+ NSAutoreleasePool* localPool = [NSAutoreleasePool new];
+
+ [[NSNotificationCenter defaultCenter] postNotificationName
+ :@"NetworkConfigurationDidChangeNotification" object:(id)info];
+
+ [localPool drain];
+}
+
+- (void)setDelegate:(jobject) delegate inJNIEnv:(JNIEnv *)jniEnv
+{
+ if (self->delegateObject)
+ {
+ if (!jniEnv)
+ (*(self->vm))->AttachCurrentThread(self->vm, (void **)&jniEnv, NULL);
+ (*jniEnv)->DeleteGlobalRef(jniEnv, self->delegateObject);
+ self->delegateObject = NULL;
+ self->vm = NULL;
+ }
+ if (delegate)
+ {
+ delegate = (*jniEnv)->NewGlobalRef(jniEnv, delegate);
+ if (delegate)
+ {
+ (*jniEnv)->GetJavaVM(jniEnv, &(self->vm));
+ self->delegateObject = delegate;
+
+ // These notifications are filed on NSWorkspace's notification center,
+ // not the default notification center. You will not receive
+ // sleep/wake notifications if you file with the default
+ // notification center.
+ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
+ selector: @selector(receiveSleepNote:)
+ name: @"NSWorkspaceWillSleepNotification" object: NULL];
+
+ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
+ selector: @selector(receiveWakeNote:)
+ name: @"NSWorkspaceDidWakeNotification" object: NULL];
+
+ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
+ selector: @selector(receiveDisplayWakeNote:)
+ name: @"NSWorkspaceScreensDidWakeNotification" object: NULL];
+
+ [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver: self
+ selector: @selector(receiveDisplaySleepNote:)
+ name: @"NSWorkspaceScreensDidSleepNotification" object: NULL];
+
+ NSDistributedNotificationCenter * center =
+ [NSDistributedNotificationCenter defaultCenter];
+
+ [center addObserver:self
+ selector: @selector(screenIsLocked:)
+ name:@"com.apple.screenIsLocked" object:NULL];
+
+ [center addObserver:self
+ selector: @selector(screenIsUnlocked:)
+ name:@"com.apple.screenIsUnlocked" object:NULL];
+
+ [center addObserver:self
+ selector: @selector(screensaverStart:)
+ name:@"com.apple.screensaver.didstart" object:NULL];
+
+ [center addObserver:self
+ selector: @selector(screensaverWillStop:)
+ name:@"com.apple.screensaver.willstop" object:NULL];
+
+ [center addObserver:self
+ selector: @selector(screensaverStop:)
+ name:@"com.apple.screensaver.didstop" object:NULL];
+
+
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector: @selector(netChange:)
+ name:@"NetworkConfigurationDidChangeNotification" object:NULL];
+
+
+ SCDynamicStoreRef dynStore;
+
+ SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};
+
+ dynStore = SCDynamicStoreCreate(kCFAllocatorDefault,
+ CFBundleGetIdentifier(CFBundleGetMainBundle()),
+ scCallback,
+ &context);
+
+ const CFStringRef keys[1] = {
+ CFSTR("State:/Network/Interface/.*/Link")
+ };
+ CFArrayRef watchedKeys = CFArrayCreate(kCFAllocatorDefault,
+ (const void **)keys,
+ 1,
+ &kCFTypeArrayCallBacks);
+ if (!SCDynamicStoreSetNotificationKeys(dynStore,
+ NULL,
+ watchedKeys))
+ {
+ CFRelease(watchedKeys);
+ fprintf(stderr, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
+ CFRelease(dynStore);
+ dynStore = NULL;
+
+ return;
+ }
+ CFRelease(watchedKeys);
+
+
+ rlSrc = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynStore, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rlSrc, kCFRunLoopDefaultMode);
+ CFRelease(rlSrc);
+ }
+ }
+}
+
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ self->delegateObject = NULL;
+ self->vm = NULL;
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self setDelegate:NULL inJNIEnv:NULL];
+ [super dealloc];
+}
+
+- (void)clean
+{
+ [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver: self];
+
+ NSDistributedNotificationCenter * center =
+ [NSDistributedNotificationCenter defaultCenter];
+
+ [center removeObserver:self];
+
+ [self setDelegate:NULL inJNIEnv:NULL];
+}
+
+- (void)start
+{
+ loopRef = CFRunLoopGetCurrent();
+ CFRunLoopRun();
+}
+
+- (void)stop
+{
+ if(loopRef)
+ CFRunLoopStop(loopRef);
+}
+@end
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: setDelegate
+ * Signature: (Lnet/java/sip/communicator/impl/sysactivity/SystemActivityNotifications/NotificationsDelegate;)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_setDelegate
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr, jobject m_delegate)
+{
+ AISleepNotification *oDelegate;
+
+ if (m_delegate)
+ {
+ oDelegate = (AISleepNotification *) ptr;
+ [oDelegate setDelegate:m_delegate inJNIEnv:jniEnv];
+ }
+ else
+ oDelegate = nil;
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: allocAndInit
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_allocAndInit
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ AISleepNotification *oDelegate;
+ NSAutoreleasePool *autoreleasePool;
+ autoreleasePool = [[NSAutoreleasePool alloc] init];
+
+ oDelegate = [[AISleepNotification alloc] init];
+
+ [autoreleasePool release];
+
+ return (jlong)oDelegate;
+}
+
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_release
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ AISleepNotification *oDelegate;
+ NSAutoreleasePool *autoreleasePool;
+ autoreleasePool = [[NSAutoreleasePool alloc] init];
+
+ oDelegate = (AISleepNotification *) ptr;
+ [oDelegate clean];
+
+ [oDelegate release];
+
+ [autoreleasePool release];
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: start
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_start
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ AISleepNotification *oDelegate;
+ oDelegate = (AISleepNotification *) ptr;
+ [oDelegate start];
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: stop
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_stop
+ (JNIEnv* jniEnv, jclass clazz, jlong ptr)
+{
+ AISleepNotification *oDelegate;
+ oDelegate = (AISleepNotification *) ptr;
+ [oDelegate stop];
+}
+
+/*
+ * Class: net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications
+ * Method: getLastInput
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_net_java_sip_communicator_impl_sysactivity_SystemActivityNotifications_getLastInput
+ (JNIEnv* jniEnv, jclass clazz)
+{
+ int64_t idlesecs = -1;
+ io_iterator_t iter = 0;
+ if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
+ io_registry_entry_t entry = IOIteratorNext(iter);
+ if (entry) {
+ CFMutableDictionaryRef dict = NULL;
+ if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) {
+ CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
+ if (obj) {
+ int64_t nanoseconds = 0;
+ if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) {
+ idlesecs = nanoseconds / 1000000;
+ }
+ }
+ CFRelease(dict);
+ }
+ IOObjectRelease(entry);
+ }
+ IOObjectRelease(iter);
+ }
+ return idlesecs;
+}
diff --git a/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java b/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java
index e70881fe6..d645ef81b 100644
--- a/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java
+++ b/src/net/java/sip/communicator/impl/netaddr/NetaddrActivator.java
@@ -147,4 +147,15 @@ public void stop(BundleContext bundleContext)
if (logger.isInfoEnabled())
logger.info("Network Address Manager Service ...[STOPPED]");
}
+
+ /**
+ * Returns a reference to the bundle context that we were started with.
+ *
+ * @return a reference to the BundleContext instance that we were started
+ * with.
+ */
+ static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/netaddr/NetworkConfigurationWatcher.java b/src/net/java/sip/communicator/impl/netaddr/NetworkConfigurationWatcher.java
index bff54db20..ab0a188f5 100644
--- a/src/net/java/sip/communicator/impl/netaddr/NetworkConfigurationWatcher.java
+++ b/src/net/java/sip/communicator/impl/netaddr/NetworkConfigurationWatcher.java
@@ -9,8 +9,12 @@
import java.lang.reflect.*;
import java.net.*;
import java.util.*;
+
import net.java.sip.communicator.service.netaddr.event.*;
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.service.sysactivity.event.*;
import net.java.sip.communicator.util.*;
+import org.osgi.framework.*;
/**
* Periodically checks the current network interfaces to track changes
@@ -19,7 +23,8 @@
* @author Damian Minkov
*/
public class NetworkConfigurationWatcher
- implements Runnable
+ implements SystemActivityChangeListener,
+ ServiceListener
{
/**
* Our class logger.
@@ -27,11 +32,6 @@ public class NetworkConfigurationWatcher
private static Logger logger =
Logger.getLogger(NetworkConfigurationWatcher.class);
- /**
- * Interval between check of network configuration.
- */
- private static final int CHECK_INTERVAL = 3000; // 3 sec.
-
/**
* Listers for network configuration changes.
*/
@@ -39,9 +39,24 @@ public class NetworkConfigurationWatcher
new ArrayList();
/**
- * Whether current thread is running.
+ * The current active interfaces.
+ */
+ private List activeInterfaces
+ = new ArrayList();
+
+ /**
+ * Service we use to listen for network changes.
*/
- private boolean isRunning = false;
+ private SystemActivityNotificationsService
+ systemActivityNotificationsService = null;
+
+ /**
+ * Inits configuration watcher.
+ */
+ NetworkConfigurationWatcher()
+ {
+ checkNetworkInterfaces(false);
+ }
/**
* Adds new NetworkConfigurationChangeListener which will
@@ -56,15 +71,14 @@ void addNetworkConfigurationChangeListener(
listeners.add(listener);
}
- if(!isRunning)
- {
- isRunning = true;
- Thread th = new Thread(this);
- // set to max priority to prevent detecting sleep if the cpu is
- // overloaded
- th.setPriority(Thread.MAX_PRIORITY);
- th.start();
- }
+ NetaddrActivator.getBundleContext().addServiceListener(this);
+
+ this.systemActivityNotificationsService
+ = ServiceUtils.getService(
+ NetaddrActivator.getBundleContext(),
+ SystemActivityNotificationsService.class);
+ this.systemActivityNotificationsService
+ .addSystemActivityChangeListener(this);
}
/**
@@ -81,147 +95,44 @@ void removeNetworkConfigurationChangeListener(
}
/**
- * Main loop of this thread.
+ * When new protocol provider is registered we add needed listeners.
+ *
+ * @param serviceEvent ServiceEvent
*/
- public void run()
+ public void serviceChanged(ServiceEvent serviceEvent)
{
- long last = 0;
- boolean isAfterStandby = false;
-
- List activeInterfaces =
- new ArrayList();
+ ServiceReference serviceRef = serviceEvent.getServiceReference();
- while(isRunning)
+ // 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)
{
- long curr = System.currentTimeMillis();
-
- // if time spent between checks is more than 4 times
- // longer than the check interval we consider it as a
- // new check after standby
- if(!isAfterStandby && last != 0)
- isAfterStandby = (last + 4*CHECK_INTERVAL - curr) < 0;
-
- if(isAfterStandby)
- {
- // oo standby lets fire down to all interfaces
- // so they can reconnect
- Iterator iter = activeInterfaces.iterator();
- while (iter.hasNext())
- {
- NetworkInterface niface = iter.next();
- fireChangeEvent(new ChangeEvent(niface,
- ChangeEvent.IFACE_DOWN, isAfterStandby));
- }
- activeInterfaces.clear();
-
- // we have fired events for standby, make it to false now
- // so we can calculate it again next time
- isAfterStandby = false;
-
- last = curr;
-
- // give time to interfaces
- synchronized(this)
- {
- try{
- wait(CHECK_INTERVAL);
- }
- catch (Exception e){}
- }
-
- continue;
- }
-
- try
- {
- Enumeration e =
- NetworkInterface.getNetworkInterfaces();
-
- boolean networkIsUP = activeInterfaces.size() > 0;
-
- List currentActiveInterfaces =
- new ArrayList();
-
- while (e.hasMoreElements())
- {
- NetworkInterface networkInterface = e.nextElement();
-
- if(isInterfaceLoopback(networkInterface))
- continue;
-
- // if interface is up and has some valid(non-local) address
- if(isInterfaceUp(networkInterface)
- && hasValidAddress(networkInterface))
- {
- currentActiveInterfaces.add(networkInterface);
- }
- }
-
- List inactiveActiveInterfaces =
- new ArrayList(activeInterfaces);
- inactiveActiveInterfaces.removeAll(currentActiveInterfaces);
-
- // fire that interface has gone down
- for (int i = 0; i < inactiveActiveInterfaces.size(); i++)
- {
- NetworkInterface iface = inactiveActiveInterfaces.get(i);
-
- if(!containsInterfaceWithName(
- currentActiveInterfaces, iface.getName()))
- {
- fireChangeEvent(new ChangeEvent(iface,
- ChangeEvent.IFACE_DOWN, isAfterStandby));
-
- activeInterfaces.remove(iface);
- }
- }
-
- // now we leave with only with the new and up interfaces
- // in currentActiveInterfaces list
- currentActiveInterfaces.removeAll(activeInterfaces);
-
- // calm for a while, we sometimes receive those events and
- // configuration has not yet finished (dns can be the old one)
- if(currentActiveInterfaces.size() != 0)
- {
- synchronized(this)
- {
- try{
- wait(1000);
- }catch(InterruptedException ex){}
- }
- }
-
- // fire that interface has gone up
- for (int i = 0; i < currentActiveInterfaces.size(); i++)
- {
- NetworkInterface iface = currentActiveInterfaces.get(i);
+ return;
+ }
- fireChangeEvent(new ChangeEvent(iface,
- ChangeEvent.IFACE_UP, isAfterStandby));
- activeInterfaces.add(iface);
- }
+ Object sService = NetaddrActivator.getBundleContext()
+ .getService(serviceRef);
- // fire that network has gone up
- if(!networkIsUP && activeInterfaces.size() > 0)
- {
- isAfterStandby = false;
- }
-
- // save the last time that we checked
- last = System.currentTimeMillis();
- } catch (SocketException e)
+ if(sService instanceof SystemActivityNotificationsService)
+ {
+ switch (serviceEvent.getType())
{
- logger.error("Error checking network interfaces", e);
+ case ServiceEvent.REGISTERED:
+ if(this.systemActivityNotificationsService != null)
+ break;
+
+ this.systemActivityNotificationsService =
+ (SystemActivityNotificationsService)sService;
+ systemActivityNotificationsService
+ .addSystemActivityChangeListener(this);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ ((SystemActivityNotificationsService)sService)
+ .addSystemActivityChangeListener(this);
+ break;
}
- synchronized(this)
- {
- try{
- wait(CHECK_INTERVAL);
- }
- catch (Exception e){}
- }
+ return;
}
}
@@ -251,15 +162,10 @@ private void fireChangeEvent(ChangeEvent evt)
/**
- * Stop current running thread.
+ * Stop.
*/
void stop()
{
- synchronized(this)
- {
- isRunning = false;
- notifyAll();
- }
}
/**
@@ -361,4 +267,90 @@ public static boolean isInterfaceUp(NetworkInterface iface)
return true;
}
+
+ public void activityChanged(SystemActivityEvent event)
+ {
+ if(event.getEventID() == SystemActivityEvent.EVENT_SLEEP)
+ {
+ // oo standby lets fire down to all interfaces
+ // so they can reconnect
+ Iterator iter = activeInterfaces.iterator();
+ while (iter.hasNext())
+ {
+ NetworkInterface niface = iter.next();
+ fireChangeEvent(new ChangeEvent(niface,
+ ChangeEvent.IFACE_DOWN, true));
+ }
+ activeInterfaces.clear();
+ }
+ else if(event.getEventID() == SystemActivityEvent.EVENT_NETWORK_CHANGE)
+ {
+ checkNetworkInterfaces(true);
+ }
+ }
+
+ private void checkNetworkInterfaces(boolean fireEvents)
+ {
+ try
+ {
+ Enumeration e =
+ NetworkInterface.getNetworkInterfaces();
+
+ List currentActiveInterfaces =
+ new ArrayList();
+
+ while (e.hasMoreElements())
+ {
+ NetworkInterface networkInterface = e.nextElement();
+
+ if(isInterfaceLoopback(networkInterface))
+ continue;
+
+ // if interface is up and has some valid(non-local) address
+ if(isInterfaceUp(networkInterface)
+ && hasValidAddress(networkInterface))
+ {
+ currentActiveInterfaces.add(networkInterface);
+ }
+ }
+
+ List inactiveActiveInterfaces =
+ new ArrayList(activeInterfaces);
+ inactiveActiveInterfaces.removeAll(currentActiveInterfaces);
+
+ // fire that interface has gone down
+ for (int i = 0; i < inactiveActiveInterfaces.size(); i++)
+ {
+ NetworkInterface iface = inactiveActiveInterfaces.get(i);
+
+ if(!containsInterfaceWithName(
+ currentActiveInterfaces, iface.getName()))
+ {
+ if(fireEvents)
+ fireChangeEvent(new ChangeEvent(iface,
+ ChangeEvent.IFACE_DOWN, false));
+
+ activeInterfaces.remove(iface);
+ }
+ }
+
+ // now we leave with only with the new and up interfaces
+ // in currentActiveInterfaces list
+ currentActiveInterfaces.removeAll(activeInterfaces);
+
+ // fire that interface has gone up
+ for (int i = 0; i < currentActiveInterfaces.size(); i++)
+ {
+ NetworkInterface iface = currentActiveInterfaces.get(i);
+
+ if(fireEvents)
+ fireChangeEvent(new ChangeEvent(iface,
+ ChangeEvent.IFACE_UP, false));
+ activeInterfaces.add(iface);
+ }
+ } catch (SocketException e)
+ {
+ logger.error("Error checking network interfaces", e);
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
index 6a83aae72..248827827 100644
--- a/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
+++ b/src/net/java/sip/communicator/impl/netaddr/netaddr.manifest.mf
@@ -7,6 +7,8 @@ System-Bundle: yes
Import-Package: net.java.sip.communicator.service.configuration,
net.java.sip.communicator.service.packetlogging,
net.java.sip.communicator.util,
+ net.java.sip.communicator.service.sysactivity,
+ net.java.sip.communicator.service.sysactivity.event,
org.osgi.framework,
org.ice4j.stack,
org.xml.sax,
diff --git a/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java
new file mode 100644
index 000000000..d13b3271c
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/sysactivity/NetworkManagerListenerImpl.java
@@ -0,0 +1,153 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.*;
+import org.freedesktop.*;
+import org.freedesktop.dbus.*;
+import org.freedesktop.dbus.exceptions.*;
+
+/**
+ * Responsible for subscribe and dispatch signals from NetworkManager.
+ * Uses dbus to connect.
+ *
+ * @author Damian Minkov
+ */
+public class NetworkManagerListenerImpl
+ implements DBusSigHandler
+{
+ /**
+ * The logger.
+ */
+ private Logger logger = Logger.getLogger(
+ NetworkManagerListenerImpl.class.getName());
+
+ /**
+ * The only instance of this impl.
+ */
+ private static NetworkManagerListenerImpl networkManagerListenerImpl;
+
+ /**
+ * Dbus connection we use.
+ */
+ private DBusConnection dbusConn;
+
+ /**
+ * Make only one instance.
+ */
+ private NetworkManagerListenerImpl()
+ {
+ try
+ {
+ dbusConn = DBusConnection.getConnection(DBusConnection.SYSTEM);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Cannot obtain dbus connection", e);
+ }
+ }
+
+ /**
+ * Gets the instance of NetworkManagerListenerImpl.
+ * @return the NetworkManagerListenerImpl.
+ */
+ public static NetworkManagerListenerImpl getInstance()
+ {
+ if(networkManagerListenerImpl == null)
+ networkManagerListenerImpl = new NetworkManagerListenerImpl();
+
+ return networkManagerListenerImpl;
+ }
+
+ /**
+ * Starts
+ */
+ public void start()
+ {
+ try
+ {
+ dbusConn.addSigHandler(DBus.NameOwnerChanged.class, this);
+ dbusConn.addSigHandler(NetworkManager.StateChange.class, this);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Error adding dbus signal handlers", e);
+ }
+ }
+
+ /**
+ * Stops.
+ */
+ public void stop()
+ {
+ try
+ {
+ dbusConn.removeSigHandler(DBus.NameOwnerChanged.class, this);
+ dbusConn.removeSigHandler(NetworkManager.StateChange.class, this);
+ }
+ catch(DBusException e)
+ {
+ logger.error("Error removing dbus signal handlers", e);
+ }
+ }
+
+ /**
+ * Receives signals and dispatch them.
+ * @param dBusSignal
+ */
+ public void handle(DBusSignal dBusSignal)
+ {
+ if(dBusSignal instanceof DBus.NameOwnerChanged)
+ {
+ DBus.NameOwnerChanged nameOwnerChanged =
+ (DBus.NameOwnerChanged)dBusSignal;
+
+ if(nameOwnerChanged.name.equals(NetworkManager.class.getName()))
+ {
+ boolean b1 = nameOwnerChanged.old_owner != null
+ && nameOwnerChanged.old_owner.length() > 0;
+ boolean b2 = nameOwnerChanged.new_owner != null
+ && nameOwnerChanged.new_owner.length() > 0;
+
+ if(b1 && !b2)
+ {
+ SystemActivityEvent evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ SysActivityActivator.getSystemActivityService()
+ .fireSystemActivityEvent(evt);
+ }
+ }
+ }
+ else if(dBusSignal instanceof NetworkManager.StateChange)
+ {
+ NetworkManager.StateChange stateChange =
+ (NetworkManager.StateChange)dBusSignal;
+
+ SystemActivityEvent evt = null;
+ switch(stateChange.getStatus())
+ {
+ case NetworkManager.NM_STATE_CONNECTED:
+ case NetworkManager.NM_STATE_DISCONNECTED:
+ evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ break;
+ case NetworkManager.NM_STATE_ASLEEP:
+ evt = new SystemActivityEvent(
+ SysActivityActivator.getSystemActivityService(),
+ SystemActivityEvent.EVENT_SLEEP);
+ break;
+ }
+
+ if(evt != null)
+ SysActivityActivator.getSystemActivityService()
+ .fireSystemActivityEvent(evt);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java
new file mode 100644
index 000000000..ea60cfc7b
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/sysactivity/SysActivityActivator.java
@@ -0,0 +1,108 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.*;
+import org.osgi.framework.*;
+
+import net.java.sip.communicator.util.*;
+
+/**
+ * Listens for system activity changes like sleep, network change, inactivity
+ * and inform all its listeners.
+ *
+ * @author Damian Minkov
+ */
+public class SysActivityActivator
+ implements BundleActivator
+{
+ /**
+ * The logger.
+ */
+ private Logger logger = Logger.getLogger(
+ SysActivityActivator.class.getName());
+
+ /**
+ * The OSGi service registration.
+ */
+ private ServiceRegistration sysActivitiesServReg = null;
+
+ /**
+ * The OSGi BundleContext.
+ */
+ private static BundleContext bundleContext = null;
+
+ /**
+ * The system activity service impl.
+ */
+ private static SystemActivityNotificationsServiceImpl sysActivitiesServiceImpl;
+
+ /**
+ * Called when this bundle is started so the Framework can perform the
+ * bundle-specific activities necessary to start this bundle.
+ *
+ * @param context The execution context of the bundle being started.
+ * @throws Exception If this method throws an exception, this bundle is
+ * marked as stopped and the Framework will remove this bundle's
+ * listeners, unregister all services registered by this bundle, and
+ * release all services used by this bundle.
+ */
+ public void start(BundleContext context)
+ throws Exception
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Started.");
+ SysActivityActivator.bundleContext = context;
+
+ sysActivitiesServiceImpl = new SystemActivityNotificationsServiceImpl();
+ sysActivitiesServiceImpl.start();
+
+ sysActivitiesServReg = context.registerService(
+ SystemActivityNotificationsService.class.getName(),
+ sysActivitiesServiceImpl,
+ null);
+ }
+
+ /**
+ * Returns a reference to the bundle context that we were started with.
+ * @return a reference to the BundleContext instance that we were started
+ * witn.
+ */
+ public static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+
+ /**
+ * Returns a reference to the bundle context that we were started with.
+ * @return a reference to the BundleContext instance that we were started
+ * witn.
+ */
+ public static SystemActivityNotificationsServiceImpl
+ getSystemActivityService()
+ {
+ return sysActivitiesServiceImpl;
+ }
+
+ /**
+ * Called when this bundle is stopped so the Framework can perform the
+ * bundle-specific activities necessary to stop the bundle.
+ *
+ * @param context The execution context of the bundle being stopped.
+ * @throws Exception If this method throws an exception, the bundle is
+ * still marked as stopped, and the Framework will remove the bundle's
+ * listeners, unregister all services registered by the bundle, and
+ * release all services used by the bundle.
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ sysActivitiesServReg.unregister();
+
+ if(sysActivitiesServiceImpl != null)
+ sysActivitiesServiceImpl.stop();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java
new file mode 100644
index 000000000..6264b4971
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotifications.java
@@ -0,0 +1,194 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.util.*;
+
+/**
+ * @author Damian Minkov
+ */
+public class SystemActivityNotifications
+{
+ /**
+ * Notify that computers is going to sleep.
+ */
+ public static final int NOTIFY_SLEEP = 0;
+
+ /**
+ * Notify that computer is wakeing up after stand by.
+ */
+ public static final int NOTIFY_WAKE = 1;
+
+ /**
+ * Computer display has stand by.
+ */
+ public static final int NOTIFY_DISPLAY_SLEEP = 2;
+
+ /**
+ * Computer display wakes up after stand by.
+ */
+ public static final int NOTIFY_DISPLAY_WAKE = 3;
+
+ /**
+ * Screensaver has been started.
+ */
+ public static final int NOTIFY_SCREENSAVER_START = 4;
+
+ /**
+ * Screensaver will stop.
+ */
+ public static final int NOTIFY_SCREENSAVER_WILL_STOP = 5;
+
+ /**
+ * Screensaver has been stopped.
+ */
+ public static final int NOTIFY_SCREENSAVER_STOP = 6;
+
+ /**
+ * Screen has been locked.
+ */
+ public static final int NOTIFY_SCREEN_LOCKED = 7;
+
+ /**
+ * Screen has been unlocked.
+ */
+ public static final int NOTIFY_SCREEN_UNLOCKED = 8;
+
+ /**
+ * A change in network configuration has occurred.
+ */
+ public static final int NOTIFY_NETWORK_CHANGE = 9;
+
+ /**
+ * The logger.
+ */
+ private static Logger logger = Logger.getLogger(
+ SystemActivityNotifications.class.getName());
+
+ /**
+ * The native instance.
+ */
+ private static long notifierInstance = -1;
+
+ /**
+ * Init native library.
+ */
+ static
+ {
+ try
+ {
+ System.loadLibrary("sysactivitynotifications");
+
+ notifierInstance = allocAndInit();
+ }
+ catch(Throwable t)
+ {
+ logger.error("Error init native functions", t);
+ }
+ }
+
+ /**
+ * Allocate native resources and gets a pointer.
+ * @return
+ */
+ private static native long allocAndInit();
+
+ /**
+ * Release native resources.
+ * @param ptr
+ */
+ private static native void release(long ptr);
+
+ /**
+ * Sets delegate.
+ * @param delegate
+ */
+ public static void setDelegate(NotificationsDelegate delegate)
+ {
+ if(notifierInstance != -1)
+ {
+ setDelegate(notifierInstance, delegate);
+ }
+ }
+
+ /**
+ * Sets notifier delegate.
+ * @param ptr
+ * @param delegate
+ */
+ public static native void setDelegate(long ptr, NotificationsDelegate delegate);
+
+ /**
+ * Start processing.
+ * @param ptr
+ */
+ private static native void start(long ptr);
+
+ /**
+ * Stop processing.
+ * @param ptr
+ */
+ private static native void stop(long ptr);
+
+ /**
+ * Start.
+ */
+ public static void start()
+ {
+ if(notifierInstance != -1)
+ start(notifierInstance);
+ }
+
+ /**
+ * Stop.
+ */
+ public static void stop()
+ {
+ if(notifierInstance != -1)
+ {
+ stop(notifierInstance);
+ release(notifierInstance);
+ notifierInstance = -1;
+ }
+ }
+
+ /**
+ * Returns the when was last input in milliseconds. The time when
+ * there was any activity on the computer.
+ * @return
+ */
+ public static native long getLastInput();
+
+ /**
+ * Delegate class to be notified for changes.
+ */
+ public static abstract class NotificationsDelegate
+ {
+ /**
+ * Callback method when receiving notifications.
+ *
+ * @param type
+ */
+ public abstract void notify(int type);
+
+ /**
+ * Callback method when receiving special network notifications.
+ *
+ * @param family family of network change (ipv6, ipv4)
+ * @param luidIndex unique index of interface
+ * @param name name of the interface
+ * @param type of the interface
+ * @param connected whether interface is connected or not.
+ */
+ public abstract void notifyNetworkChange(
+ int family,
+ long luidIndex,
+ String name,
+ long type,
+ boolean connected);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java
new file mode 100644
index 000000000..4d7c12dbd
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/sysactivity/SystemActivityNotificationsServiceImpl.java
@@ -0,0 +1,474 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.*;
+
+import java.util.*;
+
+/**
+ * Service implementation listens for computer changes as sleeping, network
+ * change, inactivity.
+ *
+ * @author Damian Minkov
+ */
+public class SystemActivityNotificationsServiceImpl
+ extends SystemActivityNotifications.NotificationsDelegate
+ implements SystemActivityNotificationsService,
+ Runnable
+{
+ /**
+ * The logger.
+ */
+ private Logger logger = Logger.getLogger(
+ SystemActivityNotificationsServiceImpl.class.getName());
+
+ /**
+ * A list of listeners registered for system activity events.
+ */
+ private final List activityChangeListeners =
+ new LinkedList();
+
+ /**
+ * A list of listeners registered for idle events.
+ */
+ private final Map idleChangeListeners =
+ new HashMap();
+
+ /**
+ * Listeners which are fired for idle state and which will be fired
+ * with idle end when needed.
+ */
+ private final List listenersInIdleState
+ = new ArrayList();
+
+ /**
+ * The time in milliseconds between two checks for system idle.
+ */
+ private static final int idleStateCheckDelay = 10*1000;
+
+ /**
+ * Whether current service is started or stopped.
+ */
+ private boolean running = false;
+
+ /**
+ * The time when we received latest network change event.
+ */
+ private long lastNetworkChange = -1;
+
+ /**
+ * Sometimes (on windows) we got several network change events
+ * this is the time after which latest event we will skip next events.
+ */
+ private static final long NETWORK_EVENT_SILENT_TIME = 10*1000;
+
+ /**
+ * Whether network is currently connected.
+ */
+ private Boolean networkIsConnected = null;
+
+ /**
+ * Init and start notifications.
+ */
+ public void start()
+ {
+ running = true;
+
+ // set the delegate and start notification in new thread
+ // make sure we don't block startup process
+ Thread notifystartThread = new Thread(new Runnable() {
+ public void run()
+ {
+ SystemActivityNotifications.setDelegate(
+ SystemActivityNotificationsServiceImpl.this);
+ SystemActivityNotifications.start();
+ }
+ }, "SystemActivityNotificationsServiceImpl");
+ notifystartThread.setDaemon(true);
+ notifystartThread.start();
+
+ // a thread periodically checks system idle state and if it pass the
+ // idle time for a particular listener, will inform it.
+ Thread idleNotifyThread = new Thread(this,
+ "SystemActivityNotificationsServiceImpl.IdleNotifyThread");
+ idleNotifyThread.setDaemon(true);
+ idleNotifyThread.start();
+
+ if(OSUtils.IS_LINUX)
+ {
+ NetworkManagerListenerImpl.getInstance().start();
+ }
+ }
+
+ /**
+ * Stop notifications.
+ */
+ public void stop()
+ {
+ SystemActivityNotifications.stop();
+
+ if(OSUtils.IS_LINUX)
+ {
+ NetworkManagerListenerImpl.getInstance().stop();
+ }
+
+ running = false;
+
+ synchronized(this)
+ {
+ this.notifyAll();
+ }
+ }
+
+ /**
+ * Registers a listener that would be notified of changes that have occurred
+ * in the underlying system.
+ *
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addSystemActivityChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ synchronized (activityChangeListeners)
+ {
+ if (!activityChangeListeners.contains(listener))
+ {
+ activityChangeListeners.add(listener);
+ }
+ }
+ }
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications of changes that occur in the underlying system
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeSystemActivityChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ synchronized (activityChangeListeners)
+ {
+ activityChangeListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Registers a listener that would be notified for idle of the system
+ * for idleTime.
+ *
+ * @param idleTime the time in milliseconds after which we will consider
+ * system to be idle. This doesn't count when system seems idle as
+ * monitor is off or screensaver is on, or desktop is locked.
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addIdleSystemChangeListener(
+ long idleTime,
+ SystemActivityChangeListener listener)
+ {
+ synchronized (idleChangeListeners)
+ {
+ if (!idleChangeListeners.containsKey(listener))
+ {
+ idleChangeListeners.put(listener, idleTime);
+ }
+ }
+ }
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications for idle system.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeIdleSystemChangeListener(
+ SystemActivityChangeListener listener)
+ {
+ synchronized (idleChangeListeners)
+ {
+ idleChangeListeners.remove(listener);
+ }
+ }
+
+ /**
+ * Callback method when receiving notifications.
+ *
+ * @param type
+ */
+ @Override
+ public void notify(int type)
+ {
+ SystemActivityEvent evt = null;
+ switch(type)
+ {
+ case SystemActivityNotifications.NOTIFY_SLEEP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SLEEP);
+ break;
+ case SystemActivityNotifications.NOTIFY_WAKE :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_WAKE);
+ break;
+ case SystemActivityNotifications.NOTIFY_DISPLAY_SLEEP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_DISPLAY_SLEEP);
+ break;
+ case SystemActivityNotifications.NOTIFY_DISPLAY_WAKE :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_DISPLAY_WAKE);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_START :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_START);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_WILL_STOP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_WILL_STOP);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREENSAVER_STOP :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREENSAVER_STOP);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREEN_LOCKED :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREEN_LOCKED);
+ break;
+ case SystemActivityNotifications.NOTIFY_SCREEN_UNLOCKED :
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_SCREEN_UNLOCKED);
+ break;
+ case SystemActivityNotifications.NOTIFY_NETWORK_CHANGE :
+ {
+ evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ break;
+ }
+ }
+
+ if(evt != null)
+ fireSystemActivityEvent(evt);
+ }
+
+ /**
+ * Callback method when receiving special network notifications.
+ *
+ * @param family family of network change (ipv6, ipv4)
+ * AF_UNSPEC = 0 (The address family is unspecified.)
+ * AF_INET = 2 (The Internet Protocol version 4 (IPv4) address family)
+ * AF_INET6 = 23 (The Internet Protocol version 6 (IPv6) address family)
+ * @param luidIndex unique index of interface
+ * @param name name of the interface
+ * @param type of the interface
+ * Possible values for the interface type are listed in the Ipifcons.h file.
+ * common values:
+ * IF_TYPE_OTHER = 1 (Some other type of network interface.)
+ * IF_TYPE_ETHERNET_CSMACD = 6 (An Ethernet network interface.)
+ * IF_TYPE_ISO88025_TOKENRING = 9 (A token ring network interface.)
+ * IF_TYPE_PPP = 23 (A PPP network interface.)
+ * IF_TYPE_SOFTWARE_LOOPBACK = 24 (A software loopback network interface.)
+ * IF_TYPE_IEEE80211 = 71 (An IEEE 802.11 wireless network interface.)
+ * IF_TYPE_TUNNEL = 131 (A tunnel type encapsulation network interface.)
+ * IF_TYPE_IEEE1394 = 144 (An IEEE 1394 (Firewire) high performance
+ * serial bus network interface.)
+ * @param connected whether interface is connected or not.
+ */
+ @Override
+ public void notifyNetworkChange(
+ int family,
+ long luidIndex,
+ String name,
+ long type,
+ boolean connected)
+ {
+ long current = System.currentTimeMillis();
+ if(current - lastNetworkChange <= NETWORK_EVENT_SILENT_TIME
+ && (networkIsConnected != null && networkIsConnected.equals(connected)))
+ {
+ networkIsConnected = connected;
+ return;
+ }
+
+ lastNetworkChange = current;
+ networkIsConnected = connected;
+
+ SystemActivityEvent evt = new SystemActivityEvent(this,
+ SystemActivityEvent.EVENT_NETWORK_CHANGE);
+ fireSystemActivityEvent(evt);
+ }
+
+ /**
+ * The thread run method that handles idle notifies.
+ *
+ * @see Thread#run()
+ */
+ public void run()
+ {
+ while(running)
+ {
+ try
+ {
+ if(idleChangeListeners.size() > 0)
+ {
+ // check
+ long idleTime = SystemActivityNotifications.getLastInput();
+
+ if(idleTime < idleStateCheckDelay
+ && listenersInIdleState.size() > 0)
+ {
+ for(SystemActivityChangeListener l: listenersInIdleState)
+ {
+ fireSystemIdleEndEvent(l);
+ }
+ listenersInIdleState.clear();
+ }
+
+ for(Map.Entry entry :
+ idleChangeListeners.entrySet())
+ {
+ if(entry.getValue().longValue() <= idleTime)
+ {
+ fireSystemIdleEvent(entry.getKey());
+
+ listenersInIdleState.add(entry.getKey());
+ }
+ }
+ }
+
+ // wait for the specified time
+ synchronized(this)
+ {
+ this.wait(idleStateCheckDelay);
+ }
+ }
+ catch(UnsatisfiedLinkError t)
+ {
+ logger.error("Missing native impl", t);
+ return;
+ }
+ catch(Throwable t)
+ {
+ logger.error("Error checking for idle", t);
+ }
+ }
+ }
+
+ /**
+ * Delivers the specified event to all registered listeners.
+ *
+ * @param evt the SystemActivityEvent that we'd like delivered to
+ * all registered message listeners.
+ */
+ protected void fireSystemActivityEvent(SystemActivityEvent evt)
+ {
+ Collection listeners = null;
+ synchronized (this.activityChangeListeners)
+ {
+ listeners = new ArrayList(
+ this.activityChangeListeners);
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent Listeners="
+ + listeners.size() + " evt=" + evt);
+
+ for (SystemActivityChangeListener listener : listeners)
+ {
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable e)
+ {
+ logger.error("Error delivering event", e);
+ }
+ }
+ }
+
+ /**
+ * Delivers the specified event to all registered listeners.
+ *
+ * @param evt the SystemActivityEvent that we'd like delivered to
+ * all registered message listeners.
+ */
+ protected void fireSystemIdleEvent(SystemActivityEvent evt)
+ {
+ Collection listeners = null;
+ synchronized (this.idleChangeListeners)
+ {
+ listeners = new ArrayList(
+ this.idleChangeListeners.keySet());
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent Listeners="
+ + listeners.size() + " evt=" + evt);
+
+ for (SystemActivityChangeListener listener : listeners)
+ {
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable e)
+ {
+ logger.error("Error delivering event", e);
+ }
+ }
+ }
+
+ /**
+ * Delivers the specified event to all registered listeners.
+ *
+ * @param listener listener to inform
+ */
+ protected void fireSystemIdleEvent(SystemActivityChangeListener listener)
+ {
+ SystemActivityEvent evt = new SystemActivityEvent(
+ this, SystemActivityEvent.EVENT_SYSTEM_IDLE);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent evt=" + evt);
+
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable e)
+ {
+ logger.error("Error delivering event", e);
+ }
+ }
+
+ /**
+ * Delivers the specified event to listener.
+ *
+ * @param listener listener to inform
+ */
+ protected void fireSystemIdleEndEvent(
+ SystemActivityChangeListener listener)
+ {
+ SystemActivityEvent evt = new SystemActivityEvent(
+ this, SystemActivityEvent.EVENT_SYSTEM_IDLE_END);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Dispatching SystemActivityEvent evt=" + evt);
+
+ try
+ {
+ listener.activityChanged(evt);
+ }
+ catch (Throwable e)
+ {
+ logger.error("Error delivering event", e);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf b/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf
new file mode 100644
index 000000000..db284f9ef
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf
@@ -0,0 +1,13 @@
+Bundle-Activator: net.java.sip.communicator.impl.sysactivity.SysActivityActivator
+Bundle-Name: System Activity Service Implementation
+Bundle-Description: System Activity Service Implementation.
+Bundle-Vendor: sip-communicator.org
+Bundle-Version: 0.0.1
+System-Bundle: yes
+Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.configuration,
+ net.java.sip.communicator.service.resources,
+ net.java.sip.communicator.util,
+ net.java.sip.communicator.service.version
+Export-Package: net.java.sip.communicator.service.sysactivity,
+ net.java.sip.communicator.service.sysactivity.event
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
index 5b9438778..25c09791f 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigPluginActivator.java
@@ -50,22 +50,17 @@ public class GeneralConfigPluginActivator
/**
* The bundle context.
*/
- protected static BundleContext bundleContext;
+ public static BundleContext bundleContext;
/**
* The user interface service.
*/
private static UIService uiService;
- /**
- * The auto away thread.
- */
- private static Thread autoAwayThread = null;
-
/**
* The status update thread.
*/
- private static StatusUpdateThread runner = null;
+ private static AutoAwayWatcher runner = null;
/**
* The indicator which determines whether {@link #startThread()} has been
@@ -264,27 +259,8 @@ public void serviceChanged(ServiceEvent serviceEvent)
*/
private static void startThread()
{
- /*
- * FIXME Even if auto away is disabled at this point, it doesn't mean
- * that it will not get enabled later on so this method likely has to
- * also be called when the configuration property gets changed.
- */
- if (!getConfigurationService().getBoolean(Preferences.ENABLE, false))
- return;
-
if (runner == null)
- runner = new StatusUpdateThread();
- if ((autoAwayThread == null) || !runner.isRunning())
- {
- autoAwayThread = new Thread(runner);
- autoAwayThread.setName(GeneralConfigPluginActivator.class.getName());
- autoAwayThread.setPriority(Thread.MIN_PRIORITY);
- autoAwayThread.setDaemon(true);
- autoAwayThread.start();
- } else
- {
- autoAwayThread.interrupt();
- }
+ runner = new AutoAwayWatcher(getConfigurationService());
}
/**
@@ -297,11 +273,6 @@ private static void stopThread()
runner.stop();
runner = null;
}
- if (autoAwayThread != null)
- {
- autoAwayThread.interrupt();
- autoAwayThread = null;
- }
}
/**
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java
new file mode 100644
index 000000000..a90013b01
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/AutoAwayWatcher.java
@@ -0,0 +1,207 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.plugin.generalconfig.autoaway;
+
+import net.java.sip.communicator.plugin.generalconfig.*;
+import net.java.sip.communicator.service.configuration.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.sysactivity.*;
+import net.java.sip.communicator.service.sysactivity.event.*;
+import net.java.sip.communicator.util.*;
+
+import java.beans.*;
+import java.util.*;
+
+/**
+ * Listens for idle events from SystemActivityNotifications Service.
+ * @author Damian Minkov
+ */
+public class AutoAwayWatcher
+ implements SystemActivityChangeListener
+{
+ /**
+ * The states of providers before going to away.
+ */
+ private final Map lastStates
+ = new HashMap();
+
+ /**
+ * Creates AutoAway handler.
+ * @param configurationService the config service.
+ */
+ public AutoAwayWatcher(ConfigurationService configurationService)
+ {
+ // if enabled start
+ if(configurationService.getBoolean(Preferences.ENABLE, false))
+ start();
+
+ // listens for changes in configuration enable/disable
+ configurationService.addPropertyChangeListener(
+ Preferences.ENABLE,
+ new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if(Boolean.parseBoolean((String)evt.getNewValue()))
+ start();
+ else
+ stop();
+ }
+ }
+ );
+
+ // listens for changes in configured value.
+ configurationService.addPropertyChangeListener(
+ Preferences.TIMER,
+ new PropertyChangeListener()
+ {
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ stop();
+ start();
+ }
+ }
+ );
+ }
+
+ /**
+ * Starts and add needed listeners.
+ */
+ public void start()
+ {
+ getSystemActivityNotificationsService()
+ .addIdleSystemChangeListener(
+ StatusUpdateThread.getTimer()*60*1000, this);
+ getSystemActivityNotificationsService()
+ .addSystemActivityChangeListener(this);
+ }
+
+ /**
+ * Stops and removes the listeners.
+ */
+ public void stop()
+ {
+ getSystemActivityNotificationsService()
+ .removeIdleSystemChangeListener(this);
+ getSystemActivityNotificationsService()
+ .removeSystemActivityChangeListener(this);
+ }
+
+ /**
+ * Listens for activities and set corresponding statuses.
+ *
+ * @param event the NotificationActionTypeEvent, which is
+ */
+ public void activityChanged(SystemActivityEvent event)
+ {
+ switch(event.getEventID())
+ {
+ case SystemActivityEvent.EVENT_DISPLAY_SLEEP:
+ case SystemActivityEvent.EVENT_SCREEN_LOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_START:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE:
+ changeProtocolsToAway();
+ break;
+ case SystemActivityEvent.EVENT_DISPLAY_WAKE:
+ case SystemActivityEvent.EVENT_SCREEN_UNLOCKED:
+ case SystemActivityEvent.EVENT_SCREENSAVER_STOP:
+ case SystemActivityEvent.EVENT_SYSTEM_IDLE_END:
+ changeProtocolsToPreviousState();
+ break;
+ }
+ }
+
+ /**
+ * Change protocol to away saving status so it can be set again when
+ * out of idle state.
+ */
+ private void changeProtocolsToAway()
+ {
+ for (ProtocolProviderService protocolProviderService
+ : GeneralConfigPluginActivator.getProtocolProviders())
+ {
+ OperationSetPresence presence
+ = protocolProviderService
+ .getOperationSet(
+ OperationSetPresence.class);
+
+ PresenceStatus status = presence
+ .getPresenceStatus();
+
+ if (status.getStatus()
+ < PresenceStatus.AVAILABLE_THRESHOLD)
+ {
+ // already (manually) set to away or lower
+ continue;
+ }
+
+ lastStates.put(protocolProviderService, status);
+
+ PresenceStatus newStatus =
+ StatusUpdateThread.findAwayStatus(presence);
+
+ try
+ {
+ if (newStatus != null)
+ presence
+ .publishPresenceStatus(
+ newStatus,
+ newStatus.getStatusName());
+ } catch (IllegalArgumentException e)
+ {
+ } catch (IllegalStateException e)
+ {
+ } catch (OperationFailedException e)
+ {
+ }
+ }
+ }
+
+ /**
+ * Back to status which was already saved before going to idle.
+ */
+ private void changeProtocolsToPreviousState()
+ {
+ for (ProtocolProviderService protocolProviderService
+ : GeneralConfigPluginActivator.getProtocolProviders())
+ {
+ if (lastStates.get(protocolProviderService) != null)
+ {
+ PresenceStatus lastState
+ = lastStates.get(protocolProviderService);
+ OperationSetPresence presence
+ = protocolProviderService
+ .getOperationSet(
+ OperationSetPresence.class);
+ try
+ {
+ presence
+ .publishPresenceStatus(lastState, "");
+ } catch (IllegalArgumentException e)
+ {
+ } catch (IllegalStateException e)
+ {
+ } catch (OperationFailedException e)
+ {
+ }
+ lastStates.remove(protocolProviderService);
+ }
+ }
+ }
+
+ /**
+ * The SystemActivityNotifications Service.
+ * @return the SystemActivityNotifications Service.
+ */
+ private SystemActivityNotificationsService
+ getSystemActivityNotificationsService()
+ {
+ return ServiceUtils.getService(
+ GeneralConfigPluginActivator.bundleContext,
+ SystemActivityNotificationsService.class);
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java
index f34349ef7..5fe02e364 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/autoaway/StatusUpdateThread.java
@@ -140,7 +140,7 @@ public void stop()
* @param presence
* @return
*/
- private PresenceStatus findAwayStatus(OperationSetPresence presence)
+ static PresenceStatus findAwayStatus(OperationSetPresence presence)
{
Iterator statusSet = presence.getSupportedStatusSet();
PresenceStatus status = null;
@@ -166,7 +166,7 @@ private PresenceStatus findAwayStatus(OperationSetPresence presence)
return status;
}
- private int getTimer()
+ static int getTimer()
{
ConfigurationService configService
= GeneralConfigPluginActivator.getConfigurationService();
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf
index 9bbce55b3..592eb19e4 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/generalconfig/generalconfig.manifest.mf
@@ -15,6 +15,8 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.systray,
net.java.sip.communicator.util,
net.java.sip.communicator.util.swing,
+ net.java.sip.communicator.service.sysactivity,
+ net.java.sip.communicator.service.sysactivity.event,
com.sun.jna.win32,
com.sun.jna,
com.sun.jna.ptr,
diff --git a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java
index 8214baf5f..8b6ce0da0 100644
--- a/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java
+++ b/src/net/java/sip/communicator/plugin/reconnectplugin/ReconnectPluginActivator.java
@@ -118,7 +118,7 @@ public class ReconnectPluginActivator
/**
* The end of the interval for the initial reconnect.
*/
- private static final int RECONNECT_DELAY_MAX = 30; // sec
+ private static final int RECONNECT_DELAY_MAX = 15; // sec
/**
* Max value for growing the reconnect delay, all subsequent reconnects
diff --git a/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java b/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java
new file mode 100644
index 000000000..b2d848126
--- /dev/null
+++ b/src/net/java/sip/communicator/service/sysactivity/SystemActivityChangeListener.java
@@ -0,0 +1,31 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.sysactivity;
+
+import net.java.sip.communicator.service.sysactivity.event.*;
+
+import java.util.*;
+
+/**
+ * The SystemActivityChangeListener is notified any time an event
+ * in the operating system occurs.
+ *
+ * @author Damian Minkov
+ */
+public interface SystemActivityChangeListener
+ extends EventListener
+{
+ /**
+ * This method gets called when a notification action for a particular event
+ * type has been changed (for example the corresponding descriptor has
+ * changed).
+ *
+ * @param event the NotificationActionTypeEvent, which is
+ * dispatched when an action has been changed.
+ */
+ public void activityChanged(SystemActivityEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java b/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java
new file mode 100644
index 000000000..2faf4f4d5
--- /dev/null
+++ b/src/net/java/sip/communicator/service/sysactivity/SystemActivityNotificationsService.java
@@ -0,0 +1,58 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.sysactivity;
+
+/**
+ * Listens for some system specific events such as sleep, wake, network change,
+ * desktop activity, screensaver etc. and informs the registered listeners.
+ *
+ * @author Damian Minkov
+ */
+public interface SystemActivityNotificationsService
+{
+ /**
+ * Registers a listener that would be notified of changes that have occurred
+ * in the underlying system.
+ *
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addSystemActivityChangeListener(
+ SystemActivityChangeListener listener);
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications of changes that occur in the underlying system
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeSystemActivityChangeListener(
+ SystemActivityChangeListener listener);
+
+ /**
+ * Registers a listener that would be notified for idle of the system
+ * for idleTime.
+ *
+ * @param idleTime the time in milliseconds after which we will consider
+ * system to be idle. This doesn't count when system seems idle as
+ * monitor is off or screensaver is on, or desktop is locked.
+ * @param listener the listener that we'd like to register for changes in
+ * the underlying system.
+ */
+ public void addIdleSystemChangeListener(
+ long idleTime,
+ SystemActivityChangeListener listener);
+
+ /**
+ * Remove the specified listener so that it won't receive further
+ * notifications for idle system.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeIdleSystemChangeListener(
+ SystemActivityChangeListener listener);
+}
diff --git a/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
new file mode 100644
index 000000000..a06f60607
--- /dev/null
+++ b/src/net/java/sip/communicator/service/sysactivity/event/SystemActivityEvent.java
@@ -0,0 +1,106 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.sysactivity.event;
+
+import java.util.*;
+
+/**
+ * An event class representing system activity that has occurred.
+ * The event id indicates the exact reason for this event.
+ * @author Damian Minkov
+ */
+public class SystemActivityEvent
+ extends EventObject
+{
+ /**
+ * Notify that computers is going to sleep.
+ */
+ public static final int EVENT_SLEEP = 0;
+
+ /**
+ * Notify that computer is wakeing up after stand by.
+ */
+ public static final int EVENT_WAKE = 1;
+
+ /**
+ * Computer display has stand by.
+ */
+ public static final int EVENT_DISPLAY_SLEEP = 2;
+
+ /**
+ * Computer display wakes up after stand by.
+ */
+ public static final int EVENT_DISPLAY_WAKE = 3;
+
+ /**
+ * Screensaver has been started.
+ */
+ public static final int EVENT_SCREENSAVER_START = 4;
+
+ /**
+ * Screensaver will stop.
+ */
+ public static final int EVENT_SCREENSAVER_WILL_STOP = 5;
+
+ /**
+ * Screensaver has been stopped.
+ */
+ public static final int EVENT_SCREENSAVER_STOP = 6;
+
+ /**
+ * Screen has been locked.
+ */
+ public static final int EVENT_SCREEN_LOCKED = 7;
+
+ /**
+ * Screen has been unlocked.
+ */
+ public static final int EVENT_SCREEN_UNLOCKED = 8;
+
+ /**
+ * A change in network configuration has occurred.
+ */
+ public static final int EVENT_NETWORK_CHANGE = 9;
+
+ /**
+ * A system idle event has occurred.
+ */
+ public static final int EVENT_SYSTEM_IDLE = 10;
+
+ /**
+ * A system was in idle state and now exits.
+ */
+ public static final int EVENT_SYSTEM_IDLE_END = 11;
+
+ /**
+ * The type of the event.
+ */
+ private final int eventID;
+
+ /**
+ * Constructs a prototypical Event.
+ *
+ * @param source The object on which the Event initially occurred.
+ * @param eventID the type of the event.
+ * @throws IllegalArgumentException if source is null.
+ */
+ public SystemActivityEvent(Object source, int eventID)
+ {
+ super(source);
+
+ this.eventID = eventID;
+ }
+
+ /**
+ * Returns the type of the event.
+ * @return
+ */
+ public int getEventID()
+ {
+ return this.eventID;
+ }
+}