Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "nsNativeAppSupportBase.h" |
michael@0 | 7 | #include "nsCOMPtr.h" |
michael@0 | 8 | #include "nsXPCOM.h" |
michael@0 | 9 | #include "nsISupportsPrimitives.h" |
michael@0 | 10 | #include "nsIObserverService.h" |
michael@0 | 11 | #include "nsIAppStartup.h" |
michael@0 | 12 | #include "nsServiceManagerUtils.h" |
michael@0 | 13 | #include "prlink.h" |
michael@0 | 14 | #include "nsXREDirProvider.h" |
michael@0 | 15 | #include "nsReadableUtils.h" |
michael@0 | 16 | |
michael@0 | 17 | #include "nsIFile.h" |
michael@0 | 18 | #include "nsDirectoryServiceDefs.h" |
michael@0 | 19 | #include "nsICommandLineRunner.h" |
michael@0 | 20 | #include "nsIWindowMediator.h" |
michael@0 | 21 | #include "nsPIDOMWindow.h" |
michael@0 | 22 | #include "nsIDocShell.h" |
michael@0 | 23 | #include "nsIBaseWindow.h" |
michael@0 | 24 | #include "nsIWidget.h" |
michael@0 | 25 | #include "nsIWritablePropertyBag2.h" |
michael@0 | 26 | #include "nsIPrefService.h" |
michael@0 | 27 | #include "mozilla/Services.h" |
michael@0 | 28 | |
michael@0 | 29 | #include <stdlib.h> |
michael@0 | 30 | #include <glib.h> |
michael@0 | 31 | #include <glib-object.h> |
michael@0 | 32 | #include <gtk/gtk.h> |
michael@0 | 33 | |
michael@0 | 34 | #ifdef MOZ_X11 |
michael@0 | 35 | #include <gdk/gdkx.h> |
michael@0 | 36 | #include <X11/Xatom.h> |
michael@0 | 37 | #endif |
michael@0 | 38 | |
michael@0 | 39 | #ifdef MOZ_ENABLE_DBUS |
michael@0 | 40 | #include <dbus/dbus.h> |
michael@0 | 41 | #endif |
michael@0 | 42 | |
michael@0 | 43 | #define MIN_GTK_MAJOR_VERSION 2 |
michael@0 | 44 | #define MIN_GTK_MINOR_VERSION 10 |
michael@0 | 45 | #define UNSUPPORTED_GTK_MSG "We're sorry, this application requires a version of the GTK+ library that is not installed on your computer.\n\n\ |
michael@0 | 46 | You have GTK+ %d.%d.\nThis application requires GTK+ %d.%d or newer.\n\n\ |
michael@0 | 47 | Please upgrade your GTK+ library if you wish to use this application." |
michael@0 | 48 | |
michael@0 | 49 | typedef struct _GnomeProgram GnomeProgram; |
michael@0 | 50 | typedef struct _GnomeModuleInfo GnomeModuleInfo; |
michael@0 | 51 | typedef struct _GnomeClient GnomeClient; |
michael@0 | 52 | |
michael@0 | 53 | typedef enum { |
michael@0 | 54 | GNOME_SAVE_GLOBAL, |
michael@0 | 55 | GNOME_SAVE_LOCAL, |
michael@0 | 56 | GNOME_SAVE_BOTH |
michael@0 | 57 | } GnomeSaveStyle; |
michael@0 | 58 | |
michael@0 | 59 | typedef enum { |
michael@0 | 60 | GNOME_INTERACT_NONE, |
michael@0 | 61 | GNOME_INTERACT_ERRORS, |
michael@0 | 62 | GNOME_INTERACT_ANY |
michael@0 | 63 | } GnomeInteractStyle; |
michael@0 | 64 | |
michael@0 | 65 | typedef enum { |
michael@0 | 66 | GNOME_DIALOG_ERROR, |
michael@0 | 67 | GNOME_DIALOG_NORMAL |
michael@0 | 68 | } GnomeDialogType; |
michael@0 | 69 | |
michael@0 | 70 | typedef GnomeProgram * (*_gnome_program_init_fn)(const char *, const char *, |
michael@0 | 71 | const GnomeModuleInfo *, int, |
michael@0 | 72 | char **, const char *, ...); |
michael@0 | 73 | typedef GnomeProgram * (*_gnome_program_get_fn)(void); |
michael@0 | 74 | typedef const GnomeModuleInfo * (*_libgnomeui_module_info_get_fn)(); |
michael@0 | 75 | typedef GnomeClient * (*_gnome_master_client_fn)(void); |
michael@0 | 76 | typedef void (*_gnome_client_set_restart_command_fn)(GnomeClient*, gint, gchar*[]); |
michael@0 | 77 | |
michael@0 | 78 | static _gnome_client_set_restart_command_fn gnome_client_set_restart_command; |
michael@0 | 79 | |
michael@0 | 80 | gboolean save_yourself_cb(GnomeClient *client, gint phase, |
michael@0 | 81 | GnomeSaveStyle style, gboolean shutdown, |
michael@0 | 82 | GnomeInteractStyle interact, gboolean fast, |
michael@0 | 83 | gpointer user_data) |
michael@0 | 84 | { |
michael@0 | 85 | nsCOMPtr<nsIObserverService> obsServ = |
michael@0 | 86 | mozilla::services::GetObserverService(); |
michael@0 | 87 | |
michael@0 | 88 | nsCOMPtr<nsISupportsPRBool> didSaveSession = |
michael@0 | 89 | do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); |
michael@0 | 90 | |
michael@0 | 91 | if (!obsServ || !didSaveSession) |
michael@0 | 92 | return TRUE; // OOM |
michael@0 | 93 | |
michael@0 | 94 | // Notify observers to save the session state |
michael@0 | 95 | didSaveSession->SetData(false); |
michael@0 | 96 | obsServ->NotifyObservers(didSaveSession, "session-save", nullptr); |
michael@0 | 97 | |
michael@0 | 98 | bool status; |
michael@0 | 99 | didSaveSession->GetData(&status); |
michael@0 | 100 | |
michael@0 | 101 | // If there was no session saved and the save_yourself request is |
michael@0 | 102 | // caused by upcoming shutdown we like to prepare for it |
michael@0 | 103 | if (!status && shutdown) { |
michael@0 | 104 | nsCOMPtr<nsISupportsPRBool> cancelQuit = |
michael@0 | 105 | do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID); |
michael@0 | 106 | |
michael@0 | 107 | cancelQuit->SetData(false); |
michael@0 | 108 | obsServ->NotifyObservers(cancelQuit, "quit-application-requested", nullptr); |
michael@0 | 109 | |
michael@0 | 110 | bool abortQuit; |
michael@0 | 111 | cancelQuit->GetData(&abortQuit); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | return TRUE; |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | void die_cb(GnomeClient *client, gpointer user_data) |
michael@0 | 118 | { |
michael@0 | 119 | nsCOMPtr<nsIAppStartup> appService = |
michael@0 | 120 | do_GetService("@mozilla.org/toolkit/app-startup;1"); |
michael@0 | 121 | |
michael@0 | 122 | if (appService) |
michael@0 | 123 | appService->Quit(nsIAppStartup::eForceQuit); |
michael@0 | 124 | } |
michael@0 | 125 | |
michael@0 | 126 | class nsNativeAppSupportUnix : public nsNativeAppSupportBase |
michael@0 | 127 | { |
michael@0 | 128 | public: |
michael@0 | 129 | NS_IMETHOD Start(bool* aRetVal); |
michael@0 | 130 | NS_IMETHOD Stop(bool *aResult); |
michael@0 | 131 | NS_IMETHOD Enable(); |
michael@0 | 132 | |
michael@0 | 133 | private: |
michael@0 | 134 | }; |
michael@0 | 135 | |
michael@0 | 136 | NS_IMETHODIMP |
michael@0 | 137 | nsNativeAppSupportUnix::Start(bool *aRetVal) |
michael@0 | 138 | { |
michael@0 | 139 | NS_ASSERTION(gAppData, "gAppData must not be null."); |
michael@0 | 140 | |
michael@0 | 141 | // The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService, |
michael@0 | 142 | // from diffrent threads. This could lead to race conditions if the dbus is not |
michael@0 | 143 | // initialized before making any other library calls. |
michael@0 | 144 | #ifdef MOZ_ENABLE_DBUS |
michael@0 | 145 | dbus_threads_init_default(); |
michael@0 | 146 | #endif |
michael@0 | 147 | |
michael@0 | 148 | #if (MOZ_WIDGET_GTK == 2) |
michael@0 | 149 | if (gtk_major_version < MIN_GTK_MAJOR_VERSION || |
michael@0 | 150 | (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) { |
michael@0 | 151 | GtkWidget* versionErrDialog = gtk_message_dialog_new(nullptr, |
michael@0 | 152 | GtkDialogFlags(GTK_DIALOG_MODAL | |
michael@0 | 153 | GTK_DIALOG_DESTROY_WITH_PARENT), |
michael@0 | 154 | GTK_MESSAGE_ERROR, |
michael@0 | 155 | GTK_BUTTONS_OK, |
michael@0 | 156 | UNSUPPORTED_GTK_MSG, |
michael@0 | 157 | gtk_major_version, |
michael@0 | 158 | gtk_minor_version, |
michael@0 | 159 | MIN_GTK_MAJOR_VERSION, |
michael@0 | 160 | MIN_GTK_MINOR_VERSION); |
michael@0 | 161 | gtk_dialog_run(GTK_DIALOG(versionErrDialog)); |
michael@0 | 162 | gtk_widget_destroy(versionErrDialog); |
michael@0 | 163 | exit(0); |
michael@0 | 164 | } |
michael@0 | 165 | #endif |
michael@0 | 166 | |
michael@0 | 167 | *aRetVal = true; |
michael@0 | 168 | |
michael@0 | 169 | #if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2) |
michael@0 | 170 | |
michael@0 | 171 | PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0"); |
michael@0 | 172 | if (!gnomeuiLib) |
michael@0 | 173 | return NS_OK; |
michael@0 | 174 | |
michael@0 | 175 | PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0"); |
michael@0 | 176 | if (!gnomeLib) { |
michael@0 | 177 | PR_UnloadLibrary(gnomeuiLib); |
michael@0 | 178 | return NS_OK; |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | _gnome_program_init_fn gnome_program_init = |
michael@0 | 182 | (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init"); |
michael@0 | 183 | _gnome_program_get_fn gnome_program_get = |
michael@0 | 184 | (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get"); |
michael@0 | 185 | _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get"); |
michael@0 | 186 | if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) { |
michael@0 | 187 | PR_UnloadLibrary(gnomeuiLib); |
michael@0 | 188 | PR_UnloadLibrary(gnomeLib); |
michael@0 | 189 | return NS_OK; |
michael@0 | 190 | } |
michael@0 | 191 | |
michael@0 | 192 | #endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */ |
michael@0 | 193 | |
michael@0 | 194 | #ifdef ACCESSIBILITY |
michael@0 | 195 | // We will load gail, atk-bridge by ourself later |
michael@0 | 196 | // We can't run atk-bridge init here, because gail get the control |
michael@0 | 197 | // Set GNOME_ACCESSIBILITY to 0 can avoid this |
michael@0 | 198 | static const char *accEnv = "GNOME_ACCESSIBILITY"; |
michael@0 | 199 | const char *accOldValue = getenv(accEnv); |
michael@0 | 200 | setenv(accEnv, "0", 1); |
michael@0 | 201 | #endif |
michael@0 | 202 | |
michael@0 | 203 | #if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2) |
michael@0 | 204 | if (!gnome_program_get()) { |
michael@0 | 205 | gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), |
michael@0 | 206 | gArgc, gArgv, nullptr); |
michael@0 | 207 | } |
michael@0 | 208 | #endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */ |
michael@0 | 209 | |
michael@0 | 210 | #ifdef ACCESSIBILITY |
michael@0 | 211 | if (accOldValue) { |
michael@0 | 212 | setenv(accEnv, accOldValue, 1); |
michael@0 | 213 | } else { |
michael@0 | 214 | unsetenv(accEnv); |
michael@0 | 215 | } |
michael@0 | 216 | #endif |
michael@0 | 217 | |
michael@0 | 218 | // Careful! These libraries cannot be unloaded after this point because |
michael@0 | 219 | // gnome_program_init causes atexit handlers to be registered. Strange |
michael@0 | 220 | // crashes will occur if these libraries are unloaded. |
michael@0 | 221 | |
michael@0 | 222 | // TODO GTK3 - see Bug 694570 - Stop using libgnome and libgnomeui on Linux |
michael@0 | 223 | #if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2) |
michael@0 | 224 | gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn) |
michael@0 | 225 | PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command"); |
michael@0 | 226 | |
michael@0 | 227 | _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn) |
michael@0 | 228 | PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client"); |
michael@0 | 229 | |
michael@0 | 230 | GnomeClient *client = gnome_master_client(); |
michael@0 | 231 | g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), nullptr); |
michael@0 | 232 | g_signal_connect(client, "die", G_CALLBACK(die_cb), nullptr); |
michael@0 | 233 | |
michael@0 | 234 | // Set the correct/requested restart command in any case. |
michael@0 | 235 | |
michael@0 | 236 | // Is there a request to suppress default binary launcher? |
michael@0 | 237 | nsAutoCString path; |
michael@0 | 238 | char* argv1 = getenv("MOZ_APP_LAUNCHER"); |
michael@0 | 239 | |
michael@0 | 240 | if(!argv1) { |
michael@0 | 241 | // Tell the desktop the command for restarting us so that we can be part of XSMP session restore |
michael@0 | 242 | NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!"); |
michael@0 | 243 | nsCOMPtr<nsIFile> executablePath; |
michael@0 | 244 | nsresult rv; |
michael@0 | 245 | |
michael@0 | 246 | bool dummy; |
michael@0 | 247 | rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath)); |
michael@0 | 248 | |
michael@0 | 249 | if (NS_SUCCEEDED(rv)) { |
michael@0 | 250 | // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does |
michael@0 | 251 | nsAutoCString leafName; |
michael@0 | 252 | rv = executablePath->GetNativeLeafName(leafName); |
michael@0 | 253 | if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) { |
michael@0 | 254 | leafName.SetLength(leafName.Length() - strlen("-bin")); |
michael@0 | 255 | executablePath->SetNativeLeafName(leafName); |
michael@0 | 256 | } |
michael@0 | 257 | |
michael@0 | 258 | executablePath->GetNativePath(path); |
michael@0 | 259 | argv1 = (char*)(path.get()); |
michael@0 | 260 | } |
michael@0 | 261 | } |
michael@0 | 262 | |
michael@0 | 263 | if (argv1) { |
michael@0 | 264 | gnome_client_set_restart_command(client, 1, &argv1); |
michael@0 | 265 | } |
michael@0 | 266 | #endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */ |
michael@0 | 267 | |
michael@0 | 268 | return NS_OK; |
michael@0 | 269 | } |
michael@0 | 270 | |
michael@0 | 271 | NS_IMETHODIMP |
michael@0 | 272 | nsNativeAppSupportUnix::Stop(bool *aResult) |
michael@0 | 273 | { |
michael@0 | 274 | NS_ENSURE_ARG(aResult); |
michael@0 | 275 | *aResult = true; |
michael@0 | 276 | return NS_OK; |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | NS_IMETHODIMP |
michael@0 | 280 | nsNativeAppSupportUnix::Enable() |
michael@0 | 281 | { |
michael@0 | 282 | return NS_OK; |
michael@0 | 283 | } |
michael@0 | 284 | |
michael@0 | 285 | nsresult |
michael@0 | 286 | NS_CreateNativeAppSupport(nsINativeAppSupport **aResult) |
michael@0 | 287 | { |
michael@0 | 288 | nsNativeAppSupportBase* native = new nsNativeAppSupportUnix(); |
michael@0 | 289 | if (!native) |
michael@0 | 290 | return NS_ERROR_OUT_OF_MEMORY; |
michael@0 | 291 | |
michael@0 | 292 | *aResult = native; |
michael@0 | 293 | NS_ADDREF(*aResult); |
michael@0 | 294 | |
michael@0 | 295 | return NS_OK; |
michael@0 | 296 | } |