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