Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include <gtk/gtk.h>
10 #include "nsIdleServiceGTK.h"
11 #include "nsIServiceManager.h"
12 #include "nsDebug.h"
13 #include "prlink.h"
14 #include "prlog.h"
16 #ifdef PR_LOGGING
17 static PRLogModuleInfo* sIdleLog = nullptr;
18 #endif
20 typedef bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
21 int* error_base);
23 typedef XScreenSaverInfo* (*_XScreenSaverAllocInfo_fn)(void);
25 typedef void (*_XScreenSaverQueryInfo_fn)(Display* dpy, Drawable drw,
26 XScreenSaverInfo *info);
28 static bool sInitialized = false;
29 static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nullptr;
30 static _XScreenSaverAllocInfo_fn _XSSAllocInfo = nullptr;
31 static _XScreenSaverQueryInfo_fn _XSSQueryInfo = nullptr;
33 NS_IMPL_ISUPPORTS_INHERITED0(nsIdleServiceGTK, nsIdleService)
35 static void Initialize()
36 {
37 // This will leak - See comments in ~nsIdleServiceGTK().
38 PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
39 if (!xsslib) // ouch.
40 {
41 #ifdef PR_LOGGING
42 PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to find libXss.so!\n"));
43 #endif
44 return;
45 }
47 _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
48 PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension");
49 _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)
50 PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo");
51 _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)
52 PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo");
53 #ifdef PR_LOGGING
54 if (!_XSSQueryExtension)
55 PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryExtension!\n"));
56 if (!_XSSAllocInfo)
57 PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSAllocInfo!\n"));
58 if (!_XSSQueryInfo)
59 PR_LOG(sIdleLog, PR_LOG_WARNING, ("Failed to get XSSQueryInfo!\n"));
60 #endif
62 sInitialized = true;
63 }
65 nsIdleServiceGTK::nsIdleServiceGTK()
66 : mXssInfo(nullptr)
67 {
68 #ifdef PR_LOGGING
69 if (!sIdleLog)
70 sIdleLog = PR_NewLogModule("nsIIdleService");
71 #endif
73 Initialize();
74 }
76 nsIdleServiceGTK::~nsIdleServiceGTK()
77 {
78 if (mXssInfo)
79 XFree(mXssInfo);
81 // It is not safe to unload libXScrnSaver until each display is closed because
82 // the library registers callbacks through XESetCloseDisplay (Bug 397607).
83 // (Also the library and its functions are scoped for the file not the object.)
84 #if 0
85 if (xsslib) {
86 PR_UnloadLibrary(xsslib);
87 xsslib = nullptr;
88 }
89 #endif
90 }
92 bool
93 nsIdleServiceGTK::PollIdleTime(uint32_t *aIdleTime)
94 {
95 if (!sInitialized) {
96 // For some reason, we could not find xscreensaver.
97 return false;
98 }
100 // Ask xscreensaver about idle time:
101 *aIdleTime = 0;
103 // We might not have a display (cf. in xpcshell)
104 Display *dplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
105 if (!dplay) {
106 #ifdef PR_LOGGING
107 PR_LOG(sIdleLog, PR_LOG_WARNING, ("No display found!\n"));
108 #endif
109 return false;
110 }
112 if (!_XSSQueryExtension || !_XSSAllocInfo || !_XSSQueryInfo) {
113 return false;
114 }
116 int event_base, error_base;
117 if (_XSSQueryExtension(dplay, &event_base, &error_base))
118 {
119 if (!mXssInfo)
120 mXssInfo = _XSSAllocInfo();
121 if (!mXssInfo)
122 return false;
123 _XSSQueryInfo(dplay, GDK_ROOT_WINDOW(), mXssInfo);
124 *aIdleTime = mXssInfo->idle;
125 return true;
126 }
127 // If we get here, we couldn't get to XScreenSaver:
128 #ifdef PR_LOGGING
129 PR_LOG(sIdleLog, PR_LOG_WARNING, ("XSSQueryExtension returned false!\n"));
130 #endif
131 return false;
132 }
134 bool
135 nsIdleServiceGTK::UsePollMode()
136 {
137 return sInitialized;
138 }