Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohossettings.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/private/qohoscommon_p.h>
6#include <cmath>
7#include <cstring>
8#include <functional>
9#include <qohosdeviceinfo_p.h>
10#include <qohosjsutils.h>
11#include <qohosplugincore.h>
12#include <qohosutils.h>
13#include <stdexcept>
14#include <string>
15#include <utility>
16
18
19namespace {
20
21constexpr const char *fontSizeScalePropertyName = "font_scale";
22constexpr const char *windowPcModeSwitchStatusPropertyName = "window_pcmode_switch_status";
23
24QOhosOptional<std::string> tryGetDataItemValue(const std::string &name, const std::string &domainName)
25{
26 return QtOhos::evalInJsThreadWithPromise<QOhosOptional<std::string>>(
27 [&](QtOhos::JsState &jsState, auto evalPromise) {
28 auto defaultQAbility = jsState.defaultQAbilityPeer()->qAbility();
29 if (defaultQAbility.IsEmpty()) {
30 evalPromise(makeEmptyQOhosOptional());
31 return;
32 }
33
34 auto thenCatchPromises = std::move(evalPromise).makeThenCatchBranches(Q_FUNC_INFO);
35 jsState.evalToPromiseOrRejectOnThrow(
36 "@ohos.settings.getValue(*)",
37 {defaultQAbility.get("context"), name, domainName})
38 .onThen([thenPromise = std::move(thenCatchPromises.first)](const QtOhos::CallbackInfo &cbInfo) {
39 std::string result = cbInfo.getFirstArg<QNapi::String>(Q_FUNC_INFO);
40 thenPromise(makeQOhosOptional(result));
41 })
42 .onCatch([catchPromise = std::move(thenCatchPromises.second), name, domainName](const QtOhos::CallbackInfo &) {
43 qOhosPrintfError(
44 "Got error from @ohos.settings.getValue(..., '%s', '%s').",
45 name.c_str(), domainName.c_str());
46 catchPromise(makeEmptyQOhosOptional());
47 });
48 },
49 Q_FUNC_INFO);
50}
51
52template<typename T>
53QOhosOptional<T> tryGetDataItemTypedValue(const std::string &name, const std::string &domainName);
54
55template<>
56QOhosOptional<double> tryGetDataItemTypedValue(const std::string &name, const std::string &domainName)
57{
58 auto optStringValue = tryGetDataItemValue(name, domainName);
59 auto optDoubleValue = optStringValue.has_value()
60 ? QtOhos::tryParseStringAsFiniteDouble(optStringValue.value())
62
63 if (optStringValue.has_value() && !optDoubleValue.has_value()) {
64 qOhosPrintfError(
65 "OHOS settings value %s/%s ('%s') is not correct double value, assuming empty setting",
66 name.c_str(), domainName.c_str(), optStringValue.value().c_str());
67 }
68
69 return optDoubleValue;
70}
71
73{
74 return QtOhos::evalInJsThread([](QtOhos::JsState &jsState) {
75 return jsState.eval<QNapi::String>("@ohos.settings.domainName.USER_PROPERTY").Utf8Value();
76 },
77 Q_FUNC_INFO);
78}
79
81{
82 return jsState.eval<QNapi::String>("@ohos.settings.domainName.USER_PROPERTY");
83}
84
86{
87 return jsState.defaultQAbilityPeer()->qAbility().eval<QNapi::Object>("context");
88}
89
91 QtOhos::JsState &jsState, const QNapi::Object &context, const std::string &name)
92{
93 return jsState.eval<QNapi::String>(
94 "@ohos.settings.getValueSync(*)",
95 {context, name, "", settingsUserPropertyDomainName(jsState)});
96}
97
99 QtOhos::JsState &jsState, QNapi::Object context, const std::string &name,
100 std::function<void(QtOhos::JsState &)> onChanged)
101{
102 const std::string domainName = settingsUserPropertyDomainName(jsState);
103
104 const bool registered = jsState.eval<QNapi::Boolean>(
105 "@ohos.settings.registerKeyObserver(*)",
106 {
107 context, name, domainName,
108 [onChanged = std::move(onChanged)](const QtOhos::CallbackInfo &cbInfo) {
109 onChanged(cbInfo.jsState());
110 }
111 });
112 if (!registered) {
113 qOhosPrintfWarning(
114 "Failed to register observer for settings key '%s' in domain '%s'.",
115 name.c_str(), domainName.c_str());
116 return nullptr;
117 }
118
119 auto contextRefPtr = QtOhos::moveToSharedPtr(QNapi::Reference<>::makePersistentFrom(context));
120 return std::shared_ptr<void>(
121 nullptr,
122 [contextRefPtr, name, domainName](auto) {
124 [&](QtOhos::JsState &jsState) {
125 auto contextRef = std::move(*contextRefPtr);
126 jsState.eval<QNapi::Value>(
127 "@ohos.settings.unregisterKeyObserver(*)",
128 {contextRef.Value(), name, domainName});
129 },
130 Q_FUNC_INFO);
131 });
132}
133
135{
136 if (jsState.defaultQAbilityPeer()->qAbility().IsEmpty())
137 return false;
138
139 return readSettingValue(jsState, settingsContext(jsState), windowPcModeSwitchStatusPropertyName) == "true";
140}
141
143{
145 return [] { return true; };
146
147 return QtOhos::makeDataSource<bool>(
148 readWindowPcModeEnabled,
149 [](QtOhos::JsState &jsState, QOhosConsumer<bool> valueChangedConsumer) -> std::shared_ptr<void> {
150 // FIXME: the observer must use the launching UIAbility's context. By
151 // API definition @ohos.settings does not accept the application
152 // context, and free-window state is not part of the app Configuration.
153 // That context can be destroyed while the process lives, orphaning the
154 // observer. The orphaned observer keeps firing (verified on device), so
155 // the cached value stays correct. Revisit when the platform exposes
156 // settings observation on the application context.
157 if (jsState.defaultQAbilityPeer()->qAbility().IsEmpty())
158 return nullptr;
159
160 return registerSettingsKeyObserver(
161 jsState, settingsContext(jsState), windowPcModeSwitchStatusPropertyName,
162 [valueChangedConsumer = std::move(valueChangedConsumer)](QtOhos::JsState &jsState) {
163 valueChangedConsumer(readWindowPcModeEnabled(jsState));
164 });
165 },
166 makeQOhosNoOpConsumer(),
167 Q_FUNC_INFO);
168}
169
170}
171
176
178{
179 constexpr double defaultFontSizeScale = 1.0;
180 const auto maybeFontSizeScaleSetting = tryGetDataItemTypedValue<double>(
181 fontSizeScalePropertyName, getOhosSettingsUserPropertyDomainName());
182
183 if (!maybeFontSizeScaleSetting.has_value()) {
184 qOhosPrintfWarning(
185 "Cannot obtain '%s' property. Assuming its default fallback mode value %f",
186 fontSizeScalePropertyName, defaultFontSizeScale);
187 return defaultFontSizeScale;
188 }
189
190 return maybeFontSizeScaleSetting.value();
191}
192
194{
195 return m_windowPcModeEnabled();
196}
197
198QT_END_NAMESPACE
bool isWindowPcModeEnabled() const
double fontSizeScale() const
Combined button and popup list for selecting options.
QOhosOptional< std::string > tryGetDataItemValue(const std::string &name, const std::string &domainName)
bool readWindowPcModeEnabled(QtOhos::JsState &jsState)
constexpr const char * windowPcModeSwitchStatusPropertyName
QOhosSupplier< bool > makeWindowPcModeEnabledSupplier()
QOhosOptional< T > tryGetDataItemTypedValue(const std::string &name, const std::string &domainName)
std::shared_ptr< void > registerSettingsKeyObserver(QtOhos::JsState &jsState, QNapi::Object context, const std::string &name, std::function< void(QtOhos::JsState &)> onChanged)
QOhosOptional< double > tryGetDataItemTypedValue(const std::string &name, const std::string &domainName)
constexpr const char * fontSizeScalePropertyName
std::string getOhosSettingsUserPropertyDomainName()
std::string settingsUserPropertyDomainName(QtOhos::JsState &jsState)
QNapi::Object settingsContext(QtOhos::JsState &jsState)
std::string readSettingValue(QtOhos::JsState &jsState, const QNapi::Object &context, const std::string &name)
void runInJsThreadAndWait(const std::function< void(JsState &)> &task, std::string callerContextName={})
std::nullopt_t makeEmptyQOhosOptional()