Introduces service for detecting system activity like network changes and detecting idle states. Produced events used for autoaway and reconnect plugin.

cusax-fix
Damian Minkov 14 years ago
parent 6e080f08a2
commit f9992f25f8

@ -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" />
</jar>
</target>
<target name="bundle-systemactivitynotifications">
<jar compress="false" destfile="${bundles.dest}/sysactivitynotifications.jar"
manifest="${src}/net/java/sip/communicator/impl/sysactivity/sysactivity.impl.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/impl/sysactivity"
prefix="net/java/sip/communicator/impl/sysactivity" />
<zipfileset dir="${dest}/net/java/sip/communicator/service/sysactivity"
prefix="net/java/sip/communicator/service/sysactivity"/>
<zipfileset src="${lib.noinst}/libdbus-java-2.7.jar" prefix=""/>
<zipfileset src="${lib.noinst}/unix-0.5.jar" prefix=""/>
<zipfileset src="${lib.noinst}/hexdump-0.2.jar" prefix=""/>
</jar>
</target>
</project>

@ -75,5 +75,8 @@
<classpathentry kind="lib" path="lib/installer-exclude/gdata-contacts-3.0.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/gdata-contacts-meta-3.0.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/gdata-core-1.0.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/libdbus-java-2.7.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/hexdump-0.2.jar"/>
<classpathentry kind="lib" path="lib/installer-exclude/unix-0.5.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -122,7 +122,7 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/2">
<compilation-unit>
<package-root>src</package-root>
<classpath mode="compile">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</classpath>
<classpath mode="compile">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</classpath>
<built-to>classes</built-to>
<source-level>1.5</source-level>
</compilation-unit>

@ -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

Binary file not shown.

@ -801,6 +801,100 @@
<delete file="${native_install_dir}/history.xml" failonerror="false" />
</target>
<target name="sysactivity" description="Build sysactivity"
depends="init-native">
<cc outtype="shared" name="gcc" outfile="${native_install_dir}/sysactivitynotifications"
objdir="${obj}">
<!-- common compiler flags -->
<compilerarg value="-Wall" />
<compilerarg value="-Wextra" />
<compilerarg value="-m32" if="cross_32" unless="is.running.macos" />
<compilerarg value="-m64" if="cross_64" unless="is.running.macos" />
<linkerarg value="-m32" if="cross_32" unless="is.running.macos" />
<linkerarg value="-m64" if="cross_64" unless="is.running.macos" />
<!-- Mac OS X specific flags -->
<compilerarg value="-mmacosx-version-min=10.5" if="is.running.macos"/>
<compilerarg value="-O2" if="is.running.macos"/>
<compilerarg value="-arch" if="is.running.macos"/>
<compilerarg value="x86_64" if="is.running.macos"/>
<compilerarg value="-arch" if="is.running.macos"/>
<compilerarg value="i386" if="is.running.macos"/>
<compilerarg value="-arch" if="is.running.macos"/>
<compilerarg value="ppc" if="is.running.macos"/>
<compilerarg value="-I/System/Library/Frameworks/JavaVM.framework/Headers"
if="is.running.macos"/>
<linkerarg value="-o" location="end" if="is.running.macos"/>
<linkerarg value="libsysactivitynotifications.jnilib" location="end"
if="is.running.macos"/>
<linkerarg value="-arch" if="is.running.macos"/>
<linkerarg value="x86_64" if="is.running.macos"/>
<linkerarg value="-arch" if="is.running.macos"/>
<linkerarg value="i386" if="is.running.macos"/>
<linkerarg value="-arch" if="is.running.macos"/>
<linkerarg value="ppc" if="is.running.macos"/>
<linkerarg value="-framework" if="is.running.macos"/>
<linkerarg value="AppKit" if="is.running.macos"/>
<linkerarg value="-framework" if="is.running.macos"/>
<linkerarg value="Carbon" if="is.running.macos"/>
<linkerarg value="-framework" if="is.running.macos"/>
<linkerarg value="SystemConfiguration" if="is.running.macos"/>
<linkerarg value="-framework" if="is.running.macos" />
<linkerarg value="IOKit" if="is.running.macos" />
<fileset dir="${src}/native/sysactivity"
includes="*.m" if="is.running.macos"/>
<!-- Linux specific flags -->
<fileset dir="${src}/native/sysactivity" includes="*.c" if="is.running.linux" />
<compilerarg value="-I/usr/include/gtk-2.0" if="is.running.linux" />
<compilerarg value="-I/usr/include/glib-2.0/" if="is.running.linux" />
<compilerarg value="-I/usr/include/cairo/" if="is.running.linux" />
<compilerarg value="-I/usr/include/pango-1.0/" if="is.running.linux" />
<compilerarg value="-I/usr/include/gdk-pixbuf-2.0/" if="is.running.linux" />
<compilerarg value="-I/usr/lib/glib-2.0/include/" if="is.running.linux" />
<compilerarg value="-I/usr/lib/gtk-2.0/include/" if="is.running.linux" />
<compilerarg value="-m32" if="cross_32" unless="is.running.macos" />
<compilerarg value="-m64" if="cross_64" unless="is.running.macos" />
<compilerarg value="-I${system.JAVA_HOME}/include" if="is.running.linux" />
<compilerarg value="-I${system.JAVA_HOME}/include/linux" if="is.running.linux" />
<linkerarg value="-m32" if="cross_32" unless="is.running.macos" />
<linkerarg value="-m64" if="cross_64" unless="is.running.macos" />
<linkerarg value="-lgdk-x11-2.0" if="is.running.linux" />
<linkerarg value="-lXss" if="is.running.linux" />
</cc>
</target>
<!-- compile sysactivity library for Windows
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.Cmd" /x86 /xp /Release
-->
<target name="sysactivity-windows"
description="Build sysactivity shared library for Windows"
if="is.running.windows"
depends="init-native">
<cc outtype="shared" name="msvc"
outfile="${native_install_dir}/sysactivitynotifications"
objdir="${obj}">
<compilerarg value="/O2" />
<compilerarg value="/GS" if="cross_64" />
<compilerarg value="/MT" location="end" />
<compilerarg value="-I${system.JAVA_HOME}/include" />
<compilerarg value="-I${system.JAVA_HOME}/include/win32" />
<linkerarg value="/LIBPATH:${system.JAVA_HOME}\\lib" />
<linkerarg value="iphlpapi.lib" location="end" />
<linkerarg value="user32.lib" location="end" />
<linkerarg value="jawt.lib" location="end" />
<fileset dir="${src}/native/sysactivity" includes="*.cpp" />
</cc>
</target>
<!-- Cleanup object file and shared libraries -->
<target name="clean-native" description="Clean all object file and libraries.">
<delete failonerror="false" includeemptydirs="true">

