#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+namespace {
+double time_offset_ = 0.0;
+} // namespace
+#endif
+
namespace base {
namespace {
exploded.hour, exploded.minute, exploded.second);
}
+#if BUILDFLAG(IS_TIZEN_TV)
+// Static
+double Time::TimeOffset() {
+ return time_offset_;
+}
+
+// Static
+void Time::SetTimeOffset(double time_offset) {
+ time_offset_ = time_offset;
+}
+#endif
} // namespace base
// `TimeDelta::FromMiseconds()` for `TimeDelta`. http://crbug.com/634507
static constexpr Time FromInternalValue(int64_t us) { return Time(us); }
+#if BUILDFLAG(IS_TIZEN_TV)
+ // Gets time offset
+ static double TimeOffset();
+ // Sets time offset
+ static void SetTimeOffset(double time_offset);
+#endif
+
private:
friend class time_internal::TimeBase<Time>;
converted_time.LocalExplode(&to_exploded);
if (ExplodedMostlyEquals(to_exploded, exploded)) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ converted_time -= Microseconds(TimeOffset());
+#endif
*time = converted_time;
return true;
}
// Combine seconds and microseconds in a 64-bit field containing microseconds
// since the epoch. That's enough for nearly 600 centuries. Adjust from
// Unix (1970) to Windows (1601) epoch.
+#if BUILDFLAG(IS_TIZEN_TV)
+ return Time() +
+ Microseconds((tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec) +
+ Time::kTimeTToMicrosecondsOffset +
+ Time::TimeOffset() * Time::kMicrosecondsPerMillisecond);
+#else
return Time() +
Microseconds((tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec) +
Time::kTimeTToMicrosecondsOffset);
+#endif
}
Time TimeNowFromSystemTimeIgnoringOverride() {
// Drop privilege of zygote process.
kZygoteCommandDropProcessPrivileges = 7,
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ kZygoteCommandSetTimeZoneOffset = 8,
+#endif
};
} // namespace content
return pid_;
}
#endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void ZygoteCommunication::SetTimeZoneOffset(
+ const std::string& time_zone_offset) {
+ DCHECK(init_);
+ base::Pickle pickle;
+
+ pickle.WriteInt(kZygoteCommandSetTimeZoneOffset);
+ pickle.WriteString(time_zone_offset);
+ base::AutoLock lock(control_lock_);
+ if (!SendMessage(pickle, NULL))
+ LOG(ERROR) << "Failed to send SetTimeZoneOffset message to zygote";
+}
+#endif
} // namespace content
pid_t GetZygotePid();
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ void SetTimeZoneOffset(const std::string&);
+#endif
+
private:
// Should be called every time a Zygote child is born.
void ZygoteChildBorn(pid_t process);
#include "sandbox/policy/sandbox.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "third_party/icu/source/i18n/unicode/timezone.h"
+#endif
+
// See
// https://chromium.googlesource.com/chromium/src/+/main/docs/linux/zygote.md
case kZygoteCommandReinitializeLogging:
HandleReinitializeLoggingRequest(iter, std::move(fds));
return false;
+#if BUILDFLAG(IS_TIZEN_TV)
+ case kZygoteCommandSetTimeZoneOffset:
+ HandleSetTimeZoneOffset(iter);
+ return false;
+#endif
default:
NOTREACHED();
break;
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void Zygote::HandleSetTimeZoneOffset(base::PickleIterator iter) {
+ std::string time_zone_offset;
+ if (!iter.ReadString(&time_zone_offset))
+ return;
+ icu::TimeZone::adoptDefault(icu::TimeZone::createTimeZone(
+ icu::UnicodeString::fromUTF8(time_zone_offset)));
+}
+#endif
} // namespace content
// Attempt to reap all outstanding children in |to_reap_|.
void ReapChildren();
+#if BUILDFLAG(IS_TIZEN_TV)
+ void HandleSetTimeZoneOffset(base::PickleIterator iter);
+#endif
+
// The Zygote needs to keep some information about each process. Most
// notably what the PID of the process is inside the PID namespace of
// the Zygote and whether or not a process was started by the
std::string cookie_path = CanonPathWithString(
url, parsed_cookie.HasPath() ? parsed_cookie.Path() : std::string());
+#if BUILDFLAG(IS_TIZEN_TV)
+ /* creation_time is associated with base::Time::Now() which includes
+ * TimeOffset.
+ * Remove offset so we have true UTC and mimic a server time by default.
+ */
+ Time cookie_server_time(creation_time -
+ base::Microseconds(Time::TimeOffset()));
+#else
Time cookie_server_time(creation_time);
+#endif
+
if (server_time.has_value() && !server_time->is_null())
cookie_server_time = server_time.value();
}
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+void DeviceService::UpdateTimeZone(const std::string& timezone) {
+ if (time_zone_monitor_)
+ time_zone_monitor_->UpdateTimeZone(timezone);
+}
+#endif
} // namespace device
static void OverrideNFCProviderBinderForTesting(NFCProviderBinder binder);
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ void UpdateTimeZone(const std::string& timezone) override;
+#endif
+
private:
// mojom::DeviceService implementation:
void BindFingerprint(
enabled_features += [ "enable_device_posture" ]
}
+ if (tizen_product_tv) {
+ enabled_features += [ "tizen_product_tv" ]
+ }
+
public_deps = [
":generic_sensor",
":mojom",
// Binds a UsbDeviceManagerTest endpoint.
BindUsbDeviceManagerTest(pending_receiver<UsbDeviceManagerTest> receiver);
+
+ // Update to specified TimeZone
+ [EnableIf=tizen_product_tv]
+ UpdateTimeZone(string timezone);
};
clients_.Add(std::move(client));
}
+#if BUILDFLAG(IS_TIZEN_TV)
+void TimeZoneMonitor::UpdateTimeZone(std::string time_zone_str) {
+ std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createTimeZone(
+ icu::UnicodeString::fromUTF8(time_zone_str)));
+ UpdateIcuAndNotifyClients(std::move(timezone));
+}
+#endif
} // namespace device
void Bind(mojo::PendingReceiver<device::mojom::TimeZoneMonitor> receiver);
+#if BUILDFLAG(IS_TIZEN_TV)
+ void UpdateTimeZone(std::string time_zone);
+#endif
+
protected:
TimeZoneMonitor();
#include "browser/background_sync_controller_efl.h"
#include "browser/geolocation/geolocation_permission_context_efl.h"
#include "browser/webdata/web_data_service_factory.h"
+#include "common/render_messages_ewk.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "content/common/paths_efl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "eweb_context.h"
#include "network_delegate_efl.h"
#include "permission_controller_delegate_efl.h"
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "content/common/zygote/zygote_communication_linux.h"
+#include "content/public/browser/device_service.h"
+#include "content/public/common/zygote/zygote_handle.h"
+#include "third_party/icu/source/i18n/unicode/timezone.h"
+#endif
+
using namespace autofill::prefs;
using namespace password_manager::prefs;
using std::pair;
return cert_list;
}
+void SendToAllRenderers(IPC::Message* message) {
+ content::RenderProcessHost::iterator it =
+ content::RenderProcessHost::AllHostsIterator();
+ while (!it.IsAtEnd()) {
+ it.GetCurrentValue()->Send(new IPC::Message(*message));
+ it.Advance();
+ }
+ delete message;
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void FormatHour(long time, std::ostringstream& ost) {
+ static const double kMinutesPerHour = 60.0;
+ ost.width(2);
+ ost.fill('0');
+ ost << (int)(time / kMinutesPerHour);
+ ost << ":";
+ ost.width(2);
+ ost.fill('0');
+ ost << (int)(time % static_cast<int>(kMinutesPerHour));
+}
+
+std::string CreateTimeZoneID(double time_zone_offset,
+ double daylight_saving_time) {
+ static const double kMilliSecondsPerMinute = 60.0 * 1000.0;
+ static const char* kMinusSign = "-";
+ static const char* kPlusSign = "+";
+
+ long time_zone = (long)(time_zone_offset / kMilliSecondsPerMinute);
+ const long daylight_saving =
+ (long)(daylight_saving_time / kMilliSecondsPerMinute);
+
+ if (!time_zone && (daylight_saving <= 0))
+ return std::string();
+
+ std::ostringstream ost;
+ const char* sign = kMinusSign;
+
+ long total_offset = time_zone + daylight_saving;
+ if (total_offset < 0) {
+ total_offset *= -1;
+ sign = kPlusSign;
+ }
+ ost << "GMT" << sign;
+ FormatHour(total_offset, ost);
+
+ return ost.str();
+}
+#endif
} // namespace
namespace content {
special_storage_policy_efl_ = new SpecialStoragePolicyEfl();
return special_storage_policy_efl_.get();
}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void BrowserContextEfl::SetTimeOffset(double time_offset) {
+ if (time_offset_ == time_offset)
+ return;
+ time_offset_ = time_offset;
+ base::Time::SetTimeOffset(time_offset);
+ SendToAllRenderers(new EwkViewMsg_SetTimeOffset(time_offset_));
+}
+
+double BrowserContextEfl::GetTimeOffset() {
+ return time_offset_;
+}
+
+void BrowserContextEfl::SetTimeZoneOffset(double time_zone_offset,
+ double daylight_saving_time) {
+ if (time_zone_offset_ == time_zone_offset &&
+ daylight_saving_time_ == daylight_saving_time)
+ return;
+
+ std::string zone_id_str =
+ CreateTimeZoneID(time_zone_offset, daylight_saving_time);
+ if (zone_id_str.empty())
+ return;
+
+ time_zone_offset_ = time_zone_offset;
+ daylight_saving_time_ = daylight_saving_time;
+
+ /**
+ For China is UTC+8:00 or GMT+8:00
+ TZ needs to set it with opposite sign as follows:
+ TZ=UTC-8:00; export TZ
+ or,
+ TZ=GMT-8:00; export TZ
+ or,
+ TZ=Asia/Shanghai;export TZ
+ For US EST (GMT-5:00, New York):
+ TZ=UTC+5:00; export TZ
+ or,
+ TZ=GMT+5:00; export TZ
+ or,
+ TZ=America/New_York;export TZ
+ */
+ setenv("TZ", zone_id_str.c_str(), 1);
+ tzset();
+
+ // correct opposite sign from TZ
+ double total_offset = time_zone_offset + daylight_saving_time;
+ if (total_offset >= 0) {
+ if (zone_id_str.find("-") != std::string::npos)
+ zone_id_str.replace(zone_id_str.find("-"), 1, "+");
+ } else {
+ if (zone_id_str.find("+") != std::string::npos)
+ zone_id_str.replace(zone_id_str.find("+"), 1, "-");
+ }
+ LOG(INFO) << "timezone reset to " << zone_id_str;
+ icu::TimeZone::adoptDefault(
+ icu::TimeZone::createTimeZone(icu::UnicodeString::fromUTF8(zone_id_str)));
+
+ GetGenericZygote()->SetTimeZoneOffset(zone_id_str);
+ GetDeviceService().UpdateTimeZone(zone_id_str);
+}
+#endif
}
void CreateNetworkDelegate();
+#if BUILDFLAG(IS_TIZEN_TV)
+ double GetTimeOffset();
+ void SetTimeOffset(double);
+ void SetTimeZoneOffset(double time_zone_offset, double daylight_saving_time);
+#endif
+
private:
// certificate_path should be either be a directory with CA certs, a CA cert
// file or a colon-separated list of those. CA cert files should have *.crt
std::unique_ptr<PermissionControllerDelegate> permission_controller_delegate_;
scoped_refptr<SpecialStoragePolicyEfl> special_storage_policy_efl_;
std::string certificate_path_;
+#if BUILDFLAG(IS_TIZEN_TV)
+ double time_offset_ = 0.0;
+ double time_zone_offset_ = 0.0;
+ double daylight_saving_time_ = 0.0;
+#endif
};
}
const char kCORSEnabledURLSchemes[] = "cors-enabled-url-schemes";
// JS plugin mime types
const char kJSPluginMimeTypes[] = "jsplugin-mime-types";
+// Time offset
+const char kTimeOffset[] = "time-offset";
#endif
// Widget Info
CONTENT_EXPORT extern const char kCORSEnabledURLSchemes[];
// JS plugin mime types
CONTENT_EXPORT extern const char kJSPluginMimeTypes[];
+// Enables time offset
+CONTENT_EXPORT extern const char kTimeOffset[];
#endif
CONTENT_EXPORT extern const char kTizenAppId[];
CONTENT_EXPORT extern const char kTizenAppVersion[];
IPC_MESSAGE_CONTROL1(HbbtvMsg_RegisterURLSchemesAsCORSEnabled,
std::string /* scheme */)
+IPC_MESSAGE_CONTROL1(EwkViewMsg_SetTimeOffset, double /* time offset */)
#endif
command_line->AppendSwitchASCII(switches::kCORSEnabledURLSchemes,
cors_enabled_url_schemes);
}
+
+ const double time_offset =
+ static_cast<BrowserContextEfl*>(host->GetBrowserContext())
+ ->GetTimeOffset();
+ if (time_offset) {
+ command_line->AppendSwitchASCII(switches::kTimeOffset,
+ base::NumberToString(time_offset));
+ }
#endif
const std::string& injectedBundlePath = context->GetInjectedBundlePath();
HbbtvWidgetHost::Get().RegisterURLSchemesAsCORSEnabled(schemes);
}
+
+void EWebContext::SetTimeOffset(double time_offset) {
+ browser_context_->SetTimeOffset(time_offset);
+}
+
+void EWebContext::SetTimeZoneOffset(double time_zone_offset,
+ double daylight_saving_time) {
+ browser_context_->SetTimeZoneOffset(time_zone_offset, daylight_saving_time);
+}
#endif
void EWebContext::SetMaxRefreshRate(int max_refresh_rate) {
Ewk_Application_Type GetApplicationType() const { return application_type_; }
void RegisterJSPluginMimeTypes(const Eina_List*);
void RegisterURLSchemesAsCORSEnabled(const Eina_List* schemes_list);
+ void SetTimeOffset(double time_offset);
+ void SetTimeZoneOffset(double time_zone_offset, double daylight_saving_time);
#endif
void EnableAppControl(bool enabled);
const Eina_List* schemes_list) {
impl->RegisterURLSchemesAsCORSEnabled(schemes_list);
}
+
+void Ewk_Context::SetTimeOffset(double time_offset) {
+ impl->SetTimeOffset(time_offset);
+}
+
+void Ewk_Context::SetTimeZoneOffset(double time_zone_offset,
+ double daylight_saving_time) {
+ impl->SetTimeZoneOffset(time_zone_offset, daylight_saving_time);
+}
#endif
void Ewk_Context::SetMaxRefreshRate(int max_refresh_rate) {
void RegisterJSPluginMimeTypes(const Eina_List*);
// Registers url scheme as CORS enabled for HBBTV
void RegisterURLSchemesAsCORSEnabled(const Eina_List* schemes_list);
+ // Sets time offset for HBBTV
+ void SetTimeOffset(double time_offset);
+ // Sets time zone offset for HBBTV
+ void SetTimeZoneOffset(double time_zone_offset, double daylight_saving_time);
#endif
void EnableAppControl(bool enabled);
#endif
}
-void ewk_context_time_offset_set(Ewk_Context* context, double time_offset) {}
+void ewk_context_time_offset_set(Ewk_Context* context, double time_offset) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ EINA_SAFETY_ON_NULL_RETURN(context);
+ LOG(INFO) << __FUNCTION__ << ", time_offset: " << time_offset;
+ context->SetTimeOffset(time_offset);
+#else
+ LOG_EWK_API_MOCKUP("Only for Tizen TV");
+#endif
+}
+
void ewk_context_timezone_offset_set(Ewk_Context* context,
double time_zone_offset,
- double daylight_saving_time) {}
+ double daylight_saving_time) {
+#if BUILDFLAG(IS_TIZEN_TV)
+ EINA_SAFETY_ON_NULL_RETURN(context);
+ LOG(INFO) << __FUNCTION__ << ", time_zone_offset: " << time_zone_offset
+ << ", daylight_saving_time: " << daylight_saving_time;
+ context->SetTimeZoneOffset(time_zone_offset, daylight_saving_time);
+#else
+ LOG_EWK_API_MOCKUP("Only for Tizen TV");
+#endif
+}
+
void ewk_context_default_zoom_factor_set(Ewk_Context* context,
double zoom_factor) {
EINA_SAFETY_ON_NULL_RETURN(context);
// XXX: config.h needs to be included before internal blink headers.
// XXX2: It'd be great if we did not include internal blibk headers.
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
-
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "base/strings/string_number_conversions.h"
+#endif
using blink::WebCache;
using blink::WebRuntimeFeatures;
using content::RenderThread;
if (command_line.HasSwitch(switches::kEnableViewMode))
WebRuntimeFeatures::EnableCSSViewModeMediaFeature(true);
#endif
+#if BUILDFLAG(IS_TIZEN_TV)
+ if (command_line.HasSwitch(switches::kTimeOffset)) {
+ std::string time_offset =
+ command_line.GetSwitchValueASCII(switches::kTimeOffset);
+ double offset = 0.0;
+ if (base::StringToDouble(time_offset, &offset))
+ OnSetTimeOffset(offset);
+ }
+#endif
}
bool RenderThreadObserverEfl::OnControlMessageReceived(const IPC::Message& message)
IPC_MESSAGE_HANDLER(EwkProcessMsg_SetExtensibleAPI, OnSetExtensibleAPI)
IPC_MESSAGE_HANDLER(EwkProcessMsg_UpdateTizenExtensible,
OnUpdateTizenExtensible)
+#if BUILDFLAG(IS_TIZEN_TV)
+ IPC_MESSAGE_HANDLER(EwkViewMsg_SetTimeOffset, OnSetTimeOffset)
+#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
void RenderThreadObserverEfl::OnUpdateTizenExtensible(
const std::map<std::string, bool>& params) {
TizenExtensible::GetInstance()->UpdateTizenExtensible(params);
-}
\ No newline at end of file
+}
+
+#if BUILDFLAG(IS_TIZEN_TV)
+void RenderThreadObserverEfl::OnSetTimeOffset(double time_offset) {
+ if (time_offset_ == time_offset)
+ return;
+
+ time_offset_ = time_offset;
+ base::Time::SetTimeOffset(time_offset);
+}
+#endif
\ No newline at end of file
explicit RenderThreadObserverEfl(ContentRendererClientEfl* content_client);
bool OnControlMessageReceived(const IPC::Message& message) override;
void OnClearCache();
+#if BUILDFLAG(IS_TIZEN_TV)
+ void OnSetTimeOffset(double time_offset);
+#endif
-private:
+ private:
void OnSetCache(int64_t cache_total_capacity);
ContentRendererClientEfl* content_client_;
void OnSetExtensibleAPI(const std::string& api_name, bool enable);
void OnUpdateTizenExtensible(const std::map<std::string, bool>& params);
+#if BUILDFLAG(IS_TIZEN_TV)
+ double time_offset_ = 0.0;
+#endif
};
#endif