Bug 1343826 - Return updated timezone on system timezone change. r=smaug,mstange,stransky,handyman

Differential Revision: https://phabricator.services.mozilla.com/D146725
This commit is contained in:
Sean Burke 2022-06-14 19:41:30 +00:00
Родитель d3851fd23d
Коммит ad375a2527
16 изменённых файлов: 166 добавлений и 14 удалений

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -189,6 +189,7 @@
#include "nsIScriptError.h"
#include "nsIScriptSecurityManager.h"
#include "nsJSEnvironment.h"
#include "nsJSUtils.h"
#include "nsMemoryInfoDumper.h"
#include "nsPluginHost.h"
#include "nsServiceManagerUtils.h"
@ -2470,6 +2471,11 @@ mozilla::ipc::IPCResult ContentChild::RecvUpdateRequestedLocales(
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvSystemTimezoneChanged() {
nsJSUtils::ResetTimeZone();
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvAddPermission(
const IPC::Permission& permission) {
nsCOMPtr<nsIPermissionManager> permissionManagerIface =

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -334,6 +334,8 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvUpdateRequestedLocales(
nsTArray<nsCString>&& aRequestedLocales);
mozilla::ipc::IPCResult RecvSystemTimezoneChanged();
mozilla::ipc::IPCResult RecvAddPermission(const IPC::Permission& permission);
mozilla::ipc::IPCResult RecvRemoveAllPermissions();

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -187,6 +187,7 @@
#include "nsHashPropertyBag.h"
#include "nsHyphenationManager.h"
#include "nsIAlertsService.h"
#include "nsIAppShell.h"
#include "nsIAppStartup.h"
#include "nsIAppWindow.h"
#include "nsIAsyncInputStream.h"
@ -641,6 +642,7 @@ static const char* sObserverTopics[] = {
"private-cookie-changed",
NS_NETWORK_LINK_TYPE_TOPIC,
"network:socket-process-crashed",
DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC,
};
static const char kFissionEnforceBlockList[] =
@ -3860,6 +3862,8 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
UpdateNetworkLinkType();
} else if (!strcmp(aTopic, "network:socket-process-crashed")) {
Unused << SendSocketProcessCrashed();
} else if (!strcmp(aTopic, DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC)) {
Unused << SendSystemTimezoneChanged();
}
return NS_OK;

Просмотреть файл

@ -1,5 +1,5 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 ft=cpp : */
/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -702,6 +702,12 @@ child:
async UpdateAppLocales(nsCString[] appLocales);
async UpdateRequestedLocales(nsCString[] requestedLocales);
/**
* The system timezone has changed; the child process should ensure that
* calls to get the default timezone return the new value.
*/
async SystemTimezoneChanged();
async UpdateL10nFileSources(L10nFileSourceDescriptor[] sources);
async RegisterStringBundles(StringBundleDescriptor[] stringBundles);

Просмотреть файл

@ -456,6 +456,21 @@ var AppConstants = Object.freeze({
false,
#endif
MOZ_CAN_FOLLOW_SYSTEM_TIME:
#ifdef XP_WIN
true,
#elif XP_MACOSX
true,
#elif MOZ_WIDGET_GTK
#ifdef MOZ_ENABLE_DBUS
true,
#else
false,
#endif
#else
false,
#endif
// Returns true for CN region build when distibution id set as 'MozillaOnline'
isChinaRepack() {
return (

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
/* -*- tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -980,6 +981,10 @@ void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(timezoneChanged:)
name:NSSystemTimeZoneDidChangeNotification
object:nil];
}
return self;
@ -1032,6 +1037,14 @@ void nsAppShell::OnMemoryPressureChanged(dispatch_source_memorypressure_flags_t
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
- (void)timezoneChanged:(NSNotification*)aNotification {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
nsBaseAppShell::OnSystemTimezoneChange();
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
@end
// We hook terminate: in order to make OS-initiated termination work nicely

Просмотреть файл

@ -1,6 +1,5 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=4:tabstop=4:
*/
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -11,6 +10,7 @@
#include <errno.h>
#include <gdk/gdk.h>
#include "nsAppShell.h"
#include "nsBaseAppShell.h"
#include "nsWindow.h"
#include "mozilla/Logging.h"
#include "prenv.h"
@ -178,6 +178,19 @@ static void SessionSleepCallback(DBusGProxy* aProxy, gboolean aSuspend,
}
}
static void TimedatePropertiesChangedCallback(DBusGProxy* aProxy,
char* interface,
GHashTable* aChanged,
char** aInvalidated,
gpointer aData) {
// dbus signals are not fine-grained enough for us to only react to timezone
// changes, so we need to ensure that timezone is one of the properties
// changed.
if (g_hash_table_contains(aChanged, "Timezone")) {
nsBaseAppShell::OnSystemTimezoneChange();
}
}
static DBusHandlerResult ConnectionSignalFilter(DBusConnection* aConnection,
DBusMessage* aMessage,
void* aData) {
@ -221,7 +234,7 @@ void nsAppShell::StartDBusListening() {
"org.freedesktop.login1.Manager");
if (!mLogin1Proxy) {
NS_WARNING("gds: error-no dbus proxy\n");
NS_WARNING("gds: error creating login dbus proxy\n");
return;
}
@ -229,6 +242,23 @@ void nsAppShell::StartDBusListening() {
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(mLogin1Proxy, "PrepareForSleep",
G_CALLBACK(SessionSleepCallback), this, nullptr);
mTimedate1Proxy = dbus_g_proxy_new_for_name(
mDBusConnection, "org.freedesktop.timedate1",
"/org/freedesktop/timedate1", "org.freedesktop.DBus.Properties");
if (!mTimedate1Proxy) {
NS_WARNING("gds: error creating timedate dbus proxy\n");
return;
}
dbus_g_proxy_add_signal(
mTimedate1Proxy, "PropertiesChanged", G_TYPE_STRING,
dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
G_TYPE_STRV, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(mTimedate1Proxy, "PropertiesChanged",
G_CALLBACK(TimedatePropertiesChangedCallback),
this, nullptr);
}
void nsAppShell::StopDBusListening() {
@ -247,6 +277,15 @@ void nsAppShell::StopDBusListening() {
g_object_unref(mLogin1Proxy);
mLogin1Proxy = nullptr;
}
if (mTimedate1Proxy) {
dbus_g_proxy_disconnect_signal(
mTimedate1Proxy, "PropertiesChanged",
G_CALLBACK(TimedatePropertiesChangedCallback), this);
g_object_unref(mTimedate1Proxy);
mTimedate1Proxy = nullptr;
}
dbus_g_connection_unref(mDBusConnection);
mDBusConnection = nullptr;
}

Просмотреть файл

@ -39,6 +39,7 @@ class nsAppShell : public nsBaseAppShell {
#ifdef MOZ_ENABLE_DBUS
DBusGConnection* mDBusConnection = nullptr;
DBusGProxy* mLogin1Proxy = nullptr;
DBusGProxy* mTimedate1Proxy = nullptr;
#endif
};

Просмотреть файл

@ -7,7 +7,9 @@
#include "nsBaseAppShell.h"
#include "nsExceptionHandler.h"
#include "nsJSUtils.h"
#include "nsThreadUtils.h"
#include "nsIAppShell.h"
#include "nsIObserverService.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/Services.h"
@ -96,6 +98,17 @@ void nsBaseAppShell::NativeEventCallback() {
DecrementEventloopNestingLevel();
}
void nsBaseAppShell::OnSystemTimezoneChange() {
nsJSUtils::ResetTimeZone();
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
if (obsSvc) {
// Timezone changed notification
obsSvc->NotifyObservers(nullptr, DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC,
nullptr);
}
}
// Note, this is currently overidden on windows, see comments in nsAppShell for
// details.
void nsBaseAppShell::DoProcessMoreGeckoEvents() { OnDispatchedEvent(); }

Просмотреть файл

@ -31,6 +31,12 @@ class nsBaseAppShell : public nsIAppShell,
nsBaseAppShell();
/**
* Called by subclasses. Reset the internal timezone when the user's system
* timezone changes.
*/
static void OnSystemTimezoneChange();
protected:
virtual ~nsBaseAppShell();

Просмотреть файл

@ -9,6 +9,12 @@
interface nsIRunnable;
%{ C++
template <class T> struct already_AddRefed;
/**
* After the default timezone changes, this topic is notified. Some systems may
* not support monitoring timezone.
*/
#define DEFAULT_TIMEZONE_CHANGED_OBSERVER_TOPIC "default-timezone-changed"
%}
/**

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

Просмотреть файл

@ -2309,5 +2309,18 @@ void WinUtils::EnableWindowOcclusion(const bool aEnable) {
reinterpret_cast<LPARAM>(&aEnable));
}
bool WinUtils::GetTimezoneName(wchar_t* aBuffer) {
DYNAMIC_TIME_ZONE_INFORMATION tzInfo;
DWORD tzid = GetDynamicTimeZoneInformation(&tzInfo);
if (tzid == TIME_ZONE_ID_INVALID) {
return false;
}
wcscpy_s(aBuffer, 128, tzInfo.TimeZoneKeyName);
return true;
}
} // namespace widget
} // namespace mozilla

Просмотреть файл

@ -600,6 +600,8 @@ class WinUtils {
static void EnableWindowOcclusion(const bool aEnable);
static bool GetTimezoneName(wchar_t* aBuffer);
private:
static WhitelistVec BuildWhitelist();

Просмотреть файл

@ -581,6 +581,10 @@ nsresult nsAppShell::Init() {
#endif // defined(ACCESSIBILITY)
}
if (!WinUtils::GetTimezoneName(mTimezoneName)) {
NS_WARNING("Unable to get system timezone name, timezone may be invalid\n");
}
return nsBaseAppShell::Init();
}
@ -734,6 +738,24 @@ bool nsAppShell::ProcessNextNativeEvent(bool mayWait) {
}
#endif
// Windows documentation suggets that WM_SETTINGSCHANGE is the message
// to watch for timezone changes, but experimentation showed that it
// doesn't fire on changing the timezone, but that WM_TIMECHANGE does,
// even if there's no immediate effect on the clock (e.g., changing
// from Pacific Daylight at UTC-7 to Arizona at UTC-7).
if (msg.message == WM_TIMECHANGE) {
// The message may not give us sufficient information to determine
// if the timezone changed, so keep track of it ourselves.
wchar_t systemTimezone[128];
bool getSystemTimeSucceeded =
WinUtils::GetTimezoneName(systemTimezone);
if (getSystemTimeSucceeded && wcscmp(systemTimezone, mTimezoneName)) {
nsBaseAppShell::OnSystemTimezoneChange();
wcscpy_s(mTimezoneName, 128, systemTimezone);
}
}
::TranslateMessage(&msg);
::DispatchMessageW(&msg);
}

Просмотреть файл

@ -56,6 +56,9 @@ class nsAppShell : public nsBaseAppShell {
Mutex mLastNativeEventScheduledMutex MOZ_UNANNOTATED;
TimeStamp mLastNativeEventScheduled;
std::vector<MSG> mMsgsToRepost;
private:
wchar_t mTimezoneName[128];
};
#endif // nsAppShell_h__