@ -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 <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>
#include <gdk/gdkx.h>
/*
* 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)
{
}

@ -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 <winsock2.h>
#include <ws2def.h>
#include <ws2ipdef.h>
#include <windows.h>
#include <iphlpapi.h>
#include <process.h>
#include <tchar.h>
// 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();
}

@ -0,0 +1,83 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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

@ -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 <AppKit/NSWorkspace.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import <Carbon/Carbon.h>
#import <SystemConfiguration/SystemConfiguration.h>
@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;
}

@ -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;
}
}

@ -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<NetworkConfigurationChangeListener>();
/**
* Whether current thread is running.
* The current active interfaces.
*/
private List<NetworkInterface> activeInterfaces
= new ArrayList<NetworkInterface>();
/**
* Service we use to listen for network changes.
*/
private boolean isRunning = false;
private SystemActivityNotificationsService
systemActivityNotificationsService = null;
/**
* Inits configuration watcher.
*/
NetworkConfigurationWatcher()
{
checkNetworkInterfaces(false);
}
/**
* Adds new <tt>NetworkConfigurationChangeListener</tt> 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<NetworkInterface> activeInterfaces =
new ArrayList<NetworkInterface>();
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<NetworkInterface> 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<NetworkInterface> e =
NetworkInterface.getNetworkInterfaces();
boolean networkIsUP = activeInterfaces.size() > 0;
List<NetworkInterface> currentActiveInterfaces =
new ArrayList<NetworkInterface>();
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<NetworkInterface> inactiveActiveInterfaces =
new ArrayList<NetworkInterface>(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<NetworkInterface> 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<NetworkInterface> e =
NetworkInterface.getNetworkInterfaces();
List<NetworkInterface> currentActiveInterfaces =
new ArrayList<NetworkInterface>();
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<NetworkInterface> inactiveActiveInterfaces =
new ArrayList<NetworkInterface>(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);
}
}
}

@ -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,

@ -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 <tt>NetworkManagerListenerImpl</tt>.
* @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);
}
}
}

@ -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 <tt>BundleContext</tt>.
*/
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();
}
}

@ -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);
}
}

@ -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<SystemActivityChangeListener> activityChangeListeners =
new LinkedList<SystemActivityChangeListener>();
/**
* A list of listeners registered for idle events.
*/
private final Map<SystemActivityChangeListener,Long> idleChangeListeners =
new HashMap<SystemActivityChangeListener, Long>();
/**
* Listeners which are fired for idle state and which will be fired
* with idle end when needed.
*/
private final List<SystemActivityChangeListener> listenersInIdleState
= new ArrayList<SystemActivityChangeListener>();
/**
* 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 <tt>idleTime</tt>.
*
* @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<SystemActivityChangeListener, Long> 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 <tt>SystemActivityEvent</tt> that we'd like delivered to
* all registered message listeners.
*/
protected void fireSystemActivityEvent(SystemActivityEvent evt)
{
Collection<SystemActivityChangeListener> listeners = null;
synchronized (this.activityChangeListeners)
{
listeners = new ArrayList<SystemActivityChangeListener>(
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 <tt>SystemActivityEvent</tt> that we'd like delivered to
* all registered message listeners.
*/
protected void fireSystemIdleEvent(SystemActivityEvent evt)
{
Collection<SystemActivityChangeListener> listeners = null;
synchronized (this.idleChangeListeners)
{
listeners = new ArrayList<SystemActivityChangeListener>(
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);
}
}
}

@ -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

@ -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;
}
}
/**

@ -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<ProtocolProviderService, PresenceStatus> lastStates
= new HashMap<ProtocolProviderService, PresenceStatus>();
/**
* 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 <tt>NotificationActionTypeEvent</tt>, 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);
}
}

@ -140,7 +140,7 @@ public void stop()
* @param presence
* @return
*/
private PresenceStatus findAwayStatus(OperationSetPresence presence)
static PresenceStatus findAwayStatus(OperationSetPresence presence)
{
Iterator<PresenceStatus> 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();

@ -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,

@ -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

@ -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 <tt>SystemActivityChangeListener</tt> 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 <tt>NotificationActionTypeEvent</tt>, which is
* dispatched when an action has been changed.
*/
public void activityChanged(SystemActivityEvent event);
}

@ -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 <tt>idleTime</tt>.
*
* @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);
}

@ -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;
}
}
Loading…
Cancel
Save