mirror of https://github.com/sipwise/jitsi.git
Introduces service for detecting system activity like network changes and detecting idle states. Produced events used for autoaway and reconnect plugin.
parent
6e080f08a2
commit
f9992f25f8
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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…
Reference in new issue