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
qohosplatformservices.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/QUrl>
6#include <QtCore/private/qnapi_p.h>
7#include <QtCore/private/qohoscommon_p.h>
8#include <QtCore/qfileinfo.h>
9#include <QtCore/qscopeguard.h>
10#include <QtGui/QColor>
11#include <cstdlib>
12#include <filemanagement/file_uri/oh_file_uri.h>
13#include <memory>
14#include <qohosenums.h>
15#include <qohosplugincore.h>
16#include <utility>
17
19
20using QOhosWantConstantFlags = QtOhos::enums::ohos::app::ability::wantConstant::Flags;
21
22namespace {
23
24void callStartAbility(QNapi::Object baseQAbility, QNapi::Object want, QOhosConsumer<bool> resultConsumer)
25{
26 qOhosPrintfDebug("Calling startAbility() with Want '%s'", QNapi::toJsonString(want).c_str());
27
28 baseQAbility.evalToPromiseOrRejectOnThrow("context.startAbility(*)", {want})
29 .withContext(std::move(resultConsumer))
30 .onThenWithContext(
31 [](const QtOhos::CallbackInfo &, auto &resultConsumer) {
32 qOhosPrintfDebug("Got success from startAbility()");
33 resultConsumer(true);
34 })
35 .onCatchWithContext(
36 [](const QtOhos::CallbackInfo &cbInfo, auto &resultConsumer) {
37 QtOhos::logJsCallbackError(cbInfo, "Got error from startAbility()");
38 resultConsumer(false);
39 });
40}
41
42std::string callOhFileUriConversionFunc(
43 FileManagement_ErrCode (*convFunc)(const char *, unsigned int, char **),
44 const char *convFuncName, const std::string &input)
45{
46 std::string outputString;
47
48 char *outputPtr = nullptr;
49 auto outputPtrGuard = qScopeGuard(std::bind(::free, outputPtr));
50 auto convFuncRetVal = convFunc(input.c_str(), input.size(), &outputPtr);
51
52 if (convFuncRetVal == FileManagement_ErrCode::ERR_OK && outputPtr != nullptr) {
53 outputString = outputPtr;
54 } else {
55 qWarning(
56 "OH FileUri conversion function '%s' failed for input '%s', retval: %d",
57 convFuncName, input.c_str(), static_cast<int>(convFuncRetVal));
58 }
59
60 return outputString;
61}
62
63class QOhosColorPicker : public QPlatformServiceColorPicker
64{
65public:
66 QOhosColorPicker();
67
68 void pickColor() override;
69
70private:
71 std::shared_ptr<void> m_ohosColorPickingHandle;
72};
73
74QOhosColorPicker::QOhosColorPicker() = default;
75
76void QOhosColorPicker::pickColor()
77{
78 struct Context
79 {
80 std::unique_ptr<QObject> colorConsumerQtContext;
81 QOhosConsumer<QOhosOptional<quint32>> colorConsumer;
82 };
83
84 auto sharedContext = QtOhos::moveToSharedPtr(
85 Context{
86 .colorConsumerQtContext = std::make_unique<QObject>(),
87 .colorConsumer =
88 [this](QOhosOptional<quint32> rgbaColor) {
89 if (rgbaColor.has_value())
90 Q_EMIT colorPicked(QColor::fromRgba(rgbaColor.value()));
91 },
92 });
93
94 auto colorConsumerProxy = QtOhos::moveToSharedPtr(
95 [weakContext = QtOhos::makeWeakPtr(sharedContext)](QOhosOptional<quint32> rgbaColor) {
96 auto sharedContext = weakContext.lock();
97 if (sharedContext) {
98 QMetaObject::invokeMethod(
99 sharedContext->colorConsumerQtContext.get(),
100 [weakContext, rgbaColor]() {
101 auto sharedContext = weakContext.lock();
102 if (sharedContext)
103 sharedContext->colorConsumer(rgbaColor);
104 },
105 Qt::QueuedConnection);
106 }
107 });
108
110 [colorConsumerProxy](QtOhos::JsState &jsState) {
111 jsState.evalToPromiseOrRejectOnThrow("@kit.Penkit.imageFeaturePicker.pickForResult()")
112 .onThen(
113 [colorConsumerProxy](const QtOhos::CallbackInfo &cbInfo) {
114 auto pickedColorInfo = cbInfo.getFirstArg<QNapi::Object>(Q_FUNC_INFO);
115 auto color = pickedColorInfo.get<QNapi::Object>("color");
116 QColor qColor(
117 color.get<QNapi::Number>("red"),
118 color.get<QNapi::Number>("green"),
119 color.get<QNapi::Number>("blue"),
120 color.get<QNapi::Number>("alpha"));
121 (*colorConsumerProxy)(makeQOhosOptional(qColor.rgba()));
122 })
123 .onCatch(
124 [colorConsumerProxy](const QtOhos::CallbackInfo &cbInfo) {
125 QtOhos::logJsCallbackError(cbInfo, "@kit.Penkit.imageFeaturePicker.pickForResult() failed");
126 (*colorConsumerProxy)(makeEmptyQOhosOptional());
127 });
128 });
129
130 m_ohosColorPickingHandle = std::move(sharedContext);
131}
132} // namespace
133
135
137{
138 Q_UNUSED(parent);
139 return new QOhosColorPicker;
140}
141
142bool QOhosPlatformServices::hasCapability(Capability capability) const
143{
144 switch (capability) {
145 case ColorPicking:
146 return true;
147 default:
148 return false;
149 }
150}
151
152bool QOhosPlatformServices::openUrl(const QUrl &url)
153{
154 return QtOhos::evalInJsThreadWithPromise<bool>(
155 [&](QtOhos::JsState &jsState, QOhosTaskPromise<bool> evalPromise) {
156 auto mainUiAbility = jsState.defaultQAbilityPeer()->qAbility();
157 if (mainUiAbility.IsEmpty()) {
158 evalPromise(false);
159 return;
160 }
161
162 auto want =
163 !url.isLocalFile()
164 ? QNapi::makeObject(
165 jsState.env(),
166 {
167 {"action", "ohos.want.action.viewData"},
168 {"entities", QNapi::makeArray(jsState.env(), {"entity.system.browsable"})},
169 {"uri", url.toString().toStdString()},
170 })
171 : QFileInfo(url.path()).isDir()
172 ? QNapi::makeObject(
173 jsState.env(),
174 {
175 {"abilityName", "MainAbility"},
176 {"bundleName", "com.huawei.hmos.filemanager"},
177 {
178 "parameters",
179 QNapi::makeObject(
180 jsState.env(),
181 {
182 {"fileUri", mapPathToOhosUriInJsThread(url.path().toStdString())},
183 })
184 },
185 })
186 : QNapi::makeObject(
187 jsState.env(),
188 {
189 {"action", "ohos.want.action.viewData"},
190 {"uri", mapPathToOhosUriInJsThread(url.path().toStdString())},
191 {
192 "flags",
193 jsState.mapOhosEnumToJs(QOhosWantConstantFlags::FLAG_AUTH_READ_URI_PERMISSION).Int32Value()
194 | jsState.mapOhosEnumToJs(QOhosWantConstantFlags::FLAG_AUTH_WRITE_URI_PERMISSION).Int32Value()
195 },
196 });
197 callStartAbility(mainUiAbility, want, std::move(evalPromise));
198 },
199 Q_FUNC_INFO);
200}
201
203{
204 return openUrl(url);
205}
206
208{
209 return QByteArray("Ohos");
210}
211
213{
214 return callOhFileUriConversionFunc(OH_FileUri_GetUriFromPath, "OH_FileUri_GetUriFromPath", path);
215}
216
218{
219 return callOhFileUriConversionFunc(OH_FileUri_GetPathFromUri, "OH_FileUri_GetPathFromUri", ohosFileUri);
220}
221
222QT_END_NAMESPACE
static std::string mapPathToOhosUriInJsThread(const std::string &path)
QPlatformServiceColorPicker * colorPicker(QWindow *parent) override
QByteArray desktopEnvironment() const override
QPlatformServices::desktopEnvironment returns the active desktop environment.
static std::string mapOhosFileUriToPathInJsThread(const std::string &ohosFileUri)
bool openUrl(const QUrl &url) override
bool openDocument(const QUrl &url) override
bool hasCapability(Capability capability) const override
Combined button and popup list for selecting options.
void invokeInJsThread(std::function< void(JsState &)> task)
std::nullopt_t makeEmptyQOhosOptional()