⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 293729 in webkit


Ignore:
Timestamp:
May 3, 2022, 10:06:02 AM (4 years ago)
Author:
yurys@chromium.org
Message:

[WK2] Add API to allow embedder to set a timezone override
​https://bugs.webkit.org/show_bug.cgi?id=213884

Source/JavaScriptCore:

Reviewed by Yusuke Suzuki.

  • runtime/DateConstructor.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

  • runtime/DateConversion.cpp:

(JSC::formatDateTime): Format the overridden timezone if it's enabled.

  • runtime/DateConversion.h:
  • runtime/DatePrototype.cpp:

(JSC::formateDateInstance):

  • runtime/JSDateMath.cpp:

(JSC::toICUTimeZone):
(JSC::toOpaqueICUTimeZone):
(JSC::OpaqueICUTimeZoneDeleter::operator()):
(JSC::DateCache::calculateLocalTimeOffset):
(JSC::DateCache::defaultTimeZone):
(JSC::DateCache::timeZoneDisplayNameOverride):
(JSC::DateCache::timeZoneCacheSlow): Apply timezone override if it is set.
(JSC::DateCache::resetIfNecessary):

  • runtime/JSDateMath.h:

Source/WebKit:

Reviewed by Yusuke Suzuki.

This patch adds:

  • new Cocoa API
  • new Glib API (targetting both WPE and GTK ports)
  • new C API (for the win port)

that allows the embedder to set a timezone override for the underlying PageConfiguration.
Since this API is not exposed in glib ports, a new contruct-time-only property was added to
the WebKitWebContext API. It would also allow fine-grained control over multiple pages, for
instance it's not possible currently to have two pages in different timezones.

No new layout tests, this change is covered by new API tests.

  • Shared/WebProcessCreationParameters.cpp:

(WebKit::WebProcessCreationParameters::encode const):
(WebKit::WebProcessCreationParameters::decode):

  • Shared/WebProcessCreationParameters.h:
  • UIProcess/API/APIProcessPoolConfiguration.cpp:

(API::ProcessPoolConfiguration::copy):

  • UIProcess/API/APIProcessPoolConfiguration.h:
  • UIProcess/API/C/WKContextConfigurationRef.cpp:

(WKContextConfigurationCopyTimeZoneOverride):
(WKContextConfigurationSetTimeZoneOverride):

  • UIProcess/API/C/WKContextConfigurationRef.h:
  • UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h:
  • UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm:

(-[_WKProcessPoolConfiguration timeZoneOverride]):
(-[_WKProcessPoolConfiguration setTimeZoneOverride:]):

  • UIProcess/API/glib/WebKitWebContext.cpp:

(webkitWebContextGetProperty):
(webkitWebContextSetProperty):
(webkitWebContextConstructed):
(webkit_web_context_class_init):
(webkit_web_context_set_time_zone_override):
(webkit_web_context_get_time_zone_override):

  • UIProcess/API/gtk/WebKitWebContext.h:
  • UIProcess/API/wpe/WebKitWebContext.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::initializeNewWebProcess):

  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::initializeWebProcess): Apply timezone override if any on process start.

Source/WTF:

Reviewed by Yusuke Suzuki.

  • wtf/DateMath.cpp: New APIs to control and query the timezone override.

(WTF::innerTimeZoneOverride): Static storage of the override informations.
(WTF::WTF_REQUIRES_LOCK):
(WTF::validateTimeZone): New function allowing to check if a timezone identifier is valid according to ICU's database and covert it
to UChar buffer suitable for passing to ucal.
(WTF::isTimeZoneValid):
(WTF::setTimeZoneOverride): New API to set the timezone override, this is meant to be
used on newly created WebProcesses. In addition to providing alternative name for the code
that calls into ICU library, on POSIX systems writes new timezone to "TZ" environement
variable to adjust result of strftime (called in formatDateTime).
(WTF::getTimeZoneOverride): Query the timezone override.

  • wtf/DateMath.h:

Tools:

Reviewed by Yusuke Suzuki.

Add API tests for the timezone configuration API. The GTK and WPE MiniBrowsers also gained
new runtime options allowing to exercise this new API.

  • MiniBrowser/gtk/main.c:

(activate):

  • MiniBrowser/wpe/main.cpp:

(main):

  • TestWebKitAPI/SourcesCocoa.txt:
  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/TimeZoneOverride.mm: Added.

(TimeZoneOverrideTest::runScriptAndExecuteCallback):
(TimeZoneOverrideTest::callAsyncFunctionBody):
(TEST_F):

  • TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:

(testWebContextTimeZoneOverride):
(testWebContextTimeZoneOverrideInWorker):
(beforeAll):

  • TestWebKitAPI/glib/WebKitGLib/TestMain.cpp:

(main):

  • TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp:

(runJavaScriptReadyCallback):
(WebViewTest::runJavaScriptAndWaitUntilFinished):

  • TestWebKitAPI/glib/WebKitGLib/WebViewTest.h:
  • flatpak/flatpakutils.py:

(WebkitFlatpak.run_in_sandbox):

Location:
trunk
Files:
1 added
29 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r293714 r293729  
     12022-05-03  Philippe Normand  <pnormand@igalia.com> and Pavel Feldman <pavel.feldman@gmail.com> and Yury Semikhatsky <yurys@chromium.org>
     2
     3        [WK2] Add API to allow embedder to set a timezone override
     4        https://bugs.webkit.org/show_bug.cgi?id=213884
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * runtime/DateConstructor.cpp:
     9        (JSC::JSC_DEFINE_HOST_FUNCTION):
     10        * runtime/DateConversion.cpp:
     11        (JSC::formatDateTime): Format the overridden timezone if it's enabled.
     12        * runtime/DateConversion.h:
     13        * runtime/DatePrototype.cpp:
     14        (JSC::formateDateInstance):
     15        * runtime/JSDateMath.cpp:
     16        (JSC::toICUTimeZone):
     17        (JSC::toOpaqueICUTimeZone):
     18        (JSC::OpaqueICUTimeZoneDeleter::operator()):
     19        (JSC::DateCache::calculateLocalTimeOffset):
     20        (JSC::DateCache::defaultTimeZone):
     21        (JSC::DateCache::timeZoneDisplayNameOverride):
     22        (JSC::DateCache::timeZoneCacheSlow): Apply timezone override if it is set.
     23        (JSC::DateCache::resetIfNecessary):
     24        * runtime/JSDateMath.h:
     25
     26
    1272022-04-29  Yusuke Suzuki  <ysuzuki@apple.com>
    228
  • trunk/Source/JavaScriptCore/runtime/JSDateMath.cpp

    r293693 r293729  
    434434{
    435435    ASSERT(!m_timeZoneCache);
     436
     437    Vector<UChar, 32> timeZoneID;
     438    getTimeZoneOverride(timeZoneID);
    436439#if HAVE(ICU_C_TIMEZONE_API)
    437440    auto* cache = new OpaqueICUTimeZone;
    438441
    439442    String canonical;
    440     Vector<UChar, 32> timeZoneID;
    441     auto status = callBufferProducingFunction(ucal_getHostTimeZone, timeZoneID);
     443    UErrorCode status = U_ZERO_ERROR;
     444    if (timeZoneID.isEmpty()) {
     445        status = callBufferProducingFunction(ucal_getHostTimeZone, timeZoneID);
     446        ASSERT_UNUSED(status, U_SUCCESS(status));
     447    }
    442448    if (U_SUCCESS(status)) {
    443449        Vector<UChar, 32> canonicalBuffer;
    … …  
    456462    m_timeZoneCache = std::unique_ptr<OpaqueICUTimeZone, OpaqueICUTimeZoneDeleter>(cache);
    457463#else
     464    if (!timeZoneID.isEmpty()) {
     465        m_timeZoneCache = std::unique_ptr<OpaqueICUTimeZone, OpaqueICUTimeZoneDeleter>(toOpaqueICUTimeZone(icu::TimeZone::createTimeZone(icu::UnicodeString(timeZoneID.data(), timeZoneID.size()))));
     466        return;
     467    }
    458468    // Do not use icu::TimeZone::createDefault. ICU internally has a cache for timezone and createDefault returns this cached value.
    459469    m_timeZoneCache = std::unique_ptr<OpaqueICUTimeZone, OpaqueICUTimeZoneDeleter>(toOpaqueICUTimeZone(icu::TimeZone::detectHostTimeZone()));
  • trunk/Source/WTF/ChangeLog

    r293688 r293729  
     12022-05-03  Philippe Normand  <pnormand@igalia.com> and Pavel Feldman <pavel.feldman@gmail.com> and Yury Semikhatsky <yurys@chromium.org>
     2
     3        [WK2] Add API to allow embedder to set a timezone override
     4        https://bugs.webkit.org/show_bug.cgi?id=213884
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * wtf/DateMath.cpp: New APIs to control and query the timezone override.
     9        (WTF::innerTimeZoneOverride): Static storage of the override informations.
     10        (WTF::WTF_REQUIRES_LOCK):
     11        (WTF::validateTimeZone): New function allowing to check if a timezone identifier is valid according to ICU's database and covert it
     12        to UChar buffer suitable for passing to ucal.
     13        (WTF::isTimeZoneValid):
     14        (WTF::setTimeZoneOverride): New API to set the timezone override, this is meant to be
     15        used on newly created WebProcesses. In addition to providing alternative name for the code
     16        that calls into ICU library, on POSIX systems writes new timezone to "TZ" environement
     17        variable to adjust result of strftime (called in formatDateTime).
     18        (WTF::getTimeZoneOverride): Query the timezone override.
     19        * wtf/DateMath.h:
     20
    1212022-05-02  Justin Michaud  <justin_michaud@apple.com>
    222
  • trunk/Source/WTF/wtf/DateMath.cpp

    r293484 r293729  
    7777#include <stdint.h>
    7878#include <time.h>
     79#include <unicode/ucal.h>
    7980#include <wtf/Assertions.h>
    8081#include <wtf/ASCIICType.h>
     82#include <wtf/Language.h>
     83#include <wtf/NeverDestroyed.h>
     84#include <wtf/ThreadSpecific.h>
    8185#include <wtf/text/StringBuilder.h>
     86#include <wtf/unicode/UTF8Conversion.h>
     87#include <wtf/unicode/icu/ICUHelpers.h>
    8288
    8389#if OS(WINDOWS)
    … …  
    9197{
    9298    return equalLettersIgnoringASCIICase(string, lowercaseLetters, length - 1);
     99}
     100
     101static Lock innerTimeZoneOverrideLock;
     102static Vector<UChar>& innerTimeZoneOverride() WTF_REQUIRES_LOCK(innerTimeZoneOverrideLock)
     103{
     104    static NeverDestroyed<Vector<UChar>> timeZoneOverride;
     105    return timeZoneOverride;
    93106}
    94107
    … …  
    10171030}
    10181031
     1032static std::optional<Vector<UChar, 32>> validateTimeZone(StringView timeZone)
     1033{
     1034    Vector<UChar, 32> buffer(timeZone.length());
     1035    timeZone.getCharactersWithUpconvert(buffer.data());
     1036
     1037    Vector<UChar, 32> canonicalBuffer;
     1038    auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, buffer.data(), buffer.size(), canonicalBuffer, nullptr);
     1039    if (!U_SUCCESS(status))
     1040        return std::nullopt;
     1041    return WTFMove(canonicalBuffer);
     1042}
     1043
     1044bool isTimeZoneValid(StringView timeZone)
     1045{
     1046    return validateTimeZone(timeZone).has_value();
     1047}
     1048
     1049bool setTimeZoneOverride(StringView timeZone)
     1050{
     1051    if (timeZone.isEmpty()) {
     1052        Locker locker { innerTimeZoneOverrideLock };
     1053        innerTimeZoneOverride().clear();
     1054        return true;
     1055    }
     1056
     1057    auto canonicalBuffer = validateTimeZone(timeZone);
     1058    if (!canonicalBuffer)
     1059        return false;
     1060
     1061    {
     1062        Locker locker { innerTimeZoneOverrideLock };
     1063        innerTimeZoneOverride() = WTFMove(*canonicalBuffer);
     1064    }
     1065    return true;
     1066}
     1067
     1068void getTimeZoneOverride(Vector<UChar, 32>& timeZoneID)
     1069{
     1070    Locker locker { innerTimeZoneOverrideLock };
     1071    timeZoneID = innerTimeZoneOverride();
     1072}
     1073
    10191074} // namespace WTF
  • trunk/Source/WTF/wtf/DateMath.h

    r292696 r293729  
    394394}
    395395
     396WTF_EXPORT_PRIVATE bool isTimeZoneValid(StringView);
     397WTF_EXPORT_PRIVATE bool setTimeZoneOverride(StringView);
     398WTF_EXPORT_PRIVATE void getTimeZoneOverride(Vector<UChar, 32>& timeZoneID);
     399
    396400// Returns combined offset in millisecond (UTC + DST).
    397401WTF_EXPORT_PRIVATE LocalTimeOffset calculateLocalTimeOffset(double utcInMilliseconds, TimeType = UTCTime);
    … …  
    399403} // namespace WTF
    400404
    401 using WTF::isLeapYear;
     405using WTF::calculateLocalTimeOffset;
    402406using WTF::dateToDaysFrom1970;
    403407using WTF::dayInMonthFromDayInYear;
    404408using WTF::dayInYear;
     409using WTF::getTimeZoneOverride;
     410using WTF::isLeapYear;
     411using WTF::isTimeZoneValid;
     412using WTF::jsCurrentTime;
     413using WTF::LocalTimeOffset;
     414using WTF::makeRFC2822DateString;
    405415using WTF::minutesPerHour;
    406416using WTF::monthFromDayInYear;
    … …  
    409419using WTF::msPerMinute;
    410420using WTF::msPerSecond;
     421using WTF::msToDays;
     422using WTF::msToHours;
     423using WTF::msToMinutes;
    411424using WTF::msToYear;
    412 using WTF::msToDays;
    413 using WTF::msToMinutes;
    414 using WTF::msToHours;
     425using WTF::parseDateFromNullTerminatedCharacters;
    415426using WTF::secondsPerDay;
    416427using WTF::secondsPerMinute;
    417 using WTF::parseDateFromNullTerminatedCharacters;
     428using WTF::setTimeZoneOverride;
     429using WTF::timeClip;
    418430using WTF::timeToMS;
    419 using WTF::makeRFC2822DateString;
    420 using WTF::LocalTimeOffset;
    421 using WTF::calculateLocalTimeOffset;
    422 using WTF::timeClip;
    423 using WTF::jsCurrentTime;
  • trunk/Source/WebKit/ChangeLog

    r293723 r293729  
     12022-05-03  Philippe Normand  <pnormand@igalia.com> and Yury Semikhatsky <yurys@chromium.org>
     2
     3        [WK2] Add API to allow embedder to set a timezone override
     4        https://bugs.webkit.org/show_bug.cgi?id=213884
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        This patch adds:
     9
     10        - new Cocoa API
     11        - new Glib API (targetting both WPE and GTK ports)
     12        - new C API (for the win port)
     13
     14        that allows the embedder to set a timezone override for the underlying PageConfiguration.
     15        Since this API is not exposed in glib ports, a new contruct-time-only property was added to
     16        the WebKitWebContext API. It would also allow fine-grained control over multiple pages, for
     17        instance it's not possible currently to have two pages in different timezones.
     18
     19        No new layout tests, this change is covered by new API tests.
     20
     21        * Shared/WebProcessCreationParameters.cpp:
     22        (WebKit::WebProcessCreationParameters::encode const):
     23        (WebKit::WebProcessCreationParameters::decode):
     24        * Shared/WebProcessCreationParameters.h:
     25        * UIProcess/API/APIProcessPoolConfiguration.cpp:
     26        (API::ProcessPoolConfiguration::copy):
     27        * UIProcess/API/APIProcessPoolConfiguration.h:
     28        * UIProcess/API/C/WKContextConfigurationRef.cpp:
     29        (WKContextConfigurationCopyTimeZoneOverride):
     30        (WKContextConfigurationSetTimeZoneOverride):
     31        * UIProcess/API/C/WKContextConfigurationRef.h:
     32        * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h:
     33        * UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm:
     34        (-[_WKProcessPoolConfiguration timeZoneOverride]):
     35        (-[_WKProcessPoolConfiguration setTimeZoneOverride:]):
     36        * UIProcess/API/glib/WebKitWebContext.cpp:
     37        (webkitWebContextGetProperty):
     38        (webkitWebContextSetProperty):
     39        (webkitWebContextConstructed):
     40        (webkit_web_context_class_init):
     41        (webkit_web_context_set_time_zone_override):
     42        (webkit_web_context_get_time_zone_override):
     43        * UIProcess/API/gtk/WebKitWebContext.h:
     44        * UIProcess/API/wpe/WebKitWebContext.h:
     45        * UIProcess/WebProcessPool.cpp:
     46        (WebKit::WebProcessPool::initializeNewWebProcess):
     47        * WebProcess/WebProcess.cpp:
     48        (WebKit::WebProcess::initializeWebProcess): Apply timezone override if any on process start.
     49
    1502022-05-03  Kimmo Kinnunen  <kkinnunen@apple.com>
    251
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp

    r292632 r293729  
    215215    encoder << accessibilityBusAddress;
    216216#endif
     217
     218    encoder << timeZoneOverride;
    217219}
    218220
    … …  
    572574#endif
    573575
     576    std::optional<String> timeZoneOverride;
     577    decoder >> timeZoneOverride;
     578    if (!timeZoneOverride)
     579        return false;
     580    parameters.timeZoneOverride = WTFMove(*timeZoneOverride);
     581
    574582    return true;
    575583}
  • trunk/Source/WebKit/Shared/WebProcessCreationParameters.h

    r292632 r293729  
    256256    String accessibilityBusAddress;
    257257#endif
     258
     259    String timeZoneOverride;
    258260};
    259261
  • trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.cpp

    r285584 r293729  
    8585    copy->m_presentingApplicationProcessToken = this->m_presentingApplicationProcessToken;
    8686#endif
     87    copy->m_timeZoneOverride = this->m_timeZoneOverride;
    8788    return copy;
    8889}
  • trunk/Source/WebKit/UIProcess/API/APIProcessPoolConfiguration.h

    r285584 r293729  
    164164    const std::optional<MemoryPressureHandler::Configuration>& memoryPressureHandlerConfiguration() const { return m_memoryPressureHandlerConfiguration; }
    165165#endif
     166
     167    void setTimeZoneOverride(const WTF::String& timeZoneOverride) { m_timeZoneOverride = timeZoneOverride; }
     168    const WTF::String& timeZoneOverride() const { return m_timeZoneOverride; }
    166169
    167170private:
    … …  
    207210    std::optional<audit_token_t> m_presentingApplicationProcessToken;
    208211#endif
     212    WTF::String m_timeZoneOverride;
    209213};
    210214
  • trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.cpp

    r258629 r293729  
    223223    toImpl(configuration)->setShouldConfigureJSCForTesting(value);
    224224}
     225
     226WKStringRef WKContextConfigurationCopyTimeZoneOverride(WKContextConfigurationRef configuration)
     227{
     228    return toCopiedAPI(toImpl(configuration)->timeZoneOverride());
     229}
     230
     231void WKContextConfigurationSetTimeZoneOverride(WKContextConfigurationRef configuration, WKStringRef timeZoneOverride)
     232{
     233    toImpl(configuration)->setTimeZoneOverride(toImpl(timeZoneOverride)->string());
     234}
  • trunk/Source/WebKit/UIProcess/API/C/WKContextConfigurationRef.h

    r258629 r293729  
    9696WK_EXPORT void WKContextConfigurationSetShouldConfigureJSCForTesting(WKContextConfigurationRef configuration, bool value);
    9797
     98WK_EXPORT WKStringRef WKContextConfigurationCopyTimeZoneOverride(WKContextConfigurationRef configuration);
     99WK_EXPORT void WKContextConfigurationSetTimeZoneOverride(WKContextConfigurationRef configuration, WKStringRef timeZoneOverride);
     100
    98101#ifdef __cplusplus
    99102}
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.h

    r285584 r293729  
    2525
    2626#import <Foundation/Foundation.h>
     27#import <WebKit/WKBase.h>
    2728#import <WebKit/WKFoundation.h>
    2829
    … …  
    7879@property (nonatomic) BOOL configureJSCForTesting WK_API_AVAILABLE(macos(10.15.4), ios(13.4));
    7980
     81@property (nonatomic, nullable, copy) NSString *timeZoneOverride WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     82
    8083@end
    8184
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKProcessPoolConfiguration.mm

    r285584 r293729  
    404404}
    405405
     406- (NSString *)timeZoneOverride
     407{
     408    return _processPoolConfiguration->timeZoneOverride();
     409}
     410
     411- (void)setTimeZoneOverride:(NSString *)timeZone
     412{
     413    _processPoolConfiguration->setTimeZoneOverride(timeZone);
     414}
     415
    406416#pragma mark WKObject protocol implementation
    407417
  • trunk/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp

    r293326 r293729  
    6666#include <memory>
    6767#include <pal/HysteresisActivity.h>
     68#include <wtf/DateMath.h>
    6869#include <wtf/FileSystem.h>
    6970#include <wtf/HashMap.h>
    … …  
    128129#endif
    129130    PROP_MEMORY_PRESSURE_SETTINGS,
     131    PROP_TIME_ZONE_OVERRIDE,
    130132    N_PROPERTIES,
    131133};
    … …  
    246248
    247249    WebKitMemoryPressureSettings* memoryPressureSettings;
     250
     251    String timeZoneOverride;
    248252};
    249253
    … …  
    351355#endif
    352356#endif
     357    case PROP_TIME_ZONE_OVERRIDE:
     358        g_value_set_string(value, webkit_web_context_get_time_zone_override(context));
     359        break;
    353360    default:
    354361        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    … …  
    386393        break;
    387394    }
     395    case PROP_TIME_ZONE_OVERRIDE: {
     396        if (const auto* override = g_value_get_string(value))
     397            webkit_web_context_set_time_zone_override(context, override);
     398        break;
     399    }
    388400    default:
    389401        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, paramSpec);
    … …  
    414426        g_clear_pointer(&priv->memoryPressureSettings, webkit_memory_pressure_settings_free);
    415427    }
     428    configuration.setTimeZoneOverride(priv->timeZoneOverride);
    416429
    417430    if (!priv->websiteDataManager)
    … …  
    572585            WEBKIT_TYPE_MEMORY_PRESSURE_SETTINGS,
    573586            static_cast<GParamFlags>(WEBKIT_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
     587
     588    /**
     589     * WebKitWebContext:time-zone-override:
     590     *
     591     * The timezone override for this web context. Setting this property provides a better
     592     * alternative to configure the timezone information for all webviews managed by the WebContext.
     593     * The other, less optimal, approach is to globally set the TZ environment variable in the
     594     * process before creating the context. However this approach might not be very convenient and
     595     * can have side-effects in your application.
     596     *
     597     * The expected values for this property are defined in the IANA timezone database. See this
     598     * wikipedia page for instance, https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
     599     *
     600     * Since: 2.38
     601     */
     602    sObjProperties[PROP_TIME_ZONE_OVERRIDE] =
     603        g_param_spec_string(
     604            "time-zone-override",
     605            _("Time Zone Override"),
     606            _("The time zone to use instead of the system one"),
     607            nullptr,
     608            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
    574609
    575610    g_object_class_install_properties(gObjectClass, N_PROPERTIES, sObjProperties);
    … …  
    18361871#endif
    18371872
     1873/**
     1874 * webkit_web_context_set_time_zone_override:
     1875 * @context: a #WebKitWebContext
     1876 * @time_zone_override: value to set
     1877 *
     1878 * Set the #WebKitWebContext:time-zone-override property. Refer to the IANA database for valid
     1879 * specifiers, https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
     1880 *
     1881 * Since: 2.38
     1882 */
     1883void webkit_web_context_set_time_zone_override(WebKitWebContext* context, const gchar* timeZoneOverride)
     1884{
     1885    g_return_if_fail(WEBKIT_IS_WEB_CONTEXT(context));
     1886    g_return_if_fail(isTimeZoneValid(timeZoneOverride));
     1887
     1888    context->priv->timeZoneOverride = String::fromUTF8(timeZoneOverride);
     1889}
     1890
     1891/**
     1892 * webkit_web_context_get_time_zone_override:
     1893 * @context: a #WebKitWebContext
     1894 *
     1895 * Get the #WebKitWebContext:time-zone-override property.
     1896 *
     1897 * Since: 2.38
     1898 */
     1899const gchar* webkit_web_context_get_time_zone_override(WebKitWebContext* context)
     1900{
     1901    g_return_val_if_fail(WEBKIT_IS_WEB_CONTEXT(context), nullptr);
     1902
     1903    return context->priv->timeZoneOverride.utf8().data();
     1904}
     1905
    18381906void webkitWebContextInitializeNotificationPermissions(WebKitWebContext* context)
    18391907{
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebContext.h

    r292263 r293729  
    303303webkit_web_context_get_use_system_appearance_for_scrollbars (WebKitWebContext      *context);
    304304
     305WEBKIT_API void
     306webkit_web_context_set_time_zone_override           (WebKitWebContext              *context,
     307                                                     const gchar                   *time_zone_override);
     308
     309WEBKIT_API const gchar*
     310webkit_web_context_get_time_zone_override           (WebKitWebContext              *context);
     311
    305312G_END_DECLS
    306313
  • trunk/Source/WebKit/UIProcess/API/wpe/WebKitWebContext.h

    r292263 r293729  
    292292                                                     WebKitUserMessage             *message);
    293293
     294WEBKIT_API void
     295webkit_web_context_set_time_zone_override           (WebKitWebContext              *context,
     296                                                     const gchar                   *time_zone_override);
     297
     298WEBKIT_API const gchar*
     299webkit_web_context_get_time_zone_override           (WebKitWebContext              *context);
     300
    294301G_END_DECLS
    295302
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r293562 r293729  
    914914    parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
    915915
     916    parameters.timeZoneOverride = m_configuration->timeZoneOverride();
     917
    916918    // Add any platform specific parameters
    917919    platformInitializeWebProcess(process, parameters);
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r293665 r293729  
    144144#include <wtf/Algorithms.h>
    145145#include <wtf/CallbackAggregator.h>
     146#include <wtf/DateMath.h>
    146147#include <wtf/Language.h>
    147148#include <wtf/ProcessPrivilege.h>
    … …  
    507508    setCacheModel(parameters.cacheModel);
    508509
     510    if (!parameters.timeZoneOverride.isEmpty())
     511        setTimeZoneOverride(parameters.timeZoneOverride);
     512
    509513    if (!parameters.overrideLanguages.isEmpty()) {
    510514        LOG_WITH_STREAM(Language, stream << "Web Process initialization is setting overrideLanguages: " << parameters.overrideLanguages);
  • trunk/Tools/ChangeLog

    r293681 r293729  
     12022-05-03  Philippe Normand  <pnormand@igalia.com> and Yury Semikhatsky <yurys@chromium.org>
     2
     3        [WK2] Add API to allow embedder to set a timezone override
     4        https://bugs.webkit.org/show_bug.cgi?id=213884
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Add API tests for the timezone configuration API. The GTK and WPE MiniBrowsers also gained
     9        new runtime options allowing to exercise this new API.
     10
     11        * MiniBrowser/gtk/main.c:
     12        (activate):
     13        * MiniBrowser/wpe/main.cpp:
     14        (main):
     15        * TestWebKitAPI/SourcesCocoa.txt:
     16        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     17        * TestWebKitAPI/Tests/WebKitCocoa/TimeZoneOverride.mm: Added.
     18        (TimeZoneOverrideTest::runScriptAndExecuteCallback):
     19        (TimeZoneOverrideTest::callAsyncFunctionBody):
     20        (TEST_F):
     21        * TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp:
     22        (testWebContextTimeZoneOverride):
     23        (testWebContextTimeZoneOverrideInWorker):
     24        (beforeAll):
     25        * TestWebKitAPI/glib/WebKitGLib/TestMain.cpp:
     26        (main):
     27        * TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp:
     28        (runJavaScriptReadyCallback):
     29        (WebViewTest::runJavaScriptAndWaitUntilFinished):
     30        * TestWebKitAPI/glib/WebKitGLib/WebViewTest.h:
     31        * flatpak/flatpakutils.py:
     32        (WebkitFlatpak.run_in_sandbox):
     33
    1342022-05-02  Wenson Hsieh  <wenson_hsieh@apple.com>
    235
  • trunk/Tools/MiniBrowser/gtk/main.c

    r280382 r293729  
    5353static const char *proxy;
    5454static gboolean darkMode;
     55static char* timeZone;
    5556static gboolean enableITP;
    5657static gboolean enableSandbox;
    … …  
    150151    { "enable-sandbox", 0, 0, G_OPTION_ARG_NONE, &enableSandbox, "Enable web process sandbox support", NULL },
    151152    { "exit-after-load", 0, 0, G_OPTION_ARG_NONE, &exitAfterLoad, "Quit the browser after the load finishes", NULL },
     153    { "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
    152154    { "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WebKitGTK version", NULL },
    153155    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, 0, "[URL…]" },
    … …  
    675677        "use-system-appearance-for-scrollbars", FALSE,
    676678#endif
     679        "time-zone-override", timeZone,
    677680        NULL);
    678681    g_object_unref(manager);
  • trunk/Tools/MiniBrowser/wpe/main.cpp

    r288168 r293729  
    4747static const char* proxy;
    4848const char* bgColor;
     49static char* timeZone;
    4950static gboolean enableITP;
    5051static gboolean printVersion;
    … …  
    6465    { "bg-color", 0, 0, G_OPTION_ARG_STRING, &bgColor, "Window background color. Default: white", "COLOR" },
    6566    { "enable-itp", 0, 0, G_OPTION_ARG_NONE, &enableITP, "Enable Intelligent Tracking Prevention (ITP)", nullptr },
     67    { "time-zone", 't', 0, G_OPTION_ARG_STRING, &timeZone, "Set time zone", "TIMEZONE" },
    6668    { "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WPE version", nullptr },
    6769    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, nullptr, "[URL]" },
    … …  
    230232        webkit_website_data_manager_set_tls_errors_policy(manager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
    231233
    232     auto* webContext = webkit_web_context_new_with_website_data_manager(manager);
     234    auto* webContext = WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT, "website-data-manager", manager, "time-zone-override", timeZone, nullptr));
    233235    g_object_unref(manager);
    234236
  • trunk/Tools/TestWebKitAPI/SourcesCocoa.txt

    r292680 r293729  
    241241Tests/WebKitCocoa/TextSize.mm
    242242Tests/WebKitCocoa/TextWidth.mm
     243Tests/WebKitCocoa/TimeZoneOverride.mm
    243244Tests/WebKitCocoa/TopContentInset.mm
    244245Tests/WebKitCocoa/UIDelegate.mm
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r293681 r293729  
    30333033                EC79F168BE454E579E417B05 /* Markable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Markable.cpp; sourceTree = "<group>"; };
    30343034                ECA680CD1E68CC0900731D20 /* StringUtilities.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StringUtilities.mm; sourceTree = "<group>"; };
     3035                F3CEF6B82808F2D3001E23A5 /* TimeZoneOverride.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TimeZoneOverride.mm; sourceTree = "<group>"; };
    30353036                F3FC3EE213678B7300126A65 /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; };
    30363037                F4010B7F24DA24AC00A876E2 /* NavigationSwipeTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigationSwipeTests.mm; sourceTree = "<group>"; };
    … …  
    37053706                                5C16F8FB230C942B0074C4A8 /* TextSize.mm */,
    37063707                                C22FA32A228F8708009D7988 /* TextWidth.mm */,
     3708                                F3CEF6B82808F2D3001E23A5 /* TimeZoneOverride.mm */,
    37073709                                5C73A81A2323059800DEA85A /* TLSDeprecation.mm */,
    37083710                                CDE195B31CFE0ADE0053D256 /* TopContentInset.mm */,
  • trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebContext.cpp

    r292696 r293729  
    992992}
    993993
     994static void testWebContextTimeZoneOverride(WebViewTest* test, gconstpointer)
     995{
     996    GUniqueOutPtr<GError> error;
     997    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("const date = new Date(1651511226050); date.getTimezoneOffset()", &error.outPtr());
     998    g_assert_nonnull(javascriptResult);
     999    g_assert_no_error(error.get());
     1000    // By default the test harness uses the Pacific/Los_Angeles timezone which is 7 hours (420 minutes) compared to GMT.
     1001    g_assert_cmpint(WebViewTest::javascriptResultToNumber(javascriptResult), ==, 420);
     1002
     1003    // Create a new context configured with time zone overide set to Berlin which is 120 minutes ahead of the GMT offset.
     1004    auto webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT,
     1005        "time-zone-override", "Europe/Berlin", nullptr)));
     1006    g_assert_cmpstr(webkit_web_context_get_time_zone_override(webContext.get()), ==, "Europe/Berlin");
     1007    auto webView = Test::adoptView(Test::createWebView(webContext.get()));
     1008    javascriptResult = test->runJavaScriptAndWaitUntilFinished("const date = new Date(1651511226050); date.getTimezoneOffset()", &error.outPtr(), webView.get());
     1009    g_assert_nonnull(javascriptResult);
     1010    g_assert_no_error(error.get());
     1011    g_assert_cmpint(WebViewTest::javascriptResultToNumber(javascriptResult), ==, -120);
     1012}
     1013
     1014static void testWebContextTimeZoneOverrideInWorker(WebViewTest* test, gconstpointer)
     1015{
     1016    GUniqueOutPtr<GError> error;
     1017    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("Intl.DateTimeFormat().resolvedOptions().timeZone", &error.outPtr());
     1018    g_assert_nonnull(javascriptResult);
     1019    g_assert_no_error(error.get());
     1020    // By default the test harness uses the Pacific/Los_Angeles.
     1021    g_assert_cmpstr(WebViewTest::javascriptResultToCString(javascriptResult), ==, "America/Los_Angeles");
     1022    // Create a new context configured with time zone overide set to Berlin which is 120 minutes ahead of the GMT offset.
     1023    auto webContext = adoptGRef(WEBKIT_WEB_CONTEXT(g_object_new(WEBKIT_TYPE_WEB_CONTEXT,
     1024        "time-zone-override", "Europe/Berlin", nullptr)));
     1025    g_assert_cmpstr(webkit_web_context_get_time_zone_override(webContext.get()), ==, "Europe/Berlin");
     1026    auto webView = Test::adoptView(Test::createWebView(webContext.get()));
     1027
     1028    test->runJavaScriptAndWaitUntilFinished(
     1029        "window.results = [Intl.DateTimeFormat().resolvedOptions().timeZone];"
     1030        "for (let i = 0; i < 3; i++) {"
     1031        "  const worker = new Worker('data:text/javascript,self.postMessage(Intl.DateTimeFormat().resolvedOptions().timeZone)');"
     1032        "  worker.onmessage = message => results.push(message.data);"
     1033        "}", &error.outPtr(), webView.get());
     1034    do {
     1035        javascriptResult = test->runJavaScriptAndWaitUntilFinished("results.length", &error.outPtr(), webView.get());
     1036        g_assert_nonnull(javascriptResult);
     1037        g_assert_no_error(error.get());
     1038    } while (WebViewTest::javascriptResultToNumber(javascriptResult) < 4);
     1039
     1040    javascriptResult = test->runJavaScriptAndWaitUntilFinished("results.join(', ')", &error.outPtr(), webView.get());
     1041    g_assert_nonnull(javascriptResult);
     1042    g_assert_no_error(error.get());
     1043    g_assert_cmpstr(WebViewTest::javascriptResultToCString(javascriptResult), ==, "Europe/Berlin, Europe/Berlin, Europe/Berlin, Europe/Berlin");
     1044}
     1045
    9941046void beforeAll()
    9951047{
    … …  
    10091061    ProxyTest::add("WebKitWebContext", "proxy", testWebContextProxySettings);
    10101062    MemoryPressureTest::add("WebKitWebContext", "memory-pressure", testMemoryPressureSettings);
     1063    WebViewTest::add("WebKitWebContext", "timezone", testWebContextTimeZoneOverride);
     1064    WebViewTest::add("WebKitWebContext", "timezone-worker", testWebContextTimeZoneOverrideInWorker);
    10111065}
    10121066
  • trunk/Tools/TestWebKitAPI/glib/WebKitGLib/TestMain.cpp

    r284156 r293729  
    133133    // Get rid of runtime warnings about deprecated properties and signals, since they break the tests.
    134134    g_setenv("G_ENABLE_DIAGNOSTIC", "0", TRUE);
     135    g_setenv("TZ", "America/Los_Angeles", TRUE);
    135136    g_test_bug_base("https://bugs.webkit.org/");
    136137
  • trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.cpp

    r283972 r293729  
    307307}
    308308
    309 static void runJavaScriptReadyCallback(GObject*, GAsyncResult* result, WebViewTest* test)
    310 {
    311     test->m_javascriptResult = webkit_web_view_run_javascript_finish(test->m_webView, result, test->m_javascriptError);
     309static void runJavaScriptReadyCallback(GObject* object, GAsyncResult* result, WebViewTest* test)
     310{
     311    test->m_javascriptResult = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, test->m_javascriptError);
    312312    g_main_loop_quit(test->m_mainLoop);
    313313}
    … …  
    325325}
    326326
    327 WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const char* javascript, GError** error)
     327WebKitJavascriptResult* WebViewTest::runJavaScriptAndWaitUntilFinished(const char* javascript, GError** error, WebKitWebView* webView)
    328328{
    329329    if (m_javascriptResult)
    … …  
    331331    m_javascriptResult = 0;
    332332    m_javascriptError = error;
    333     webkit_web_view_run_javascript(m_webView, javascript, 0, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
     333    if (!webView)
     334        webView = m_webView;
     335    webkit_web_view_run_javascript(webView, javascript, 0, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptReadyCallback), this);
    334336    g_main_loop_run(m_mainLoop);
    335337
  • trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebViewTest.h

    r282654 r293729  
    7474#endif
    7575
    76     WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**);
     76    WebKitJavascriptResult* runJavaScriptAndWaitUntilFinished(const char* javascript, GError**, WebKitWebView* = nullptr);
    7777    WebKitJavascriptResult* runJavaScriptFromGResourceAndWaitUntilFinished(const char* resource, GError**);
    7878    WebKitJavascriptResult* runJavaScriptInWorldAndWaitUntilFinished(const char* javascript, const char* world, GError**);
  • trunk/Tools/flatpak/flatpakutils.py

    r292494 r293729  
    858858
    859859            sandbox_environment.update({
    860                 "TZ": "PST8PDT",
     860                "TZ": "America/Los_Angeles",
    861861            })
    862862
Note: See TracChangeset for help on using the changeset viewer.