no message
This commit is contained in:
269
cocos/platform/ohos/FileUtils-ohos.cpp
Normal file
269
cocos/platform/ohos/FileUtils-ohos.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "platform/ohos/FileUtils-ohos.h"
|
||||
#include <hilog/log.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <regex>
|
||||
#include "base/Log.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "base/std/container/string.h"
|
||||
#include "platform/java/jni/JniHelper.h"
|
||||
|
||||
#define ASSETS_FOLDER_NAME "@assets/"
|
||||
|
||||
#ifndef JCLS_HELPER
|
||||
#define JCLS_HELPER "com/cocos/lib/CocosHelper"
|
||||
#endif
|
||||
|
||||
namespace cc {
|
||||
|
||||
ResourceManager *FileUtilsOHOS::ohosResourceMgr = {};
|
||||
ccstd::string FileUtilsOHOS::ohosAssetPath = {};
|
||||
|
||||
namespace {
|
||||
|
||||
ccstd::string rawfilePrefix = "entry/resources/rawfile/";
|
||||
|
||||
void printRawfiles(ResourceManager *mgr, const ccstd::string &path) {
|
||||
auto *file = OpenRawFile(mgr, path.c_str());
|
||||
if (file) {
|
||||
HILOG_DEBUG(LOG_APP, "PrintRawfile %{public}s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
RawDir *dir = OpenRawDir(mgr, path.c_str());
|
||||
if (dir) {
|
||||
auto fileCnt = GetRawFileCount(dir);
|
||||
for (auto i = 0; i < fileCnt; i++) {
|
||||
ccstd::string subFile = GetRawFileName(dir, i);
|
||||
auto newPath = path + "/" + subFile; // NOLINT
|
||||
auto debugPtr = newPath.c_str();
|
||||
HILOG_ERROR(LOG_APP, " find path %{public}s", newPath.c_str());
|
||||
printRawfiles(mgr, newPath);
|
||||
}
|
||||
} else {
|
||||
HILOG_ERROR(LOG_APP, "Invalidate path %{public}s", path.c_str());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
FileUtils *createFileUtils() {
|
||||
return ccnew FileUtilsOHOS();
|
||||
}
|
||||
|
||||
bool FileUtilsOHOS::initResourceManager(ResourceManager *mgr, const ccstd::string &assetPath, const ccstd::string &moduleName) {
|
||||
CC_ASSERT(mgr);
|
||||
ohosResourceMgr = mgr;
|
||||
if (!assetPath.empty() && assetPath[assetPath.length() - 1] != '/') {
|
||||
ohosAssetPath = assetPath + "/";
|
||||
} else {
|
||||
ohosAssetPath = assetPath;
|
||||
}
|
||||
if (!moduleName.empty()) {
|
||||
setRawfilePrefix(moduleName + "/resources/rawfile/");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileUtilsOHOS::setRawfilePrefix(const ccstd::string &prefix) {
|
||||
rawfilePrefix = prefix;
|
||||
}
|
||||
|
||||
ResourceManager *FileUtilsOHOS::getResourceManager() {
|
||||
return ohosResourceMgr;
|
||||
}
|
||||
|
||||
FileUtilsOHOS::FileUtilsOHOS() {
|
||||
init();
|
||||
}
|
||||
|
||||
bool FileUtilsOHOS::init() {
|
||||
_defaultResRootPath = ASSETS_FOLDER_NAME;
|
||||
return FileUtils::init();
|
||||
}
|
||||
|
||||
FileUtils::Status FileUtilsOHOS::getContents(const ccstd::string &filename, ResizableBuffer *buffer) {
|
||||
if (filename.empty()) {
|
||||
return FileUtils::Status::NOT_EXISTS;
|
||||
}
|
||||
|
||||
ccstd::string fullPath = fullPathForFilename(filename);
|
||||
if (fullPath.empty()) {
|
||||
return FileUtils::Status::NOT_EXISTS;
|
||||
}
|
||||
|
||||
if (fullPath[0] == '/') {
|
||||
return FileUtils::getContents(fullPath, buffer);
|
||||
}
|
||||
|
||||
ccstd::string relativePath;
|
||||
size_t position = fullPath.find(ASSETS_FOLDER_NAME);
|
||||
if (0 == position) {
|
||||
// "@assets/" is at the beginning of the path and we don't want it
|
||||
relativePath = rawfilePrefix + fullPath.substr(strlen(ASSETS_FOLDER_NAME));
|
||||
} else {
|
||||
relativePath = fullPath;
|
||||
}
|
||||
|
||||
if (nullptr == ohosResourceMgr) {
|
||||
HILOG_ERROR(LOG_APP, "... FileUtilsAndroid::assetmanager is nullptr");
|
||||
return FileUtils::Status::NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
RawFile *asset = OpenRawFile(ohosResourceMgr, relativePath.c_str());
|
||||
if (nullptr == asset) {
|
||||
HILOG_DEBUG(LOG_APP, "asset (%{public}s) is nullptr", filename.c_str());
|
||||
return FileUtils::Status::OPEN_FAILED;
|
||||
}
|
||||
|
||||
auto size = GetRawFileSize(asset);
|
||||
buffer->resize(size);
|
||||
|
||||
assert(buffer->buffer());
|
||||
|
||||
int readsize = ReadRawFile(asset, buffer->buffer(), size);
|
||||
CloseRawFile(asset);
|
||||
|
||||
// TODO(unknown): read error
|
||||
if (readsize < size) {
|
||||
if (readsize >= 0) {
|
||||
buffer->resize(readsize);
|
||||
}
|
||||
return FileUtils::Status::READ_FAILED;
|
||||
}
|
||||
|
||||
return FileUtils::Status::OK;
|
||||
}
|
||||
|
||||
bool FileUtilsOHOS::isAbsolutePath(const ccstd::string &strPath) const {
|
||||
return !strPath.empty() && (strPath[0] == '/' || strPath.find(ASSETS_FOLDER_NAME) == 0);
|
||||
}
|
||||
|
||||
ccstd::string FileUtilsOHOS::getWritablePath() const {
|
||||
auto tmp = cc::JniHelper::callStaticStringMethod(JCLS_HELPER, "getWritablePath");
|
||||
if (tmp.empty()) {
|
||||
return "./";
|
||||
}
|
||||
return tmp.append("/");
|
||||
}
|
||||
|
||||
bool FileUtilsOHOS::isFileExistInternal(const ccstd::string &strFilePath) const {
|
||||
if (strFilePath.empty()) return false;
|
||||
auto filePath = strFilePath;
|
||||
auto fileFound = false;
|
||||
|
||||
if (strFilePath[0] == '/') { // absolute path
|
||||
struct stat info;
|
||||
return ::stat(filePath.c_str(), &info) == 0;
|
||||
}
|
||||
|
||||
// relative path
|
||||
if (strFilePath.find(_defaultResRootPath) == 0) {
|
||||
filePath = rawfilePrefix + filePath.substr(_defaultResRootPath.length());
|
||||
}
|
||||
|
||||
auto rawFile = OpenRawFile(ohosResourceMgr, filePath.c_str());
|
||||
if (rawFile != nullptr) {
|
||||
CloseRawFile(rawFile);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileUtilsOHOS::isDirectoryExistInternal(const ccstd::string &dirPath) const {
|
||||
if (dirPath.empty()) return false;
|
||||
ccstd::string dirPathMf = dirPath[dirPath.length() - 1] == '/' ? dirPath.substr(0, dirPath.length() - 1) : dirPath;
|
||||
|
||||
if (dirPathMf[0] == '/') {
|
||||
struct stat st;
|
||||
return stat(dirPathMf.c_str(), &st) == 0 && S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
if (dirPathMf.find(_defaultResRootPath) == 0) {
|
||||
dirPathMf = rawfilePrefix + dirPathMf.substr(_defaultResRootPath.length(), dirPathMf.length());
|
||||
}
|
||||
assert(ohosResourceMgr);
|
||||
auto dir = OpenRawDir(ohosResourceMgr, dirPathMf.c_str());
|
||||
if (dir != nullptr) {
|
||||
CloseRawDir(dir);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ccstd::string FileUtilsOHOS::expandPath(const ccstd::string &input, bool *isRawFile) const {
|
||||
if (!input.empty() && input[0] == '/') {
|
||||
if (isRawFile) *isRawFile = false;
|
||||
return input;
|
||||
}
|
||||
const auto fullpath = fullPathForFilename(input);
|
||||
|
||||
if (fullpath.find(_defaultResRootPath) == 0) {
|
||||
if (isRawFile) *isRawFile = true;
|
||||
return rawfilePrefix + fullpath.substr(_defaultResRootPath.length(), fullpath.length());
|
||||
}
|
||||
|
||||
if (isRawFile) *isRawFile = false;
|
||||
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
std::pair<int, std::function<void()>> FileUtilsOHOS::getFd(const ccstd::string &path) const {
|
||||
bool isRawFile = false;
|
||||
const auto fullpath = expandPath(path, &isRawFile);
|
||||
if (isRawFile) {
|
||||
RawFile *rf = OpenRawFile(ohosResourceMgr, fullpath.c_str());
|
||||
// FIXME: try reuse file
|
||||
const auto bufSize = GetRawFileSize(rf);
|
||||
auto fileCache = ccstd::vector<char>(bufSize);
|
||||
auto *buf = fileCache.data();
|
||||
// Fill buffer
|
||||
const auto readBytes = ReadRawFile(rf, buf, bufSize);
|
||||
assert(readBytes == bufSize); // read failure ?
|
||||
auto fd = syscall(__NR_memfd_create, fullpath.c_str(), 0);
|
||||
{
|
||||
auto writeBytes = ::write(fd, buf, bufSize); // Write can fail?
|
||||
assert(writeBytes == bufSize);
|
||||
::lseek(fd, 0, SEEK_SET);
|
||||
}
|
||||
if (errno != 0) {
|
||||
const auto *errMsg = strerror(errno);
|
||||
CC_LOG_ERROR("failed to open buffer fd %s", errMsg);
|
||||
}
|
||||
return std::make_pair(fd, [fd]() {
|
||||
close(fd);
|
||||
});
|
||||
}
|
||||
|
||||
FILE *fp = fopen(fullpath.c_str(), "rb");
|
||||
return std::make_pair(fileno(fp), [fp]() {
|
||||
fclose(fp);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
72
cocos/platform/ohos/FileUtils-ohos.h
Normal file
72
cocos/platform/ohos/FileUtils-ohos.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
//clang-format off
|
||||
#include <cstdint>
|
||||
//clang-format on
|
||||
#include <rawfile/raw_dir.h>
|
||||
#include <rawfile/raw_file.h>
|
||||
#include <rawfile/resource_manager.h>
|
||||
#include "base/Macros.h"
|
||||
#include "cocos/platform/FileUtils.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class CC_DLL FileUtilsOHOS : public FileUtils {
|
||||
public:
|
||||
static bool initResourceManager(ResourceManager *mgr, const ccstd::string &assetPath, const ccstd::string &moduleName);
|
||||
|
||||
static void setRawfilePrefix(const ccstd::string &prefix);
|
||||
|
||||
static ResourceManager *getResourceManager();
|
||||
|
||||
FileUtilsOHOS();
|
||||
~FileUtilsOHOS() override = default;
|
||||
|
||||
bool init() override;
|
||||
|
||||
FileUtils::Status getContents(const ccstd::string &filename, ResizableBuffer *buffer) override;
|
||||
|
||||
bool isAbsolutePath(const ccstd::string &strPath) const override;
|
||||
|
||||
ccstd::string getWritablePath() const override;
|
||||
|
||||
ccstd::string expandPath(const ccstd::string &input, bool *isRawFile) const;
|
||||
|
||||
std::pair<int, std::function<void()>> getFd(const ccstd::string &path) const;
|
||||
|
||||
private:
|
||||
bool isFileExistInternal(const ccstd::string &strFilePath) const override;
|
||||
|
||||
bool isDirectoryExistInternal(const ccstd::string &dirPath) const override;
|
||||
|
||||
/* weak ref, do not need release */
|
||||
static ResourceManager *ohosResourceMgr;
|
||||
static ccstd::string ohosAssetPath;
|
||||
|
||||
friend class FileUtils;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
105
cocos/platform/ohos/OhosPlatform.cpp
Normal file
105
cocos/platform/ohos/OhosPlatform.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "modules/Screen.h"
|
||||
#include "modules/System.h"
|
||||
#include "platform/java/jni/glue/JniNativeGlue.h"
|
||||
#include "platform/java/modules/Accelerometer.h"
|
||||
#include "platform/java/modules/Battery.h"
|
||||
#include "platform/java/modules/Network.h"
|
||||
#include "platform/java/modules/SystemWindow.h"
|
||||
#include "platform/java/modules/SystemWindowManager.h"
|
||||
#include "platform/java/modules/Vibrator.h"
|
||||
#include "platform/ohos/OhosPlatform.h"
|
||||
|
||||
#include "base/memory/Memory.h"
|
||||
namespace cc {
|
||||
OhosPlatform::OhosPlatform() {
|
||||
_jniNativeGlue = JNI_NATIVE_GLUE();
|
||||
}
|
||||
|
||||
int OhosPlatform::init() {
|
||||
registerInterface(std::make_shared<Accelerometer>());
|
||||
registerInterface(std::make_shared<Battery>());
|
||||
registerInterface(std::make_shared<Network>());
|
||||
registerInterface(std::make_shared<Screen>());
|
||||
registerInterface(std::make_shared<System>());
|
||||
registerInterface(std::make_shared<SystemWindowManager>());
|
||||
registerInterface(std::make_shared<Vibrator>());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OhosPlatform::getSdkVersion() const {
|
||||
return _jniNativeGlue->getSdkVersion();
|
||||
}
|
||||
|
||||
int32_t OhosPlatform::run(int argc, const char **argv) {
|
||||
std::thread mainLogicThread([this, argc, argv]() {
|
||||
waitWindowInitialized();
|
||||
UniversalPlatform::run(argc, argv);
|
||||
onDestroy();
|
||||
});
|
||||
mainLogicThread.detach();
|
||||
_jniNativeGlue->waitRunning();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OhosPlatform::waitWindowInitialized() {
|
||||
_jniNativeGlue->setRunning(true);
|
||||
while (_jniNativeGlue->isRunning()) {
|
||||
pollEvent();
|
||||
NativeWindowType *wndHandle = _jniNativeGlue->getWindowHandle();
|
||||
if (wndHandle != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OhosPlatform::exit() {
|
||||
|
||||
}
|
||||
|
||||
int32_t OhosPlatform::loop() {
|
||||
while (_jniNativeGlue->isRunning()) {
|
||||
pollEvent();
|
||||
runTask();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OhosPlatform::pollEvent() {
|
||||
_jniNativeGlue->execCommand();
|
||||
if (!_jniNativeGlue->isPause()) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
_jniNativeGlue->flushTasksOnGameThread();
|
||||
}
|
||||
|
||||
ISystemWindow *OhosPlatform::createNativeWindow(uint32_t windowId, void *externalHandle) {
|
||||
return ccnew SystemWindow(windowId, externalHandle);
|
||||
}
|
||||
|
||||
}; // namespace cc
|
||||
47
cocos/platform/ohos/OhosPlatform.h
Normal file
47
cocos/platform/ohos/OhosPlatform.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform/UniversalPlatform.h"
|
||||
|
||||
namespace cc {
|
||||
class JniNativeGlue;
|
||||
class CC_DLL OhosPlatform : public UniversalPlatform {
|
||||
public:
|
||||
OhosPlatform();
|
||||
int init() override;
|
||||
void pollEvent() override;
|
||||
int32_t run(int argc, const char **argv) override;
|
||||
int getSdkVersion() const override;
|
||||
int32_t loop() override;
|
||||
void exit() override;
|
||||
ISystemWindow *createNativeWindow(uint32_t windowId, void *externalHandle) override;
|
||||
|
||||
private:
|
||||
void waitWindowInitialized();
|
||||
|
||||
JniNativeGlue *_jniNativeGlue;
|
||||
};
|
||||
} // namespace cc
|
||||
50
cocos/platform/ohos/jni/AbilityConsts.h
Normal file
50
cocos/platform/ohos/jni/AbilityConsts.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace cc {
|
||||
namespace ohos {
|
||||
enum {
|
||||
ABILITY_CMD_INPUT_CHANGED,
|
||||
ABILITY_CMD_INIT_WINDOW,
|
||||
ABILITY_CMD_TERM_WINDOW,
|
||||
ABILITY_CMD_WINDOW_RESIZED,
|
||||
ABILITY_CMD_WINDOW_REDRAW_NEEDED,
|
||||
ABILITY_CMD_CONTENT_RECT_CHANGED,
|
||||
ABILITY_CMD_GAINED_FOCUS,
|
||||
ABILITY_CMD_LOST_FOCUS,
|
||||
ABILITY_CMD_CONFIG_CHANGED,
|
||||
ABILITY_CMD_LOW_MEMORY,
|
||||
ABILITY_CMD_START,
|
||||
ABILITY_CMD_RESUME,
|
||||
ABILITY_CMD_SAVE_STATE,
|
||||
ABILITY_CMD_PAUSE,
|
||||
ABILITY_CMD_STOP,
|
||||
ABILITY_CMD_DESTROY,
|
||||
};
|
||||
} // namespace ohos
|
||||
} // namespace cc
|
||||
125
cocos/platform/ohos/jni/JniCocosAbility.cpp
Normal file
125
cocos/platform/ohos/jni/JniCocosAbility.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "platform/ohos/jni/JniCocosAbility.h"
|
||||
#include <fcntl.h>
|
||||
#include <hilog/log.h>
|
||||
#include <jni.h>
|
||||
#include <native_layer.h>
|
||||
#include <native_layer_jni.h>
|
||||
#include <netdb.h>
|
||||
#include <platform/FileUtils.h>
|
||||
#include <unistd.h>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include "base/Log.h"
|
||||
|
||||
#include "platform/java/jni/JniHelper.h"
|
||||
#include "platform/java/jni/glue/JniNativeGlue.h"
|
||||
#include "platform/ohos/FileUtils-ohos.h"
|
||||
#include "platform/ohos/jni/AbilityConsts.h"
|
||||
|
||||
#define LOGV(...) HILOG_INFO(LOG_APP, __VA_ARGS__)
|
||||
//NOLINTNEXTLINE
|
||||
using namespace cc::ohos;
|
||||
|
||||
extern "C" {
|
||||
//NOLINTNEXTLINE JNI function name
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onCreateNative(JNIEnv *env, jobject obj, jobject ability,
|
||||
jstring moduleNameJ, jstring assetPath, jobject resourceManager,
|
||||
jint sdkVersion) {
|
||||
if (JNI_NATIVE_GLUE()->isRunning()) {
|
||||
return;
|
||||
}
|
||||
cc::JniHelper::init(env, ability);
|
||||
JNI_NATIVE_GLUE()->setSdkVersion(sdkVersion);
|
||||
|
||||
ResourceManager *objResourceManager = InitNativeResourceManager(env, resourceManager);
|
||||
JNI_NATIVE_GLUE()->setResourceManager(objResourceManager);
|
||||
|
||||
jboolean isCopy = false;
|
||||
ccstd::string assetPathClone;
|
||||
const char *assetPathStr = env->GetStringUTFChars(assetPath, &isCopy);
|
||||
assetPathClone = assetPathStr;
|
||||
if (isCopy) {
|
||||
env->ReleaseStringUTFChars(assetPath, assetPathStr);
|
||||
assetPathStr = nullptr;
|
||||
}
|
||||
ccstd::string moduleName{"entry"};
|
||||
const char *moduleNameStr = env->GetStringUTFChars(moduleNameJ, &isCopy);
|
||||
moduleName = moduleNameStr;
|
||||
if (isCopy) {
|
||||
env->ReleaseStringUTFChars(moduleNameJ, moduleNameStr);
|
||||
moduleNameStr = nullptr;
|
||||
}
|
||||
cc::FileUtilsOHOS::initResourceManager(objResourceManager, assetPathClone, moduleName);
|
||||
JNI_NATIVE_GLUE()->start(0, nullptr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_cocos_lib_CocosAbilitySlice_onSurfaceCreatedNative(JNIEnv *env, jobject obj, jobject surface) { //NOLINT JNI function name
|
||||
// termAndSetPendingWindow(GetNativeLayer(env, surface));
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_cocos_lib_CocosAbilitySlice_onSurfaceChangedNative(JNIEnv *env, jobject obj, jobject surface, jint width, //NOLINT JNI function name
|
||||
jint height) { //NOLINT JNI function name
|
||||
JNI_NATIVE_GLUE()->setWindowHandle(GetNativeLayer(env, surface));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onSurfaceDestroyNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
JNI_NATIVE_GLUE()->setWindowHandle(nullptr);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onStartNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onPauseNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
JNI_NATIVE_GLUE()->onPause();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onResumeNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
JNI_NATIVE_GLUE()->onResume();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onStopNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onLowMemoryNative(JNIEnv *env, jobject obj) { //NOLINT JNI function name
|
||||
JNI_NATIVE_GLUE()->onLowMemory();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_cocos_lib_CocosAbilitySlice_onWindowFocusChangedNative(JNIEnv *env, jobject obj, jboolean has_focus) { //NOLINT JNI function name
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_cocos_lib_CocosAbilitySlice_setRawfilePrefix(JNIEnv *env, jobject obj, jstring prefixJ) { //NOLINT JNI function name
|
||||
jboolean isCopy = false;
|
||||
const char *prefix = env->GetStringUTFChars(prefixJ, &isCopy);
|
||||
cc::FileUtilsOHOS::setRawfilePrefix(prefix);
|
||||
if (isCopy) {
|
||||
env->ReleaseStringUTFChars(prefixJ, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
cocos/platform/ohos/jni/JniCocosAbility.h
Normal file
57
cocos/platform/ohos/jni/JniCocosAbility.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <native_layer.h>
|
||||
#include <native_layer_jni.h>
|
||||
#include <rawfile/resource_manager.h>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include "base/std/container/string.h"
|
||||
|
||||
#include <future>
|
||||
|
||||
namespace cc {
|
||||
|
||||
// struct CocosApp {
|
||||
// ResourceManager *resourceManager = nullptr;
|
||||
// // NativeLayer *window = nullptr;
|
||||
// int sdkVersion = 0;
|
||||
|
||||
// std::promise<void> glThreadPromise;
|
||||
|
||||
// NativeLayer *pendingWindow = nullptr;
|
||||
// bool destroyRequested = false;
|
||||
// bool animating = true;
|
||||
// bool running = false;
|
||||
// bool surfaceInited = false;
|
||||
|
||||
// // Current state of the app's activity. May be either APP_CMD_RESUME, APP_CMD_PAUSE.
|
||||
// int activityState = 0;
|
||||
// };
|
||||
|
||||
// extern CocosApp cocosApp;
|
||||
|
||||
} // namespace cc
|
||||
46
cocos/platform/ohos/jni/JniCocosSurfaceView.cpp
Normal file
46
cocos/platform/ohos/jni/JniCocosSurfaceView.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include <jni.h>
|
||||
#include <native_layer.h>
|
||||
#include <native_layer_jni.h>
|
||||
#include "platform/BasePlatform.h"
|
||||
#include "platform/java/jni/glue/JniNativeGlue.h"
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_cocos_lib_CocosAbilitySlice_onOrientationChangedNative(JNIEnv *env, jobject obj, jint orientation, jint width, jint height) { //NOLINT JNI function name
|
||||
static jint pOrientation = 0;
|
||||
static jint pWidth = 0;
|
||||
static jint pHeight = 0;
|
||||
if (pOrientation != orientation || pWidth != width || pHeight != height) {
|
||||
cc::WindowEvent ev;
|
||||
ev.type = cc::WindowEvent::Type::SIZE_CHANGED;
|
||||
ev.width = width;
|
||||
ev.height = height;
|
||||
//JNI_NATIVE_GLUE()->dispatchEvent(ev);
|
||||
cc::events::WindowEvent::broadcast(ev);
|
||||
pOrientation = orientation;
|
||||
pHeight = height;
|
||||
pWidth = width;
|
||||
}
|
||||
}
|
||||
13
cocos/platform/ohos/libcocos/build.gradle
Normal file
13
cocos/platform/ohos/libcocos/build.gradle
Normal file
@@ -0,0 +1,13 @@
|
||||
apply plugin: 'com.huawei.ohos.library'
|
||||
ohos {
|
||||
compileSdkVersion 5
|
||||
defaultConfig {
|
||||
compatibleSdkVersion 5
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/// implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation("com.squareup.okhttp3:okhttp:3.12.13")
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
BIN
cocos/platform/ohos/libcocos/libs/okhttp-3.12.7.jar
Normal file
BIN
cocos/platform/ohos/libcocos/libs/okhttp-3.12.7.jar
Normal file
Binary file not shown.
BIN
cocos/platform/ohos/libcocos/libs/okio-1.15.0.jar
Normal file
BIN
cocos/platform/ohos/libcocos/libs/okio-1.15.0.jar
Normal file
Binary file not shown.
24
cocos/platform/ohos/libcocos/proguard-project.txt
Normal file
24
cocos/platform/ohos/libcocos/proguard-project.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
# Proguard engine for release
|
||||
-keep public class com.cocos.** { *; }
|
||||
-dontwarn com.cocos.**
|
||||
|
||||
# Proguard okhttp for release
|
||||
-keep class okhttp3.** { *; }
|
||||
-dontwarn okhttp3.**
|
||||
|
||||
-keep class okio.** { *; }
|
||||
-dontwarn okio.**
|
||||
|
||||
29
cocos/platform/ohos/libcocos/src/main/config.json
Normal file
29
cocos/platform/ohos/libcocos/src/main/config.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"app": {
|
||||
"bundleName": "com.cocos.libcocos",
|
||||
"vendor": "cocos",
|
||||
"version": {
|
||||
"code": 1000000,
|
||||
"name": "1.0"
|
||||
}
|
||||
},
|
||||
"deviceConfig": {
|
||||
"default": {
|
||||
"network": {
|
||||
"cleartextTraffic": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"package": "com.cocos.lib",
|
||||
"deviceType": [
|
||||
"phone",
|
||||
"car"
|
||||
],
|
||||
"distro": {
|
||||
"deliveryWithInstall": true,
|
||||
"moduleName": "libcocos",
|
||||
"moduleType": "har"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,480 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||
*
|
||||
* http://www.cocos.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.agp.render.Canvas;
|
||||
import ohos.agp.render.Paint;
|
||||
import ohos.agp.render.Path;
|
||||
import ohos.agp.render.Texture;
|
||||
import ohos.agp.text.Font;
|
||||
import ohos.agp.utils.Color;
|
||||
import ohos.app.Context;
|
||||
import ohos.global.resource.RawFileEntry;
|
||||
import ohos.global.resource.Resource;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.media.image.PixelMap;
|
||||
import ohos.media.image.common.AlphaType;
|
||||
import ohos.media.image.common.PixelFormat;
|
||||
import ohos.media.image.common.Rect;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CanvasRenderingContext2DImpl {
|
||||
|
||||
public static final String TAG = "CanvasContext2D";
|
||||
public static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, TAG);
|
||||
|
||||
public static final int TEXT_ALIGN_LEFT = 0;
|
||||
public static final int TEXT_ALIGN_CENTER = 1;
|
||||
public static final int TEXT_ALIGN_RIGHT = 2;
|
||||
|
||||
public static final int TEXT_BASELINE_TOP = 0;
|
||||
public static final int TEXT_BASELINE_MIDDLE = 1;
|
||||
public static final int TEXT_BASELINE_BOTTOM = 2;
|
||||
public static final int TEXT_BASELINE_ALPHABETIC = 3;
|
||||
|
||||
public static WeakReference<Context> sContext;
|
||||
public Paint mTextPaint;
|
||||
public Paint mLinePaint;
|
||||
public Path mLinePath;
|
||||
public Canvas mCanvas = new Canvas();
|
||||
public Texture mTexture;
|
||||
public int mTextAlign = TEXT_ALIGN_LEFT;
|
||||
public int mTextBaseline = TEXT_BASELINE_BOTTOM;
|
||||
public int mFillStyleR = 0;
|
||||
public int mFillStyleG = 0;
|
||||
public int mFillStyleB = 0;
|
||||
public int mFillStyleA = 255;
|
||||
|
||||
public int mStrokeStyleR = 0;
|
||||
public int mStrokeStyleG = 0;
|
||||
public int mStrokeStyleB = 0;
|
||||
public int mStrokeStyleA = 255;
|
||||
|
||||
public String mFontName = "Arial";
|
||||
public float mFontSize = 40.0f;
|
||||
public float mLineWidth = 0.0f;
|
||||
public static float _sApproximatingOblique = -0.25f;//please check paint api documentation
|
||||
public boolean mIsBoldFont = false;
|
||||
public boolean mIsItalicFont = false;
|
||||
public boolean mIsObliqueFont = false;
|
||||
public boolean mIsSmallCapsFontVariant = false;
|
||||
public String mLineCap = "butt";
|
||||
public String mLineJoin = "miter";
|
||||
private PixelMap mPixelMap;
|
||||
|
||||
|
||||
public class Point {
|
||||
Point(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Point(Point pt) {
|
||||
this.x = pt.x;
|
||||
this.y = pt.y;
|
||||
}
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
}
|
||||
|
||||
static void init(Context context) {
|
||||
sContext = new WeakReference<>(context);
|
||||
}
|
||||
|
||||
static void destroy() {
|
||||
sContext = null;
|
||||
}
|
||||
|
||||
public static HashMap<String, Font.Builder> sTypefaceCache = new HashMap<>();
|
||||
|
||||
// url is a full path started with '@assets/'
|
||||
public static void loadTypeface(String familyName, String url) {
|
||||
Context ctx = sContext.get();
|
||||
File fontTmpFile = null;
|
||||
if (!sTypefaceCache.containsKey(familyName)) {
|
||||
try {
|
||||
Font.Builder typeface = null;
|
||||
if (url.startsWith("/")) {
|
||||
/// No error reported here, but font render incorrect.
|
||||
// typeface = new Font.Builder(url);
|
||||
/// TODO: Opt.
|
||||
/// After copying to temporary location, we can load font successfully.
|
||||
/// I don't know why.
|
||||
fontTmpFile = CocosHelper.copyToTempFile(url, "fontFile");
|
||||
typeface = new Font.Builder(fontTmpFile);
|
||||
} else if (ctx != null) {
|
||||
final String prefix = "@assets/";
|
||||
if (url.startsWith(prefix)) {
|
||||
url = url.substring(prefix.length());
|
||||
}
|
||||
// TODO: 是否可以直接通过 rawfile 创建 font?
|
||||
fontTmpFile = CocosHelper.copyOutResFile(ctx, url, "fontFile");
|
||||
typeface = new Font.Builder(fontTmpFile);
|
||||
}
|
||||
|
||||
if (typeface != null) {
|
||||
sTypefaceCache.put(familyName, typeface);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// REFINE:: native should clear font cache before exiting game.
|
||||
public static void clearTypefaceCache() {
|
||||
sTypefaceCache.clear();
|
||||
}
|
||||
|
||||
public static Paint newPaint(String fontName, int fontSize, boolean enableBold, boolean enableItalic, boolean obliqueFont, boolean smallCapsFontVariant) {
|
||||
Paint paint = new Paint();
|
||||
paint.setTextSize(fontSize);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setSubpixelAntiAlias(true);
|
||||
|
||||
String key = fontName;
|
||||
if (enableBold) {
|
||||
key += "-Bold";
|
||||
paint.setFakeBoldText(true);
|
||||
}
|
||||
if (enableItalic) {
|
||||
key += "-Italic";
|
||||
}
|
||||
|
||||
Font.Builder typeFace;
|
||||
if (sTypefaceCache.containsKey(key)) {
|
||||
typeFace = sTypefaceCache.get(key);
|
||||
} else {
|
||||
typeFace = new Font.Builder(fontName);
|
||||
int style = Font.REGULAR;
|
||||
typeFace.makeItalic(enableItalic);
|
||||
typeFace.setWeight(enableBold ? Font.BOLD : Font.REGULAR);
|
||||
}
|
||||
paint.setFont(typeFace.build());
|
||||
|
||||
if (obliqueFont) {
|
||||
// TODO: skewX 缺少接口
|
||||
// paint.setTextSkewX(_sApproximatingOblique);
|
||||
}
|
||||
return paint;
|
||||
}
|
||||
|
||||
public CanvasRenderingContext2DImpl() {
|
||||
// Log.d(TAG, "constructor");
|
||||
}
|
||||
|
||||
public void recreateBuffer(float w, float h) {
|
||||
// Log.d(TAG, "recreateBuffer:" + w + ", " + h);
|
||||
PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
|
||||
initializationOptions.alphaType = AlphaType.UNPREMUL;
|
||||
initializationOptions.pixelFormat = PixelFormat.ARGB_8888;
|
||||
initializationOptions.editable = true; // allow writePixels
|
||||
initializationOptions.size = new ohos.media.image.common.Size((int) Math.ceil(w), (int) Math.ceil(h));
|
||||
|
||||
mPixelMap = PixelMap.create(initializationOptions);
|
||||
mTexture = new Texture(mPixelMap);
|
||||
// NOTE: PixelMap.resetConfig does not change pixel data or nor reallocate memory for pixel data
|
||||
|
||||
mCanvas.setTexture(mTexture);
|
||||
}
|
||||
|
||||
public void beginPath() {
|
||||
if (mLinePath == null) {
|
||||
mLinePath = new Path();
|
||||
}
|
||||
mLinePath.reset();
|
||||
}
|
||||
|
||||
public void closePath() {
|
||||
mLinePath.close();
|
||||
}
|
||||
|
||||
public void moveTo(float x, float y) {
|
||||
mLinePath.moveTo(x, y);
|
||||
}
|
||||
|
||||
public void lineTo(float x, float y) {
|
||||
mLinePath.lineTo(x, y);
|
||||
}
|
||||
|
||||
public void stroke() {
|
||||
if (mLinePaint == null) {
|
||||
mLinePaint = new Paint();
|
||||
mLinePaint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
if (mLinePath == null) {
|
||||
mLinePath = new Path();
|
||||
}
|
||||
|
||||
Color strokeColor = new Color(Color.argb(mStrokeStyleA, mStrokeStyleR, mStrokeStyleG, mStrokeStyleB));
|
||||
mLinePaint.setColor(strokeColor);
|
||||
mLinePaint.setStyle(Paint.Style.STROKE_STYLE);
|
||||
mLinePaint.setStrokeWidth(mLineWidth);
|
||||
this.setStrokeCap(mLinePaint);
|
||||
this.setStrokeJoin(mLinePaint);
|
||||
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||
}
|
||||
|
||||
public void setStrokeCap(Paint paint) {
|
||||
switch (mLineCap) {
|
||||
case "butt":
|
||||
paint.setStrokeCap(Paint.StrokeCap.BUTT_CAP);
|
||||
break;
|
||||
case "round":
|
||||
paint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
|
||||
break;
|
||||
case "square":
|
||||
paint.setStrokeCap(Paint.StrokeCap.SQUARE_CAP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setStrokeJoin(Paint paint) {
|
||||
switch (mLineJoin) {
|
||||
case "bevel":
|
||||
paint.setStrokeJoin(Paint.Join.BEVEL_JOIN);
|
||||
break;
|
||||
case "round":
|
||||
paint.setStrokeJoin(Paint.Join.ROUND_JOIN);
|
||||
break;
|
||||
case "miter":
|
||||
paint.setStrokeJoin(Paint.Join.MITER_JOIN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void fill() {
|
||||
if (mLinePaint == null) {
|
||||
mLinePaint = new Paint();
|
||||
}
|
||||
|
||||
if (mLinePath == null) {
|
||||
mLinePath = new Path();
|
||||
}
|
||||
|
||||
Color fillColor = new Color(Color.argb(mFillStyleA, mFillStyleR, mFillStyleG, mFillStyleB));
|
||||
mLinePaint.setColor(fillColor);
|
||||
mLinePaint.setStyle(Paint.Style.FILL_STYLE);
|
||||
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||
// workaround: draw a hairline to cover the border
|
||||
mLinePaint.setStrokeWidth(0);
|
||||
this.setStrokeCap(mLinePaint);
|
||||
this.setStrokeJoin(mLinePaint);
|
||||
mLinePaint.setStyle(Paint.Style.STROKE_STYLE);
|
||||
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||
mLinePaint.setStrokeWidth(mLineWidth);
|
||||
}
|
||||
|
||||
public void setLineCap(String lineCap) {
|
||||
mLineCap = lineCap;
|
||||
}
|
||||
|
||||
public void setLineJoin(String lineJoin) {
|
||||
mLineJoin = lineJoin;
|
||||
}
|
||||
|
||||
public void saveContext() {
|
||||
mCanvas.save();
|
||||
}
|
||||
|
||||
public void restoreContext() {
|
||||
// If there is no saved state, this method should do nothing.
|
||||
if (mCanvas.getSaveCount() > 1) {
|
||||
mCanvas.restore();
|
||||
}
|
||||
}
|
||||
|
||||
public void rect(float x, float y, float w, float h) {
|
||||
beginPath();
|
||||
moveTo(x, y);
|
||||
lineTo(x, y + h);
|
||||
lineTo(x + w, y + h);
|
||||
lineTo(x + w, y);
|
||||
closePath();
|
||||
}
|
||||
|
||||
public void clearRect(float x, float y, float w, float h) {
|
||||
// mTexture.getPixelMap().writePixels(Color.TRANSPARENT.getValue());
|
||||
PixelMap pm = mTexture.getPixelMap();
|
||||
if (pm.isReleased() || !pm.isEditable()) {
|
||||
return;
|
||||
}
|
||||
Rect region = new Rect((int) x, (int) y, (int) w, (int) h);
|
||||
int fillSize = (int) (w * h);
|
||||
IntBuffer buffer = IntBuffer.allocate(fillSize);
|
||||
for (int i = 0; i < fillSize; i++) {
|
||||
buffer.put(Color.TRANSPARENT.getValue());
|
||||
}
|
||||
pm.writePixels(buffer.array(), 0, (int) w, region);
|
||||
}
|
||||
|
||||
public void createTextPaintIfNeeded() {
|
||||
if (mTextPaint == null) {
|
||||
mTextPaint = newPaint(mFontName, (int) mFontSize, mIsBoldFont, mIsItalicFont, mIsObliqueFont, mIsSmallCapsFontVariant);
|
||||
}
|
||||
}
|
||||
|
||||
public void fillRect(float x, float y, float w, float h) {
|
||||
PixelMap pm = mTexture.getPixelMap();
|
||||
if (pm.isReleased() || !pm.isEditable()) {
|
||||
return;
|
||||
}
|
||||
// Log.d(TAG, "fillRect: " + x + ", " + y + ", " + ", " + w + ", " + h);
|
||||
int pixelValue = (mFillStyleA & 0xff) << 24 | (mFillStyleR & 0xff) << 16 | (mFillStyleG & 0xff) << 8 | (mFillStyleB & 0xff);
|
||||
int fillSize = (int) (w * h);
|
||||
int[] buffer = new int[fillSize];
|
||||
IntBuffer fillColors = IntBuffer.wrap(buffer);
|
||||
for (int i = 0; i < fillSize; ++i) {
|
||||
buffer[i] = pixelValue;
|
||||
}
|
||||
Rect region = new Rect((int) x, (int) y, (int) w, (int) h);
|
||||
pm.writePixels(buffer, 0, (int) w, region);
|
||||
}
|
||||
|
||||
public void scaleX(Paint textPaint, String text, float maxWidth) {
|
||||
if (maxWidth < Float.MIN_VALUE) return;
|
||||
float measureWidth = this.measureText(text);
|
||||
if ((measureWidth - maxWidth) < Float.MIN_VALUE) return;
|
||||
float scaleX = maxWidth / measureWidth;
|
||||
// TODO: font scale
|
||||
// textPaint.setTextScaleX(scaleX);
|
||||
}
|
||||
|
||||
public void fillText(String text, float x, float y, float maxWidth) {
|
||||
createTextPaintIfNeeded();
|
||||
Color fillColor = new Color(Color.argb(mFillStyleA, mFillStyleR, mFillStyleG, mFillStyleB));
|
||||
mTextPaint.setColor(fillColor);
|
||||
mTextPaint.setStyle(Paint.Style.FILL_STYLE);
|
||||
scaleX(mTextPaint, text, maxWidth);
|
||||
Point pt = convertDrawPoint(new Point(x, y), text);
|
||||
mCanvas.drawText(mTextPaint, text, pt.x, pt.y);
|
||||
}
|
||||
|
||||
public void strokeText(String text, float x, float y, float maxWidth) {
|
||||
createTextPaintIfNeeded();
|
||||
Color strokeColor = new Color(Color.argb(mStrokeStyleA, mStrokeStyleR, mStrokeStyleG, mStrokeStyleB));
|
||||
mTextPaint.setColor(strokeColor);
|
||||
mTextPaint.setStyle(Paint.Style.STROKE_STYLE);
|
||||
mTextPaint.setStrokeWidth(mLineWidth);
|
||||
scaleX(mTextPaint, text, maxWidth);
|
||||
Point pt = convertDrawPoint(new Point(x, y), text);
|
||||
mCanvas.drawText(mTextPaint, text, pt.x, pt.y);
|
||||
}
|
||||
|
||||
public float measureText(String text) {
|
||||
createTextPaintIfNeeded();
|
||||
return mTextPaint.measureText(text);
|
||||
}
|
||||
|
||||
public void updateFont(String fontName, float fontSize, boolean bold, boolean italic, boolean oblique, boolean smallCaps) {
|
||||
mFontName = fontName;
|
||||
mFontSize = fontSize;
|
||||
mIsBoldFont = bold;
|
||||
mIsItalicFont = italic;
|
||||
mIsObliqueFont = oblique;
|
||||
mIsSmallCapsFontVariant = smallCaps;
|
||||
mTextPaint = null; // Reset paint to re-create paint object in createTextPaintIfNeeded
|
||||
}
|
||||
|
||||
public void setTextAlign(int align) {
|
||||
mTextAlign = align;
|
||||
}
|
||||
|
||||
public void setTextBaseline(int baseline) {
|
||||
mTextBaseline = baseline;
|
||||
}
|
||||
|
||||
public void setFillStyle(int r, int g, int b, int a) {
|
||||
mFillStyleR = r;
|
||||
mFillStyleG = g;
|
||||
mFillStyleB = b;
|
||||
mFillStyleA = a;
|
||||
}
|
||||
|
||||
public void setStrokeStyle(int r, int g, int b, int a) {
|
||||
mStrokeStyleR = r;
|
||||
mStrokeStyleG = g;
|
||||
mStrokeStyleB = b;
|
||||
mStrokeStyleA = a;
|
||||
}
|
||||
|
||||
public void setLineWidth(float lineWidth) {
|
||||
mLineWidth = lineWidth;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void _fillImageData(int[] imageData, float imageWidth, float imageHeight, float offsetX, float offsetY) {
|
||||
int fillSize = (int) (imageWidth * imageHeight);
|
||||
int[] fillColors = new int[fillSize];
|
||||
for (int i = 0; i < fillSize; ++i) {
|
||||
// r g b a -> a r g b
|
||||
fillColors[i] = Integer.rotateRight(imageData[i], 8);
|
||||
}
|
||||
Rect dstRect = new Rect((int) offsetX, (int) offsetY, (int) imageWidth, (int) imageHeight);
|
||||
mTexture.getPixelMap().writePixels(fillColors, 0, (int) imageWidth, dstRect);
|
||||
}
|
||||
|
||||
public Point convertDrawPoint(final Point point, String text) {
|
||||
// The parameter 'point' is located at left-bottom position.
|
||||
// Need to adjust 'point' according 'text align' & 'text base line'.
|
||||
Point ret = new Point(point);
|
||||
createTextPaintIfNeeded();
|
||||
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
|
||||
float width = measureText(text);
|
||||
|
||||
if (mTextAlign == TEXT_ALIGN_CENTER) {
|
||||
ret.x -= width / 2;
|
||||
} else if (mTextAlign == TEXT_ALIGN_RIGHT) {
|
||||
ret.x -= width;
|
||||
}
|
||||
|
||||
// Canvas.drawText accepts the y parameter as the baseline position, not the most bottom
|
||||
if (mTextBaseline == TEXT_BASELINE_TOP) {
|
||||
ret.y += -fm.ascent;
|
||||
} else if (mTextBaseline == TEXT_BASELINE_MIDDLE) {
|
||||
ret.y += (fm.descent - fm.ascent) / 2 - fm.descent;
|
||||
} else if (mTextBaseline == TEXT_BASELINE_BOTTOM) {
|
||||
ret.y += -fm.descent;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private PixelMap getBitmap() {
|
||||
return mPixelMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||
*
|
||||
* http://www.cocos.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
import ohos.aafwk.content.Intent;
|
||||
import ohos.agp.components.Component;
|
||||
import ohos.agp.components.StackLayout;
|
||||
import ohos.agp.components.surfaceprovider.SurfaceProvider;
|
||||
import ohos.agp.graphics.Surface;
|
||||
import ohos.agp.graphics.SurfaceOps;
|
||||
import ohos.agp.window.service.WindowManager;
|
||||
import ohos.bundle.AbilityInfo;
|
||||
import ohos.global.resource.ResourceManager;
|
||||
import ohos.multimodalinput.event.KeyEvent;
|
||||
import ohos.multimodalinput.event.TouchEvent;
|
||||
import ohos.system.version.SystemVersion;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CocosAbilitySlice extends AbilitySlice implements SurfaceOps.Callback, Component.TouchEventListener , Component.KeyEventListener, Component.FocusChangedListener {
|
||||
private boolean mDestroyed;
|
||||
private StackLayout mRootLayout;
|
||||
private SurfaceProvider mSurfaceProvider;
|
||||
private Optional<Surface> mSurface = Optional.empty();
|
||||
private CocosTouchHandler mTouchHandler;
|
||||
private CocosWebViewHelper mWebViewHelper = null;
|
||||
private CocosVideoHelper mVideoHelper = null;
|
||||
private CocosOrientationHelper mOrientationHelper = null;
|
||||
|
||||
private boolean engineInit = false;
|
||||
|
||||
private CocosKeyCodeHandler mKeyCodeHandler;
|
||||
private CocosSensorHandler mSensorHandler;
|
||||
|
||||
|
||||
private native void onCreateNative(AbilitySlice activity, String moduleName, String assetPath, ResourceManager resourceManager, int sdkVersion);
|
||||
|
||||
private native void onSurfaceCreatedNative(Surface surface);
|
||||
|
||||
private native void onSurfaceChangedNative(Surface surface, int width, int height);
|
||||
|
||||
private native void onSurfaceDestroyNative();
|
||||
|
||||
private native void onPauseNative();
|
||||
|
||||
private native void onResumeNative();
|
||||
|
||||
private native void onStopNative();
|
||||
|
||||
private native void onStartNative();
|
||||
|
||||
private native void onLowMemoryNative();
|
||||
|
||||
private native void onOrientationChangedNative(int orientation, int width, int height);
|
||||
|
||||
private native void onWindowFocusChangedNative(boolean hasFocus);
|
||||
|
||||
private native void setRawfilePrefix(String prefix);
|
||||
|
||||
@Override
|
||||
protected void onStart(Intent savedInstanceState) {
|
||||
super.onStart(savedInstanceState);
|
||||
GlobalObject.setAbilitySlice(this);
|
||||
CocosHelper.registerBatteryLevelReceiver(this);
|
||||
CocosHelper.init(this);
|
||||
CanvasRenderingContext2DImpl.init(this);
|
||||
onLoadNativeLibraries();
|
||||
|
||||
getWindow().setTransparent(true); // required for surface provider
|
||||
|
||||
this.getWindow().addFlags(WindowManager.LayoutConfig.MARK_ALLOW_EXTEND_LAYOUT);
|
||||
this.getWindow().addFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN);
|
||||
|
||||
// getContext().setDisplayOrientation(AbilityInfo.DisplayOrientation.UNSPECIFIED);
|
||||
// getWindow().addFlags(WindowManager.LayoutConfig.INPUT_ADJUST_PAN);
|
||||
// getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
|
||||
|
||||
initView();
|
||||
|
||||
onCreateNative(this, getHapModuleInfo().getModuleName(), getAssetPath(), getResourceManager(), SystemVersion.getApiVersion());
|
||||
|
||||
mKeyCodeHandler = new CocosKeyCodeHandler(this);
|
||||
mSensorHandler = new CocosSensorHandler();
|
||||
|
||||
mTouchHandler = new CocosTouchHandler();
|
||||
|
||||
mOrientationHelper = new CocosOrientationHelper(this);
|
||||
|
||||
Thread.currentThread().setName("Cocos-UI");
|
||||
CocosHelper.runOnGameThread(()->{
|
||||
Thread.currentThread().setName("Cocos-JS");
|
||||
});
|
||||
}
|
||||
private String getAssetPath() {
|
||||
return getApplicationContext().getFilesDir().getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) {
|
||||
super.onOrientationChanged(displayOrientation);
|
||||
// CocosHelper.runOnGameThread(() ->
|
||||
// onOrientationChangedNative(displayOrientation.ordinal(), mSurfaceProvider.getWidth(), mSurfaceProvider.getHeight())
|
||||
// );
|
||||
}
|
||||
|
||||
private static String getAbsolutePath(File file) {
|
||||
return (file != null) ? file.getAbsolutePath() : null;
|
||||
}
|
||||
|
||||
protected void initView() {
|
||||
// gles view
|
||||
StackLayout.LayoutConfig config = new StackLayout.LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, StackLayout.LayoutConfig.MATCH_PARENT);
|
||||
|
||||
mSurfaceProvider = new SurfaceProvider(getContext());
|
||||
mSurfaceProvider.getSurfaceOps().get().addCallback(this);
|
||||
mSurfaceProvider.pinToZTop(false);
|
||||
|
||||
mRootLayout = new StackLayout(getContext());
|
||||
mRootLayout.setLayoutConfig(config);
|
||||
|
||||
StackLayout.LayoutConfig layoutConfigSurfaceProvider = new StackLayout.LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, StackLayout.LayoutConfig.MATCH_PARENT);
|
||||
|
||||
mRootLayout.addComponent(mSurfaceProvider, layoutConfigSurfaceProvider);
|
||||
mSurfaceProvider.setKeyEventListener(this);
|
||||
mSurfaceProvider.setFocusable(Component.FOCUS_ENABLE);
|
||||
mSurfaceProvider.setTouchFocusable(true);
|
||||
mSurfaceProvider.setFocusChangedListener(this);
|
||||
mSurfaceProvider.setTouchEventListener(this);
|
||||
mSurfaceProvider.setLayoutRefreshedListener(component -> {
|
||||
// dispatch resize event
|
||||
CocosHelper.runOnGameThreadAtForeground(()->{
|
||||
onOrientationChangedNative(getDisplayOrientation(), component.getWidth(), component.getHeight());
|
||||
});
|
||||
});
|
||||
mSurfaceProvider.requestFocus();
|
||||
|
||||
if (mWebViewHelper == null) {
|
||||
mWebViewHelper = new CocosWebViewHelper(mRootLayout);
|
||||
}
|
||||
|
||||
if (mVideoHelper == null) {
|
||||
mVideoHelper = new CocosVideoHelper(this, mRootLayout);
|
||||
}
|
||||
|
||||
setUIContent(mRootLayout);
|
||||
}
|
||||
|
||||
public SurfaceProvider getSurfaceView() {
|
||||
return this.mSurfaceProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
mDestroyed = true;
|
||||
if (mSurfaceProvider != null) {
|
||||
onSurfaceDestroyNative();
|
||||
mSurfaceProvider = null;
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInactive() {
|
||||
super.onInactive();
|
||||
mSensorHandler.onPause();
|
||||
mOrientationHelper.onPause();
|
||||
onPauseNative();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActive() {
|
||||
super.onActive();
|
||||
onStartNative();
|
||||
mSensorHandler.onResume();
|
||||
mOrientationHelper.onResume();
|
||||
onResumeNative();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBackground() {
|
||||
super.onBackground();
|
||||
onStopNative();
|
||||
}
|
||||
|
||||
// TODO: low memory listener
|
||||
// @Override
|
||||
// public void onLowMemory() {
|
||||
// super.onLowMemory();
|
||||
// if (!mDestroyed) {
|
||||
// onLowMemoryNative();
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onFocusChange(Component component, boolean b) {
|
||||
//NOTICE: may not be equivalent to onWindowFocusChanged on Android
|
||||
if (!mDestroyed) {
|
||||
onWindowFocusChangedNative(b);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceOps holder) {
|
||||
if (!mDestroyed) {
|
||||
mSurface = Optional.of(holder.getSurface());
|
||||
onSurfaceCreatedNative(holder.getSurface());
|
||||
engineInit = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceOps surfaceOps, int format, int width, int height) {
|
||||
if (!mDestroyed) {
|
||||
mSurface = Optional.of(surfaceOps.getSurface());
|
||||
onSurfaceChangedNative(surfaceOps.getSurface(), width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceOps surfaceOps) {
|
||||
mRootLayout = null;
|
||||
if (!mDestroyed) {
|
||||
onSurfaceDestroyNative();
|
||||
engineInit = false;
|
||||
}
|
||||
mSurface = Optional.empty();
|
||||
}
|
||||
|
||||
private void onLoadNativeLibraries() {
|
||||
try {
|
||||
//TODO: Read library name from configuration
|
||||
System.loadLibrary("cocos");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return mKeyCodeHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
return mKeyCodeHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
|
||||
return mTouchHandler.onTouchEvent(touchEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyEvent(Component component, KeyEvent keyEvent) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import okhttp3.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CocosDownloader {
|
||||
|
||||
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "CocosDownloader");
|
||||
|
||||
private int _id;
|
||||
private OkHttpClient _httpClient = null;
|
||||
|
||||
private String _tempFileNameSuffix;
|
||||
private int _countOfMaxProcessingTasks;
|
||||
private final ConcurrentHashMap<Integer, Call> _taskMap = new ConcurrentHashMap<>();
|
||||
private final Queue<Runnable> _taskQueue = new LinkedList<>();
|
||||
private int _runningTaskCount = 0;
|
||||
private static final ConcurrentHashMap<String, Boolean> _resumingSupport = new ConcurrentHashMap<>();
|
||||
|
||||
private void onProgress(final int id, final long downloadBytes, final long downloadNow, final long downloadTotal) {
|
||||
CocosHelper.runOnGameThread(() ->
|
||||
nativeOnProgress(_id, id, downloadBytes, downloadNow, downloadTotal)
|
||||
);
|
||||
}
|
||||
|
||||
private void onFinish(final int id, final int errCode, final String errStr, final byte[] data) {
|
||||
Call task =_taskMap.get(id);
|
||||
if (null == task) return;
|
||||
_taskMap.remove(id);
|
||||
_runningTaskCount -= 1;
|
||||
CocosHelper.runOnGameThread(() ->
|
||||
nativeOnFinish(_id, id, errCode, errStr, data)
|
||||
);
|
||||
runNextTaskIfExists();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static CocosDownloader createDownloader(int id, int timeoutInSeconds, String tempFileSuffix, int maxProcessingTasks) {
|
||||
CocosDownloader downloader = new CocosDownloader();
|
||||
downloader._id = id;
|
||||
|
||||
if (timeoutInSeconds > 0) {
|
||||
downloader._httpClient = new OkHttpClient().newBuilder()
|
||||
.followRedirects(true)
|
||||
.followSslRedirects(true)
|
||||
.callTimeout(timeoutInSeconds, TimeUnit.SECONDS)
|
||||
.build();
|
||||
} else {
|
||||
downloader._httpClient = new OkHttpClient().newBuilder()
|
||||
.followRedirects(true)
|
||||
.followSslRedirects(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
downloader._tempFileNameSuffix = tempFileSuffix;
|
||||
downloader._countOfMaxProcessingTasks = maxProcessingTasks;
|
||||
return downloader;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void createTask(final CocosDownloader downloader, int id_, String url_, String path_, String []header_) {
|
||||
final int id = id_;
|
||||
final String url = url_;
|
||||
final String path = path_;
|
||||
final String[] header = header_;
|
||||
|
||||
Runnable taskRunnable = new Runnable() {
|
||||
String domain = null;
|
||||
String host = null;
|
||||
File tempFile = null;
|
||||
File finalFile = null;
|
||||
long downloadStart = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Call task = null;
|
||||
|
||||
do {
|
||||
if (path.length() > 0) {
|
||||
try {
|
||||
URI uri = new URI(url);
|
||||
domain = uri.getHost();
|
||||
} catch (URISyntaxException | NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
|
||||
// file task
|
||||
tempFile = new File(path + downloader._tempFileNameSuffix);
|
||||
if (tempFile.isDirectory()) break;
|
||||
|
||||
File parent = tempFile.getParentFile();
|
||||
if (!parent.isDirectory() && !parent.mkdirs()) break;
|
||||
|
||||
finalFile = new File(path);
|
||||
if (finalFile.isDirectory()) break;
|
||||
long fileLen = tempFile.length();
|
||||
|
||||
host = domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||
if (fileLen > 0) {
|
||||
if (_resumingSupport.containsKey(host) && _resumingSupport.get(host)) {
|
||||
downloadStart = fileLen;
|
||||
} else {
|
||||
// Remove previous downloaded context
|
||||
try {
|
||||
PrintWriter writer = new PrintWriter(tempFile);
|
||||
writer.print("");
|
||||
writer.close();
|
||||
}
|
||||
// Not found then nothing to do
|
||||
catch (FileNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Request.Builder builder = new Request.Builder().url(url);
|
||||
for (int i = 0; i < header.length / 2; i++) {
|
||||
builder.addHeader(header[i * 2], header[(i * 2) + 1]);
|
||||
}
|
||||
if (downloadStart > 0) {
|
||||
builder.addHeader("RANGE", "bytes=" + downloadStart + "-");
|
||||
}
|
||||
|
||||
final Request request = builder.build();
|
||||
task = downloader._httpClient.newCall(request);
|
||||
if (null == task) {
|
||||
final String errStr = "Can't create DownloadTask for " + url;
|
||||
CocosHelper.runOnGameThread(() ->
|
||||
downloader.nativeOnFinish(downloader._id, id, 0, errStr, null)
|
||||
);
|
||||
} else {
|
||||
downloader._taskMap.put(id, task);
|
||||
}
|
||||
task.enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
downloader.onFinish(id, 0, e.toString(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
InputStream is = null;
|
||||
byte[] buf = new byte[4096];
|
||||
FileOutputStream fos = null;
|
||||
|
||||
try {
|
||||
|
||||
if(!(response.code() >= 200 && response.code() <= 206)) {
|
||||
// it is encourage to delete the tmp file when requested range not satisfiable.
|
||||
if (response.code() == 416) {
|
||||
File file = new File(path + downloader._tempFileNameSuffix);
|
||||
if (file.exists() && file.isFile()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
downloader.onFinish(id, -2, response.message(), null);
|
||||
return;
|
||||
}
|
||||
|
||||
long total = response.body().contentLength();
|
||||
if (path.length() > 0 && !_resumingSupport.containsKey(host)) {
|
||||
if (total > 0) {
|
||||
_resumingSupport.put(host, true);
|
||||
} else {
|
||||
_resumingSupport.put(host, false);
|
||||
}
|
||||
}
|
||||
|
||||
long current = downloadStart;
|
||||
is = response.body().byteStream();
|
||||
|
||||
if (path.length() > 0) {
|
||||
if (downloadStart > 0) {
|
||||
fos = new FileOutputStream(tempFile, true);
|
||||
} else {
|
||||
fos = new FileOutputStream(tempFile, false);
|
||||
}
|
||||
|
||||
int len;
|
||||
while ((len = is.read(buf)) != -1) {
|
||||
current += len;
|
||||
fos.write(buf, 0, len);
|
||||
downloader.onProgress(id, len, current, total);
|
||||
}
|
||||
fos.flush();
|
||||
|
||||
String errStr = null;
|
||||
do {
|
||||
// rename temp file to final file, if final file exist, remove it
|
||||
if (finalFile.exists()) {
|
||||
if (finalFile.isDirectory()) {
|
||||
break;
|
||||
}
|
||||
if (!finalFile.delete()) {
|
||||
errStr = "Can't remove old file:" + finalFile.getAbsolutePath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
tempFile.renameTo(finalFile);
|
||||
} while (false);
|
||||
|
||||
if (errStr == null) {
|
||||
downloader.onFinish(id, 0, null, null);
|
||||
downloader.runNextTaskIfExists();
|
||||
}
|
||||
else
|
||||
downloader.onFinish(id, 0, errStr, null);
|
||||
} else {
|
||||
// 非文件
|
||||
ByteArrayOutputStream buffer;
|
||||
if(total > 0) {
|
||||
buffer = new ByteArrayOutputStream((int) total);
|
||||
} else {
|
||||
buffer = new ByteArrayOutputStream(4096);
|
||||
}
|
||||
|
||||
int len;
|
||||
while ((len = is.read(buf)) != -1) {
|
||||
current += len;
|
||||
buffer.write(buf, 0, len);
|
||||
downloader.onProgress(id, len, current, total);
|
||||
}
|
||||
downloader.onFinish(id, 0, null, buffer.toByteArray());
|
||||
downloader.runNextTaskIfExists();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
downloader.onFinish(id, 0, e.toString(), null);
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HiLog.error(LABEL, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} while (false);
|
||||
}
|
||||
};
|
||||
downloader.enqueueTask(taskRunnable);
|
||||
}
|
||||
|
||||
public static void abort(final CocosDownloader downloader, final int id) {
|
||||
CocosHelper.runOnUIThread(() -> {
|
||||
for (Map.Entry<?, Call> entry : downloader._taskMap.entrySet()) {
|
||||
Object key = entry.getKey();
|
||||
Call task = entry.getValue();
|
||||
if (null != task && Integer.parseInt(key.toString()) == id) {
|
||||
task.cancel();
|
||||
downloader._taskMap.remove(id);
|
||||
downloader.runNextTaskIfExists();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void cancelAllRequests(final CocosDownloader downloader) {
|
||||
CocosHelper.runOnUIThread(() -> {
|
||||
for (Map.Entry<?, Call> entry : downloader._taskMap.entrySet()) {
|
||||
Call task = entry.getValue();
|
||||
if (null != task) {
|
||||
task.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void enqueueTask(Runnable taskRunnable) {
|
||||
synchronized (_taskQueue) {
|
||||
if (_runningTaskCount < _countOfMaxProcessingTasks) {
|
||||
CocosHelper.runOnUIThread(taskRunnable);
|
||||
_runningTaskCount++;
|
||||
} else {
|
||||
_taskQueue.add(taskRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runNextTaskIfExists() {
|
||||
synchronized (_taskQueue) {
|
||||
while (_runningTaskCount < _countOfMaxProcessingTasks &&
|
||||
CocosDownloader.this._taskQueue.size() > 0) {
|
||||
|
||||
Runnable taskRunnable = CocosDownloader.this._taskQueue.poll();
|
||||
CocosHelper.runOnUIThread(taskRunnable);
|
||||
_runningTaskCount += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
native void nativeOnProgress(int id, int taskId, long dl, long dlnow, long dltotal);
|
||||
native void nativeOnFinish(int id, int taskId, int errCode, String errStr, final byte[] data);
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
import ohos.aafwk.content.Intent;
|
||||
import ohos.accessibility.ability.AccessibleAbility;
|
||||
import ohos.accessibility.ability.SoftKeyBoardController;
|
||||
import ohos.agp.components.*;
|
||||
import ohos.agp.utils.Color;
|
||||
import ohos.agp.utils.Rect;
|
||||
import ohos.agp.window.service.DisplayAttributes;
|
||||
import ohos.agp.window.service.DisplayManager;
|
||||
import ohos.agp.window.service.WindowManager;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.multimodalinput.event.TouchEvent;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
|
||||
public class CocosEditBoxAbility extends AbilitySlice {
|
||||
|
||||
// a color of dark green, was used for confirm button background
|
||||
private static final Color DARK_GREEN = new Color(Color.getIntColor("#1fa014"));
|
||||
private static final Color DARK_GREEN_PRESS = new Color(Color.getIntColor("#008e26"));
|
||||
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "CocosEditBoxAbility");
|
||||
|
||||
private static WeakReference<CocosEditBoxAbility> sThis = null;
|
||||
private CocosTextHelper mTextFieldHelper = null;
|
||||
private Button mButton = null;
|
||||
private String mButtonTitle = null;
|
||||
private boolean mConfirmHold = true;
|
||||
private boolean mIsMultiLine;
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
Inner class.
|
||||
**************************************************************************************/
|
||||
class CocosTextHelper {
|
||||
private final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0, "Cocos2dxEditBox");
|
||||
private Text.TextObserver mTextWatcher = null;
|
||||
private TextField mTextFieldLocal;
|
||||
private int mVisibleHeight = 0;
|
||||
private ComponentContainer mLayout;
|
||||
|
||||
public CocosTextHelper(TextField tf) {
|
||||
mTextFieldLocal = tf;
|
||||
DisplayAttributes displayAttrib = DisplayManager.getInstance().getDefaultDisplay(tf.getContext()).get().getRealAttributes();
|
||||
|
||||
mTextWatcher = new Text.TextObserver() {
|
||||
@Override
|
||||
public void onTextUpdated(String s, int i, int i1, int i2) {
|
||||
CocosEditBoxAbility.this.onKeyboardInput(s);
|
||||
}
|
||||
};
|
||||
tf.setAdjustInputPanel(true);
|
||||
|
||||
mTextFieldHelper = this;
|
||||
|
||||
mLayout = (ComponentContainer) findComponentById(ResourceTable.Id_editbox_container);
|
||||
mLayout.setLayoutRefreshedListener(new Component.LayoutRefreshedListener() {
|
||||
@Override
|
||||
public void onRefreshed(Component component) {
|
||||
HiLog.debug(LABEL, "onRefreshed");
|
||||
Rect rect = new Rect();
|
||||
boolean result = mTextFieldLocal.getWindowVisibleRect(rect);
|
||||
if (!result) {
|
||||
HiLog.debug(LABEL, "getWindowVisibleRect fail");
|
||||
return;
|
||||
}
|
||||
|
||||
int tempVisibleHeight = rect.bottom;
|
||||
|
||||
if (tempVisibleHeight == 0) {
|
||||
HiLog.debug(LABEL, "invaild rect");
|
||||
} else if (mVisibleHeight == 0) {
|
||||
mVisibleHeight = tempVisibleHeight;
|
||||
} else {
|
||||
if (tempVisibleHeight > mVisibleHeight && (Math.abs(tempVisibleHeight - mVisibleHeight) > 200)) {
|
||||
HiLog.debug(LABEL, "input method down, the height is 0");
|
||||
mTextFieldLocal.setText("input method down, the height is 0");
|
||||
mVisibleHeight = tempVisibleHeight;
|
||||
onBoardDown();
|
||||
return;
|
||||
}
|
||||
if (tempVisibleHeight < mVisibleHeight && (Math.abs(tempVisibleHeight - mVisibleHeight) > 200)) {
|
||||
HiLog.debug(LABEL, "input method up, the height is" + Math.abs(tempVisibleHeight - mVisibleHeight));
|
||||
mTextFieldLocal.setText("input method up, the height is ---" + Math.abs(tempVisibleHeight - mVisibleHeight));
|
||||
onBoardUp(Math.abs(tempVisibleHeight - mVisibleHeight));
|
||||
mVisibleHeight = tempVisibleHeight;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void onBoardUp(int boardHeight) {
|
||||
HiLog.debug(LABEL, "onBoardUp, the height is ++++" + boardHeight);
|
||||
ComponentContainer.LayoutConfig layoutConfig = mTextFieldLocal.getLayoutConfig();
|
||||
layoutConfig.setMarginBottom(boardHeight);//835
|
||||
mTextFieldLocal.setLayoutConfig(layoutConfig);
|
||||
}
|
||||
|
||||
private void onBoardDown() {
|
||||
HiLog.debug(LABEL, "onBoardDown");
|
||||
ComponentContainer.LayoutConfig layoutConfig = mTextFieldLocal.getLayoutConfig();
|
||||
layoutConfig.setMarginBottom(0);
|
||||
mTextFieldLocal.setLayoutConfig(layoutConfig);
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
Public functions.
|
||||
**************************************************************************************/
|
||||
|
||||
public void show(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||
mIsMultiLine = isMultiline;
|
||||
// TODO: truncate
|
||||
// this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
|
||||
// mTextField.setTruncationMode(Text.TruncationMode.ELLIPSIS_AT_END);
|
||||
|
||||
mTextFieldLocal.setText(defaultValue);
|
||||
this.setConfirmType(confirmType);
|
||||
// this.setInputType(inputType, mIsMultiLine); // FIXME: should enable
|
||||
this.addListeners();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
mTextFieldLocal.clearFocus();
|
||||
this.removeListeners();
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
Private functions.
|
||||
**************************************************************************************/
|
||||
|
||||
private void setConfirmType(final String confirmType) {
|
||||
if (confirmType.contentEquals("done")) {
|
||||
mTextFieldLocal.setInputMethodOption(InputAttribute.ENTER_KEY_TYPE_UNSPECIFIED);
|
||||
mButtonTitle = "Done"; //TODO: read from ResourceTable
|
||||
} else if (confirmType.contentEquals("next")) {
|
||||
mTextFieldLocal.setInputMethodOption(InputAttribute.ENTER_KEY_TYPE_UNSPECIFIED);
|
||||
mButtonTitle = "Done"; //TODO: read from ResourceTable
|
||||
} else if (confirmType.contentEquals("search")) {
|
||||
mTextFieldLocal.setInputMethodOption(InputAttribute.ENTER_KEY_TYPE_SEARCH);
|
||||
mButtonTitle = "Search"; //TODO: read from ResourceTable
|
||||
} else if (confirmType.contentEquals("go")) {
|
||||
mTextFieldLocal.setInputMethodOption(InputAttribute.ENTER_KEY_TYPE_GO);
|
||||
mButtonTitle = "Go"; //TODO: read from ResourceTable
|
||||
} else if (confirmType.contentEquals("send")) {
|
||||
mTextFieldLocal.setInputMethodOption(InputAttribute.ENTER_KEY_TYPE_SEND);
|
||||
mButtonTitle = "Send"; //TODO: read from ResourceTable
|
||||
} else {
|
||||
mButtonTitle = null;
|
||||
HiLog.error(TAG, "unknown confirm type " + confirmType);
|
||||
}
|
||||
}
|
||||
|
||||
private void setInputType(final String inputType, boolean isMultiLine) {
|
||||
if (inputType.contentEquals("text")) {
|
||||
if (isMultiLine) {
|
||||
// this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_TEXT);
|
||||
mTextFieldLocal.setMultipleLine(true);
|
||||
} else {
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_TEXT);
|
||||
mTextFieldLocal.setMultipleLine(false);
|
||||
}
|
||||
} else if (inputType.contentEquals("email")) {
|
||||
// this.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_TEXT);
|
||||
} else if (inputType.contentEquals("number")) {
|
||||
// this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_NUMBER);
|
||||
} else if (inputType.contentEquals("phone")) {
|
||||
// this.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_TEXT);
|
||||
} else if (inputType.contentEquals("password")) {
|
||||
// this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
mTextFieldLocal.setTextInputType(InputAttribute.PATTERN_PASSWORD);
|
||||
} else {
|
||||
HiLog.error(TAG, "unknown input type " + inputType);
|
||||
}
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
|
||||
mTextFieldLocal.setEditorActionListener(new Text.EditorActionListener() {
|
||||
@Override
|
||||
public boolean onTextEditorAction(int i) {
|
||||
//TODO:
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mTextFieldLocal.addTextObserver(mTextWatcher);
|
||||
}
|
||||
|
||||
private void removeListeners() {
|
||||
// this.setOnEditorActionListener(null);
|
||||
mTextFieldLocal.removeTextObserver(mTextWatcher);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart(Intent intent) {
|
||||
super.onStart(intent);
|
||||
|
||||
getKeyBoard().setShowMode(AccessibleAbility.SHOW_MODE_AUTO);
|
||||
getAbility().setAbilitySliceAnimator(null); // remove animation
|
||||
|
||||
//FIXME: todo
|
||||
// getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); // android
|
||||
// getWindow().setInputPanelDisplayType(Dis); // ohos
|
||||
|
||||
sThis = new WeakReference<CocosEditBoxAbility>(this);
|
||||
getWindow().setInputPanelDisplayType(WindowManager.LayoutConfig.INPUT_ADJUST_PAN);
|
||||
|
||||
setUIContent(ResourceTable.Layout_editbox_layout);
|
||||
delayShow(intent);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void delayShow(final Intent intent) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosEditBoxAbility.this.addItems();
|
||||
CocosEditBoxAbility.this.show(intent.getStringParam("defaultValue"),
|
||||
intent.getIntParam("maxLength", 60),
|
||||
intent.getBooleanParam("isMultiline", false),
|
||||
intent.getBooleanParam("confirmHold", true),
|
||||
intent.getStringParam("confirmType"),
|
||||
intent.getStringParam("inputType"));
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************
|
||||
Public functions.
|
||||
**************************************************************************************/
|
||||
|
||||
/***************************************************************************************
|
||||
Private functions.
|
||||
**************************************************************************************/
|
||||
private void addItems() {
|
||||
mTextFieldHelper = new CocosTextHelper(getTextField());
|
||||
getTextField().setBubbleSize(0, 0);
|
||||
mButton = (Button) findComponentById(ResourceTable.Id_editbox_enterBtn);
|
||||
mButton.setTouchEventListener(new Component.TouchEventListener() {
|
||||
@Override
|
||||
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
|
||||
CocosEditBoxAbility.this.onKeyboardConfirm(CocosEditBoxAbility.this.getTextField().getText());
|
||||
if (!CocosEditBoxAbility.this.mConfirmHold && touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN)
|
||||
CocosEditBoxAbility.this.hide();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// When touch area outside EditText and soft keyboard, then hide.
|
||||
Component layout = findComponentById(ResourceTable.Id_editbox_container);
|
||||
layout.setTouchEventListener(new Component.TouchEventListener() {
|
||||
@Override
|
||||
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
|
||||
if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {
|
||||
CocosEditBoxAbility.this.hide();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
// layout.setLayoutRefreshedListener(new Component.LayoutRefreshedListener() {
|
||||
// @Override
|
||||
// public void onRefreshed(Component component) {
|
||||
// // detect keyboard re-layout?
|
||||
// HiLog.debug(LABEL, component.getClass().getSimpleName());
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private TextField getTextField() {
|
||||
return (TextField)findComponentById(ResourceTable.Id_editbox_textField);
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
// Utils.hideVirtualButton(); // TODO: hide virtual button
|
||||
this.closeKeyboard();
|
||||
}
|
||||
|
||||
public void show(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||
TextField tf = getTextField();
|
||||
mConfirmHold = confirmHold;
|
||||
mTextFieldHelper.show(defaultValue, maxLength, isMultiline, confirmHold, confirmType, inputType);
|
||||
int editPaddingBottom = tf.getPaddingBottom();
|
||||
int editPadding = tf.getPaddingTop();
|
||||
tf.setPadding(editPadding, editPadding, editPadding, editPaddingBottom);
|
||||
|
||||
|
||||
mButton.setText(mButtonTitle);
|
||||
// if (mButtonTitle == null || mButton.length() == 0) {
|
||||
// mButton.setPadding(0, 0, 0, 0);
|
||||
// mButtonParams.setMargins(0, 0, 0, 0);
|
||||
// mButtonLayout.setVisibility(Component.INVISIBLE);
|
||||
// } else {
|
||||
// int buttonTextPadding = mEditText.getPaddingBottom() / 2;
|
||||
// mButton.setPadding(editPadding, buttonTextPadding, editPadding, buttonTextPadding);
|
||||
// mButtonParams.setMargins(0, buttonTextPadding, 2, 0);
|
||||
// mButtonLayout.setVisibility(Component.VISIBLE);
|
||||
// }
|
||||
|
||||
this.openKeyboard();
|
||||
}
|
||||
|
||||
private void closeKeyboard() {
|
||||
TextField tf = getTextField();
|
||||
CocosHelper.runOnUIThread(tf::clearFocus);
|
||||
this.onKeyboardComplete(tf.getText());
|
||||
|
||||
}
|
||||
|
||||
private void openKeyboard() {
|
||||
TextField tf = getTextField();
|
||||
CocosHelper.runOnUIThread(() -> {
|
||||
tf.requestFocus();
|
||||
tf.simulateClick();
|
||||
});
|
||||
}
|
||||
|
||||
private SoftKeyBoardController getKeyBoard() {
|
||||
return ((AccessibleAbility)getAbility()).getSoftKeyBoardController();
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
Functions invoked by CPP.
|
||||
**************************************************************************************/
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void showNative(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||
|
||||
CocosHelper.runOnUIThread(() -> {
|
||||
Intent i = new Intent();
|
||||
i.setParam("defaultValue", defaultValue);
|
||||
i.setParam("maxLength", maxLength);
|
||||
i.setParam("isMultiline", isMultiline);
|
||||
i.setParam("confirmHold", confirmHold);
|
||||
i.setParam("confirmType", confirmType);
|
||||
i.setParam("inputType", inputType);
|
||||
CocosEditBoxAbility ability = new CocosEditBoxAbility();
|
||||
GlobalObject.getAbilitySlice().present(ability, i);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void hideNative() {
|
||||
CocosHelper.runOnUIThread(() -> {
|
||||
if(null != CocosEditBoxAbility.sThis) {
|
||||
CocosEditBoxAbility ability = CocosEditBoxAbility.sThis.get();
|
||||
if(ability != null) {
|
||||
ability.hide();
|
||||
ability.terminate();
|
||||
CocosEditBoxAbility.sThis = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/***************************************************************************************
|
||||
Native functions invoked by UI.
|
||||
**************************************************************************************/
|
||||
private void onKeyboardInput(String text) {
|
||||
CocosHelper.runOnGameThreadAtForeground(() ->
|
||||
CocosEditBoxAbility.onKeyboardInputNative(text)
|
||||
);
|
||||
}
|
||||
|
||||
private void onKeyboardComplete(String text) {
|
||||
CocosHelper.runOnGameThreadAtForeground(() ->
|
||||
CocosEditBoxAbility.onKeyboardCompleteNative(text)
|
||||
);
|
||||
}
|
||||
|
||||
private void onKeyboardConfirm(String text) {
|
||||
CocosHelper.runOnGameThreadAtForeground(() ->
|
||||
CocosEditBoxAbility.onKeyboardConfirmNative(text)
|
||||
);
|
||||
}
|
||||
|
||||
private static native void onKeyboardInputNative(String text);
|
||||
|
||||
private static native void onKeyboardCompleteNative(String text);
|
||||
|
||||
private static native void onKeyboardConfirmNative(String text);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2013 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.agp.window.dialog.CommonDialog;
|
||||
import ohos.agp.window.dialog.IDialog;
|
||||
import ohos.eventhandler.EventHandler;
|
||||
import ohos.eventhandler.EventRunner;
|
||||
import ohos.eventhandler.InnerEvent;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class CocosHandler extends EventHandler {
|
||||
// ===========================================================
|
||||
// Constants
|
||||
// ===========================================================
|
||||
public final static int HANDLER_SHOW_DIALOG = 1;
|
||||
|
||||
// ===========================================================
|
||||
// Fields
|
||||
// ===========================================================
|
||||
private WeakReference<CocosAbilitySlice> mActivity;
|
||||
|
||||
// ===========================================================
|
||||
// Constructors
|
||||
// ===========================================================
|
||||
public CocosHandler(CocosAbilitySlice activity) {
|
||||
super(EventRunner.getMainEventRunner());
|
||||
this.mActivity = new WeakReference<CocosAbilitySlice>(activity);
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Getter & Setter
|
||||
// ===========================================================
|
||||
|
||||
// ===========================================================
|
||||
// Methods for/from SuperClass/Interfaces
|
||||
// ===========================================================
|
||||
|
||||
// ===========================================================
|
||||
// Methods
|
||||
// ===========================================================
|
||||
|
||||
@Override
|
||||
public void processEvent(InnerEvent msg) {
|
||||
switch (msg.eventId) {
|
||||
case CocosHandler.HANDLER_SHOW_DIALOG:
|
||||
showDialog(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void showDialog(InnerEvent msg) {
|
||||
CocosAbilitySlice theActivity = this.mActivity.get();
|
||||
DialogMessage dialogMessage = (DialogMessage)msg.object;
|
||||
|
||||
CommonDialog dialog = new CommonDialog(theActivity.getContext());
|
||||
dialog.setTitleText(dialogMessage.title)
|
||||
.setContentText(dialogMessage.message)
|
||||
.setButton(IDialog.BUTTON1, "OK", new IDialog.ClickedListener() {
|
||||
@Override
|
||||
public void onClick(IDialog iDialog, int i) {
|
||||
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Inner and Anonymous Classes
|
||||
// ===========================================================
|
||||
|
||||
public static class DialogMessage {
|
||||
public String title;
|
||||
public String message;
|
||||
|
||||
public DialogMessage(String title, String message) {
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,388 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
import ohos.aafwk.content.Intent;
|
||||
import ohos.aafwk.content.Operation;
|
||||
import ohos.agp.text.Font;
|
||||
import ohos.agp.window.service.Display;
|
||||
import ohos.agp.window.service.DisplayManager;
|
||||
import ohos.app.Context;
|
||||
import ohos.app.dispatcher.TaskDispatcher;
|
||||
import ohos.batterymanager.BatteryInfo;
|
||||
import ohos.event.commonevent.*;
|
||||
import ohos.global.resource.RawFileEntry;
|
||||
import ohos.global.resource.Resource;
|
||||
import ohos.miscservices.pasteboard.PasteData;
|
||||
import ohos.miscservices.pasteboard.SystemPasteboard;
|
||||
import ohos.net.NetManager;
|
||||
import ohos.rpc.RemoteException;
|
||||
import ohos.system.DeviceInfo;
|
||||
import ohos.system.version.SystemVersion;
|
||||
import ohos.utils.net.Uri;
|
||||
import ohos.vibrator.agent.VibratorAgent;
|
||||
import ohos.vibrator.bean.VibrationPattern;
|
||||
import ohos.wifi.WifiDevice;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
|
||||
public class CocosHelper {
|
||||
// ===========================================================
|
||||
// Constants
|
||||
// ===========================================================
|
||||
private static final String TAG = CocosHelper.class.getSimpleName();
|
||||
|
||||
// ===========================================================
|
||||
// Fields
|
||||
// ===========================================================
|
||||
|
||||
private static AbilitySlice sAbilitySlice;
|
||||
private static VibratorAgent sVibrateService;
|
||||
private static Optional<BatteryReceiver> sBatteryReceiver = Optional.empty();
|
||||
private static Thread sUIThread = null;
|
||||
|
||||
public static final int NETWORK_TYPE_NONE = 0;
|
||||
public static final int NETWORK_TYPE_LAN = 1;
|
||||
public static final int NETWORK_TYPE_WWAN = 2;
|
||||
|
||||
// The absolute path to the OBB if it exists.
|
||||
private static String sObbFilePath = "";
|
||||
|
||||
|
||||
static class LockedTaskQ {
|
||||
private final Object readMtx = new Object();
|
||||
private Queue<Runnable> sTaskQ = new LinkedList<>();
|
||||
public void addTask(Runnable runnable) {
|
||||
synchronized (readMtx) {
|
||||
sTaskQ.add(runnable);
|
||||
}
|
||||
}
|
||||
public void runTasks(){
|
||||
Queue<Runnable> tmp;
|
||||
synchronized (readMtx) {
|
||||
tmp = sTaskQ;
|
||||
sTaskQ = new LinkedList<>();
|
||||
}
|
||||
for(Runnable runnable : tmp){
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static LockedTaskQ sTaskQOnGameThread = new LockedTaskQ();
|
||||
private static LockedTaskQ sForegroundTaskQOnGameThread = new LockedTaskQ();
|
||||
/**
|
||||
* Battery receiver to getting battery level.
|
||||
*/
|
||||
static class BatteryReceiver extends CommonEventSubscriber {
|
||||
public float sBatteryLevel = 0.0f;
|
||||
|
||||
public BatteryReceiver(CommonEventSubscribeInfo subscribeInfo) {
|
||||
super(subscribeInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceiveEvent(CommonEventData commonEventData) {
|
||||
Intent intent = commonEventData.getIntent();
|
||||
if (intent != null) {
|
||||
int capacity = intent.getIntParam(BatteryInfo.OHOS_BATTERY_CAPACITY, 100);
|
||||
float level = capacity / 100.0f;
|
||||
sBatteryLevel = Math.min(Math.max(level, 0.0f), 1.0f);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void registerBatteryLevelReceiver(Context context) {
|
||||
if (sBatteryReceiver.isPresent()) return;
|
||||
|
||||
MatchingSkills ms = new MatchingSkills();
|
||||
ms.addEvent(CommonEventSupport.COMMON_EVENT_BATTERY_CHANGED);
|
||||
CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(ms);
|
||||
sBatteryReceiver = Optional.of(new BatteryReceiver(subscribeInfo));
|
||||
try {
|
||||
CommonEventManager.subscribeCommonEvent(sBatteryReceiver.get());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void unregisterBatteryLevelReceiver(Context context) {
|
||||
if (sBatteryReceiver.isPresent()) {
|
||||
try {
|
||||
CommonEventManager.unsubscribeCommonEvent(sBatteryReceiver.get());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
sBatteryReceiver = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
//Run on game thread forever, no matter foreground or background
|
||||
public static void runOnGameThread(final Runnable runnable) {
|
||||
sTaskQOnGameThread.addTask(runnable);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
static void flushTasksOnGameThread() {
|
||||
sTaskQOnGameThread.runTasks();
|
||||
}
|
||||
public static void runOnGameThreadAtForeground(final Runnable runnable) {
|
||||
sForegroundTaskQOnGameThread.addTask(runnable);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
static void flushTasksOnGameThreadAtForeground() {
|
||||
sForegroundTaskQOnGameThread.runTasks();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static int getNetworkType() {
|
||||
|
||||
NetManager netManager = NetManager.getInstance(sAbilitySlice.getContext());
|
||||
if (!netManager.hasDefaultNet()) return NETWORK_TYPE_NONE;
|
||||
|
||||
WifiDevice wifiDevice = WifiDevice.getInstance(sAbilitySlice.getContext());
|
||||
if (null == wifiDevice) return NETWORK_TYPE_NONE;
|
||||
|
||||
if (wifiDevice.isWifiActive() && wifiDevice.isConnected()) {
|
||||
return NETWORK_TYPE_LAN;
|
||||
}
|
||||
return NETWORK_TYPE_WWAN;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Constructors
|
||||
// ===========================================================
|
||||
|
||||
private static boolean sInited = false;
|
||||
|
||||
public static void init(final AbilitySlice activity) {
|
||||
sAbilitySlice = activity;
|
||||
if (!sInited) {
|
||||
CocosHelper.sVibrateService = new VibratorAgent();
|
||||
CocosHelper.sUIThread = Thread.currentThread();
|
||||
sInited = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static float getBatteryLevel() {
|
||||
return sBatteryReceiver.map(x -> x.sBatteryLevel).orElse(1.0f);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getObbFilePath() {
|
||||
return CocosHelper.sObbFilePath;
|
||||
}
|
||||
|
||||
public static String getWritablePath() {
|
||||
return sAbilitySlice.getApplicationContext().getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getCurrentLanguage() {
|
||||
return Locale.getDefault().getLanguage();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getCurrentLanguageCode() {
|
||||
return Locale.getDefault().toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getDeviceModel() {
|
||||
return DeviceInfo.getModel();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getSystemVersion() {
|
||||
return SystemVersion.getVersion();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void vibrate(float durSec) {
|
||||
List<Integer> vlist = sVibrateService.getVibratorIdList();
|
||||
if (vlist.isEmpty()) return;
|
||||
int durationMs = (int) (1000 * durSec);
|
||||
int vibrateId = -1;
|
||||
for (Integer vId : vlist) {
|
||||
// TODO: choose preferred vibration effect
|
||||
if (sVibrateService.isEffectSupport(vId, VibrationPattern.VIBRATOR_TYPE_CAMERA_CLICK)) {
|
||||
vibrateId = vId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vibrateId < 0) {
|
||||
sVibrateService.startOnce(durationMs);
|
||||
} else {
|
||||
sVibrateService.startOnce(durationMs, vibrateId);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static boolean openURL(String url) {
|
||||
runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent i = new Intent();
|
||||
Operation operation = new Intent.OperationBuilder()
|
||||
.withUri(Uri.parse(url))
|
||||
.build();
|
||||
i.setOperation(operation);
|
||||
sAbilitySlice.startAbility(i);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void copyTextToClipboard(final String text) {
|
||||
runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PasteData pasteData = PasteData.creatPlainTextData(text);
|
||||
SystemPasteboard.getSystemPasteboard(sAbilitySlice.getContext()).setPasteData(pasteData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void runOnUIThread(final Runnable r, boolean forceDelay) {
|
||||
if (Thread.currentThread().getId() == sUIThread.getId() && !forceDelay) {
|
||||
r.run();
|
||||
} else {
|
||||
TaskDispatcher dispatcher = sAbilitySlice.getUITaskDispatcher();
|
||||
dispatcher.asyncDispatch(r);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runOnUIThread(final Runnable r) {
|
||||
runOnUIThread(r, false);
|
||||
}
|
||||
|
||||
public static void ruOnUIThreadSync(final Runnable r) {
|
||||
CountDownLatch cd = new CountDownLatch(1);
|
||||
runOnUIThread(() -> {
|
||||
r.run();
|
||||
cd.countDown();
|
||||
});
|
||||
try {
|
||||
cd.await();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDeviceRotation() {
|
||||
try {
|
||||
DisplayManager mgr = DisplayManager.getInstance();
|
||||
Optional<Display> display = mgr.getDefaultDisplay(sAbilitySlice.getContext());
|
||||
return display.map(Display::getRotation).orElse(0);
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 0 indicates no rotation,
|
||||
// 1 indicates 90 degrees,
|
||||
// 2 indicates 180 degrees,
|
||||
// 3 indicates 270 degrees.
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static float[] getSafeArea() {
|
||||
return new float[]{0, 0, 0, 0};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static int getDPI() {
|
||||
Optional<Display> disp = DisplayManager.getInstance().getDefaultDisplay(getContext());
|
||||
if (disp.isPresent()) {
|
||||
return (int) disp.get().getAttributes().xDpi;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return sAbilitySlice.getContext();
|
||||
}
|
||||
|
||||
public static File copyOutResFile(Context ctx, String path, String tmpName) throws IOException{
|
||||
File fontTmpFile;
|
||||
FileOutputStream fontOutputStream=null;
|
||||
Resource resource = null;
|
||||
if(!path.startsWith("resources/rawfile/")){
|
||||
path = "resources/rawfile/" + path;
|
||||
}
|
||||
RawFileEntry entry = ctx.getResourceManager().getRawFileEntry(path);
|
||||
try {
|
||||
fontTmpFile = File.createTempFile(tmpName, "-tmp");
|
||||
fontOutputStream = new FileOutputStream(fontTmpFile);
|
||||
resource = entry.openRawFile();
|
||||
byte[] buf = new byte[4096];
|
||||
while (resource.available() > 0) {
|
||||
int readBytes = resource.read(buf, 0, 4096);
|
||||
if (readBytes > 0)
|
||||
fontOutputStream.write(buf, 0, readBytes);
|
||||
}
|
||||
} finally {
|
||||
if(fontOutputStream!=null)
|
||||
fontOutputStream.close();
|
||||
if(resource != null)
|
||||
resource.close();
|
||||
}
|
||||
return fontTmpFile;
|
||||
}
|
||||
|
||||
public static File copyToTempFile(String path, String tmpName) throws IOException {
|
||||
File fontTmpFile;
|
||||
FileOutputStream fontOutputStream=null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fontTmpFile = File.createTempFile(tmpName, "-tmp");
|
||||
fontOutputStream = new FileOutputStream(fontTmpFile);
|
||||
fis = new FileInputStream(path);
|
||||
byte[] buf = new byte[4096];
|
||||
while (fis.available() > 0) {
|
||||
int readBytes = fis.read(buf, 0, 4096);
|
||||
if (readBytes > 0)
|
||||
fontOutputStream.write(buf, 0, readBytes);
|
||||
}
|
||||
} finally {
|
||||
if(fontOutputStream!=null)
|
||||
fontOutputStream.close();
|
||||
if(fis != null)
|
||||
fis.close();
|
||||
}
|
||||
return fontTmpFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,433 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2014 cocos2d-x.org
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.global.resource.RawFileEntry;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
public class CocosHttpURLConnection {
|
||||
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "CocosHttpURLConnection");
|
||||
private static final String POST_METHOD = "POST";
|
||||
private static final String PUT_METHOD = "PUT";
|
||||
private static final String PATCH_METHOD = "PATCH";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static HttpURLConnection createHttpURLConnection(String linkURL) {
|
||||
URL url;
|
||||
HttpURLConnection urlConnection;
|
||||
try {
|
||||
url = new URL(linkURL);
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
//Accept-Encoding
|
||||
urlConnection.setRequestProperty("Accept-Encoding", "identity");
|
||||
urlConnection.setDoInput(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "createHttpURLConnection:" + e.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
return urlConnection;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void setReadAndConnectTimeout(HttpURLConnection urlConnection, int readMiliseconds, int connectMiliseconds) {
|
||||
urlConnection.setReadTimeout(readMiliseconds);
|
||||
urlConnection.setConnectTimeout(connectMiliseconds);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void setRequestMethod(HttpURLConnection urlConnection, String method) {
|
||||
try {
|
||||
urlConnection.setRequestMethod(method);
|
||||
if (method.equalsIgnoreCase(POST_METHOD) || method.equalsIgnoreCase(PUT_METHOD)) {
|
||||
urlConnection.setDoOutput(true);
|
||||
}
|
||||
} catch (ProtocolException e) {
|
||||
HiLog.error(LABEL, "setRequestMethod:" + e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void setVerifySSL(HttpURLConnection urlConnection, String sslFilename) {
|
||||
if (!(urlConnection instanceof HttpsURLConnection))
|
||||
return;
|
||||
|
||||
|
||||
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlConnection;
|
||||
|
||||
try {
|
||||
InputStream caInput = null;
|
||||
FileInputStream fileInputStream = null;
|
||||
if (sslFilename.startsWith("/")) {
|
||||
caInput = new BufferedInputStream(new FileInputStream(sslFilename));
|
||||
} else {
|
||||
String assetString = "assets/";
|
||||
String assetsfilenameString = sslFilename.substring(assetString.length());
|
||||
RawFileEntry fileEntry = CocosHelper.getContext().getResourceManager().getRawFileEntry(assetsfilenameString);
|
||||
fileInputStream = new FileInputStream(fileEntry.openRawFileDescriptor().getFileDescriptor());
|
||||
caInput = new BufferedInputStream(fileInputStream);
|
||||
}
|
||||
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
Certificate ca;
|
||||
ca = cf.generateCertificate(caInput);
|
||||
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
|
||||
caInput.close();
|
||||
if (fileInputStream != null) fileInputStream.close();
|
||||
|
||||
// Create a KeyStore containing our trusted CAs
|
||||
String keyStoreType = KeyStore.getDefaultType();
|
||||
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
keyStore.load(null, null);
|
||||
keyStore.setCertificateEntry("ca", ca);
|
||||
|
||||
// Create a TrustManager that trusts the CAs in our KeyStore
|
||||
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
|
||||
tmf.init(keyStore);
|
||||
|
||||
// Create an SSLContext that uses our TrustManager
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(null, tmf.getTrustManagers(), null);
|
||||
|
||||
httpsURLConnection.setSSLSocketFactory(context.getSocketFactory());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "setVerifySSL:" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void addRequestHeader(HttpURLConnection urlConnection, String key, String value) {
|
||||
urlConnection.setRequestProperty(key, value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static int connect(HttpURLConnection http) {
|
||||
int suc = 0;
|
||||
|
||||
try {
|
||||
http.connect();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "connect" + e.toString());
|
||||
suc = 1;
|
||||
}
|
||||
|
||||
return suc;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void disconnect(HttpURLConnection http) {
|
||||
http.disconnect();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void sendRequest(HttpURLConnection http, byte[] byteArray) {
|
||||
try {
|
||||
OutputStream out = http.getOutputStream();
|
||||
if (null != byteArray) {
|
||||
out.write(byteArray);
|
||||
out.flush();
|
||||
}
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "sendRequest:" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static String getResponseHeaders(HttpURLConnection http) {
|
||||
Map<String, List<String>> headers = http.getHeaderFields();
|
||||
if (null == headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String header = "";
|
||||
|
||||
for (Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (null == key) {
|
||||
header += listToString(entry.getValue(), ",") + "\n";
|
||||
} else {
|
||||
header += key + ":" + listToString(entry.getValue(), ",") + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static String getResponseHeaderByIdx(HttpURLConnection http, int idx) {
|
||||
Map<String, List<String>> headers = http.getHeaderFields();
|
||||
if (null == headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String header = null;
|
||||
|
||||
int counter = 0;
|
||||
for (Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
if (counter == idx) {
|
||||
String key = entry.getKey();
|
||||
if (null == key) {
|
||||
header = listToString(entry.getValue(), ",") + "\n";
|
||||
} else {
|
||||
header = key + ":" + listToString(entry.getValue(), ",") + "\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static String getResponseHeaderByKey(HttpURLConnection http, String key) {
|
||||
if (null == key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, List<String>> headers = http.getHeaderFields();
|
||||
if (null == headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String header = null;
|
||||
|
||||
for (Entry<String, List<String>> entry : headers.entrySet()) {
|
||||
if (key.equalsIgnoreCase(entry.getKey())) {
|
||||
if ("set-cookie".equalsIgnoreCase(key)) {
|
||||
header = combinCookies(entry.getValue(), http.getURL().getHost());
|
||||
} else {
|
||||
header = listToString(entry.getValue(), ",");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static int getResponseHeaderByKeyInt(HttpURLConnection http, String key) {
|
||||
String value = http.getHeaderField(key);
|
||||
|
||||
if (null == value) {
|
||||
return 0;
|
||||
} else {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static byte[] getResponseContent(HttpURLConnection http) {
|
||||
InputStream in;
|
||||
try {
|
||||
in = http.getInputStream();
|
||||
String contentEncoding = http.getContentEncoding();
|
||||
if (contentEncoding != null) {
|
||||
if (contentEncoding.equalsIgnoreCase("gzip")) {
|
||||
in = new GZIPInputStream(http.getInputStream()); //reads 2 bytes to determine GZIP stream!
|
||||
} else if (contentEncoding.equalsIgnoreCase("deflate")) {
|
||||
in = new InflaterInputStream(http.getInputStream());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
in = http.getErrorStream();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "1 getResponseContent: " + e.toString());
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] buffer = new byte[1024];
|
||||
int size = 0;
|
||||
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
|
||||
while ((size = in.read(buffer, 0, 1024)) != -1) {
|
||||
bytestream.write(buffer, 0, size);
|
||||
}
|
||||
byte retbuffer[] = bytestream.toByteArray();
|
||||
bytestream.close();
|
||||
return retbuffer;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "2 getResponseContent:" + e.toString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static int getResponseCode(HttpURLConnection http) {
|
||||
int code = 0;
|
||||
try {
|
||||
code = http.getResponseCode();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HiLog.error(LABEL, "getResponseCode:" + e.toString());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static String getResponseMessage(HttpURLConnection http) {
|
||||
String msg;
|
||||
try {
|
||||
msg = http.getResponseMessage();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
msg = e.toString();
|
||||
HiLog.error(LABEL, "getResponseMessage: " + msg);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
public static String listToString(List<String> list, String strInterVal) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean flag = false;
|
||||
for (String str : list) {
|
||||
if (flag) {
|
||||
result.append(strInterVal);
|
||||
}
|
||||
if (null == str) {
|
||||
str = "";
|
||||
}
|
||||
result.append(str);
|
||||
flag = true;
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String combinCookies(List<String> list, String hostDomain) {
|
||||
StringBuilder sbCookies = new StringBuilder();
|
||||
String domain = hostDomain;
|
||||
String tailmatch = "FALSE";
|
||||
String path = "/";
|
||||
String secure = "FALSE";
|
||||
String key = null;
|
||||
String value = null;
|
||||
String expires = null;
|
||||
for (String str : list) {
|
||||
String[] parts = str.split(";");
|
||||
for (String part : parts) {
|
||||
int firstIndex = part.indexOf("=");
|
||||
if (-1 == firstIndex)
|
||||
continue;
|
||||
|
||||
String[] item = {part.substring(0, firstIndex), part.substring(firstIndex + 1)};
|
||||
if ("expires".equalsIgnoreCase(item[0].trim())) {
|
||||
expires = str2Seconds(item[1].trim());
|
||||
} else if ("path".equalsIgnoreCase(item[0].trim())) {
|
||||
path = item[1];
|
||||
} else if ("secure".equalsIgnoreCase(item[0].trim())) {
|
||||
secure = item[1];
|
||||
} else if ("domain".equalsIgnoreCase(item[0].trim())) {
|
||||
domain = item[1];
|
||||
} else if ("version".equalsIgnoreCase(item[0].trim()) || "max-age".equalsIgnoreCase(item[0].trim())) {
|
||||
//do nothing
|
||||
} else {
|
||||
key = item[0];
|
||||
value = item[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (null == domain) {
|
||||
domain = "none";
|
||||
}
|
||||
|
||||
sbCookies.append(domain);
|
||||
sbCookies.append('\t');
|
||||
sbCookies.append(tailmatch); //access
|
||||
sbCookies.append('\t');
|
||||
sbCookies.append(path); //path
|
||||
sbCookies.append('\t');
|
||||
sbCookies.append(secure); //secure
|
||||
sbCookies.append('\t');
|
||||
sbCookies.append(expires); //expires
|
||||
sbCookies.append("\t");
|
||||
sbCookies.append(key); //key
|
||||
sbCookies.append("\t");
|
||||
sbCookies.append(value); //value
|
||||
sbCookies.append('\n');
|
||||
}
|
||||
|
||||
return sbCookies.toString();
|
||||
}
|
||||
|
||||
private static String str2Seconds(String strTime) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
long milliseconds = 0;
|
||||
|
||||
try {
|
||||
c.setTime(new SimpleDateFormat("EEE, dd-MMM-yy hh:mm:ss zzz", Locale.US).parse(strTime));
|
||||
milliseconds = c.getTimeInMillis() / 1000;
|
||||
} catch (ParseException e) {
|
||||
HiLog.error(LABEL, "str2Seconds: " + e.toString());
|
||||
}
|
||||
|
||||
return Long.toString(milliseconds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
public class CocosJavascriptJavaBridge {
|
||||
@SuppressWarnings("unused")
|
||||
public static native int evalString(String value);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2013 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.multimodalinput.event.KeyEvent;
|
||||
|
||||
public class CocosKeyCodeHandler {
|
||||
private CocosAbilitySlice mAct;
|
||||
@SuppressWarnings("unused")
|
||||
public native void handleKeyDown(final int keyCode);
|
||||
@SuppressWarnings("unused")
|
||||
public native void handleKeyUp(final int keyCode);
|
||||
|
||||
public CocosKeyCodeHandler(CocosAbilitySlice act) {
|
||||
mAct = act;
|
||||
}
|
||||
|
||||
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEY_BACK:
|
||||
// CocosVideoHelper.mVideoHandler.sendEmptyMessage(CocosVideoHelper.KeyEventBack);
|
||||
case KeyEvent.KEY_MENU:
|
||||
case KeyEvent.KEY_DPAD_LEFT:
|
||||
case KeyEvent.KEY_DPAD_RIGHT:
|
||||
case KeyEvent.KEY_DPAD_UP:
|
||||
case KeyEvent.KEY_DPAD_DOWN:
|
||||
case KeyEvent.KEY_ENTER:
|
||||
case KeyEvent.KEY_MEDIA_PLAY_PAUSE:
|
||||
case KeyEvent.KEY_DPAD_CENTER:
|
||||
CocosHelper.runOnGameThreadAtForeground(() -> handleKeyDown(keyCode));
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onKeyUp(final int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEY_BACK:
|
||||
case KeyEvent.KEY_MENU:
|
||||
case KeyEvent.KEY_DPAD_LEFT:
|
||||
case KeyEvent.KEY_DPAD_RIGHT:
|
||||
case KeyEvent.KEY_DPAD_UP:
|
||||
case KeyEvent.KEY_DPAD_DOWN:
|
||||
case KeyEvent.KEY_ENTER:
|
||||
case KeyEvent.KEY_MEDIA_PLAY_PAUSE:
|
||||
case KeyEvent.KEY_DPAD_CENTER:
|
||||
CocosHelper.runOnGameThreadAtForeground(() -> handleKeyDown(keyCode));
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.data.DatabaseHelper;
|
||||
import ohos.data.rdb.*;
|
||||
import ohos.data.resultset.ResultSet;
|
||||
|
||||
public class CocosLocalStorage {
|
||||
|
||||
private static String DATABASE_NAME = "jsb.storage.db";
|
||||
private static String TABLE_NAME = "data";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private static DatabaseHelper mDatabaseOpenHelper = null;
|
||||
private static RdbStore mDatabase = null;
|
||||
|
||||
private static RdbOpenCallback rdbOpenCallback = new RdbOpenCallback() {
|
||||
@Override
|
||||
public void onCreate(RdbStore rdbStore) {
|
||||
rdbStore.executeSql("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"(key TEXT PRIMARY KEY,value TEXT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(RdbStore rdbStore, int i, int i1) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean init(String dbName, String tableName) {
|
||||
if (GlobalObject.getAbilitySlice() != null) {
|
||||
DATABASE_NAME = dbName;
|
||||
TABLE_NAME = tableName;
|
||||
mDatabaseOpenHelper = new DatabaseHelper(GlobalObject.getAbilitySlice());
|
||||
StoreConfig cfg = StoreConfig.newDefaultConfig(DATABASE_NAME);
|
||||
mDatabase = mDatabaseOpenHelper.getRdbStore(cfg, DATABASE_VERSION, rdbOpenCallback, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getTableName() {
|
||||
return DATABASE_NAME + "." + TABLE_NAME;
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if (mDatabase != null) {
|
||||
mDatabaseOpenHelper.deleteRdbStore(DATABASE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setItem(String key, String value) {
|
||||
ValuesBucket valuesBucket = new ValuesBucket();
|
||||
valuesBucket.putString("key", key);
|
||||
valuesBucket.putString("value", value);
|
||||
mDatabase.insert(TABLE_NAME, valuesBucket);
|
||||
}
|
||||
|
||||
public static String getItem(String key) {
|
||||
String[] columes = new String[] {"value"};
|
||||
RdbPredicates rdbPredicates = new RdbPredicates(TABLE_NAME).equalTo("key", key);
|
||||
ResultSet resultSet = mDatabase.query(rdbPredicates, columes);
|
||||
if(resultSet.goToNextRow()) {
|
||||
return resultSet.getString(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void removeItem(String key) {
|
||||
RdbPredicates rdbPredicates = new RdbPredicates(TABLE_NAME).equalTo("key", key);
|
||||
mDatabase.delete(rdbPredicates);
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
RdbPredicates rdbPredicates = new RdbPredicates(TABLE_NAME);
|
||||
mDatabase.delete(rdbPredicates);
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
public static String getKey(int nIndex) {
|
||||
|
||||
ResultSet result = mDatabase.querySql("SELECT key from "+TABLE_NAME + " LIMIT 1 OFFSET " + nIndex, null);
|
||||
if(result.goToNextRow()){
|
||||
return result.getString(result.getColumnIndexForName("key"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getLength() {
|
||||
ResultSet result = mDatabase.querySql("SELECT count(key) as cnt FROM "+TABLE_NAME, null);
|
||||
if(result.goToNextRow()) {
|
||||
return result.getInt(result.getColumnIndexForName("cnt"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||
*
|
||||
* http://www.cocos.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.app.Context;
|
||||
import ohos.sensor.agent.CategoryOrientationAgent;
|
||||
import ohos.sensor.agent.SensorAgent;
|
||||
import ohos.sensor.bean.CategoryOrientation;
|
||||
import ohos.sensor.data.CategoryOrientationData;
|
||||
import ohos.sensor.listener.ICategoryOrientationDataCallback;
|
||||
|
||||
public class CocosOrientationHelper implements ICategoryOrientationDataCallback {
|
||||
|
||||
private int mCurrentOrientation;
|
||||
private CategoryOrientationAgent agent;
|
||||
private CategoryOrientation orientation;
|
||||
|
||||
private final int matrix_length = 9;
|
||||
private final int rotationVectorLength = 9;
|
||||
|
||||
public CocosOrientationHelper(Context context) {
|
||||
agent = new CategoryOrientationAgent();
|
||||
orientation = agent.getSingleSensor(CategoryOrientation.SENSOR_TYPE_ORIENTATION);
|
||||
mCurrentOrientation = CocosHelper.getDeviceRotation();
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
agent.releaseSensorDataCallback(this, orientation);
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
boolean ok = agent.setSensorDataCallback(this, orientation, SensorAgent.SENSOR_SAMPLING_RATE_GAME);
|
||||
}
|
||||
|
||||
|
||||
private static native void nativeOnOrientationChanged(int rotation);
|
||||
|
||||
@Override
|
||||
public void onSensorDataModified(CategoryOrientationData data) {
|
||||
final int curOrientation = CocosHelper.getDeviceRotation();
|
||||
if (curOrientation != mCurrentOrientation) {
|
||||
mCurrentOrientation = curOrientation;
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeOnOrientationChanged(mCurrentOrientation);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyDataModified(CategoryOrientation categoryOrientation, int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandCompleted(CategoryOrientation categoryOrientation) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2016 cocos2d-x.org
|
||||
Copyright (c) 2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class CocosReflectionHelper {
|
||||
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "CocosReflection");
|
||||
public static <T> T getConstantValue(final Class aClass, final String constantName) {
|
||||
try {
|
||||
return (T)aClass.getDeclaredField(constantName).get(null);
|
||||
} catch (NoSuchFieldException e) {
|
||||
HiLog.error(LABEL, "can not find " + constantName + " in " + aClass.getName());
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
HiLog.error(LABEL, constantName + " is not accessable");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
HiLog.error(LABEL, "arguments error when get " + constantName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
HiLog.error(LABEL, "can not get constant" + constantName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
public static <T> T invokeInstanceMethod(final Object instance, final String methodName,
|
||||
final Class[] parameterTypes, final Object[] parameters) {
|
||||
|
||||
final Class aClass = instance.getClass();
|
||||
try {
|
||||
final Method method = aClass.getMethod(methodName, parameterTypes);
|
||||
return (T)method.invoke(instance, parameters);
|
||||
} catch (NoSuchMethodException e) {
|
||||
HiLog.error(LABEL, "can not find " + methodName + " in " + aClass.getName());
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
HiLog.error(LABEL, methodName + " is not accessible");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
HiLog.error(LABEL, "arguments are error when invoking " + methodName);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
HiLog.error(LABEL, "an exception was thrown by the invoked method when invoking " + methodName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2013 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.sensor.agent.CategoryMotionAgent;
|
||||
import ohos.sensor.agent.SensorAgent;
|
||||
import ohos.sensor.bean.CategoryMotion;
|
||||
import ohos.sensor.data.CategoryMotionData;
|
||||
import ohos.sensor.listener.ICategoryMotionDataCallback;
|
||||
|
||||
public class CocosSensorHandler implements ICategoryMotionDataCallback {
|
||||
// ===========================================================
|
||||
// Constants
|
||||
// ===========================================================
|
||||
|
||||
private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0, "CocosSensorHandler");
|
||||
private static CocosSensorHandler mSensorHandler;
|
||||
|
||||
private final CategoryMotionAgent mSensorManager;
|
||||
private final CategoryMotion mAcceleration;
|
||||
private final CategoryMotion mAccelerationIncludingGravity;
|
||||
private final CategoryMotion mGyroscope;
|
||||
private static float[] sDeviceMotionValues = new float[9];
|
||||
private boolean mEnabled = false;
|
||||
private long mMaxIntervalNanoSeconds = 0;
|
||||
// ===========================================================
|
||||
// Constructors
|
||||
// ===========================================================
|
||||
|
||||
public CocosSensorHandler() {
|
||||
mSensorManager = new CategoryMotionAgent();
|
||||
mAcceleration = mSensorManager.getSingleSensor(CategoryMotion.SENSOR_TYPE_ACCELEROMETER);
|
||||
mAccelerationIncludingGravity = mSensorManager.getSingleSensor(CategoryMotion.SENSOR_TYPE_LINEAR_ACCELERATION);
|
||||
mGyroscope = mSensorManager.getSingleSensor(CategoryMotion.SENSOR_TYPE_GYROSCOPE);
|
||||
mSensorHandler = this;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Getter & Setter
|
||||
// ===========================================================
|
||||
public void enable() {
|
||||
if(mMaxIntervalNanoSeconds == 0) {
|
||||
mSensorManager.setSensorDataCallback(this, mAcceleration, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST);
|
||||
mSensorManager.setSensorDataCallback(this, mAccelerationIncludingGravity, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST);
|
||||
mSensorManager.setSensorDataCallback(this, mGyroscope, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST);
|
||||
}else {
|
||||
mSensorManager.setSensorDataCallback(this, mAcceleration, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST, mMaxIntervalNanoSeconds);
|
||||
mSensorManager.setSensorDataCallback(this, mAccelerationIncludingGravity, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST, mMaxIntervalNanoSeconds);
|
||||
mSensorManager.setSensorDataCallback(this, mGyroscope, SensorAgent.SENSOR_SAMPLING_RATE_FASTEST, mMaxIntervalNanoSeconds);
|
||||
}
|
||||
mEnabled = true;
|
||||
}
|
||||
|
||||
|
||||
public void disable() {
|
||||
mSensorManager.releaseSensorDataCallback(this, mAcceleration);
|
||||
mSensorManager.releaseSensorDataCallback(this, mAccelerationIncludingGravity);
|
||||
mSensorManager.releaseSensorDataCallback(this, mGyroscope);
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
public void setInterval(float intervalSeconds) {
|
||||
mMaxIntervalNanoSeconds = (long)(1000_000_000L * intervalSeconds);
|
||||
if(mEnabled) {
|
||||
disable();
|
||||
enable();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPause() {
|
||||
disable();
|
||||
}
|
||||
|
||||
public void onResume() {
|
||||
enable();
|
||||
}
|
||||
|
||||
public static void setAccelerometerInterval(float interval) {
|
||||
mSensorHandler.setInterval(interval);
|
||||
}
|
||||
|
||||
public static void setAccelerometerEnabled(boolean enabled) {
|
||||
if(enabled == mSensorHandler.mEnabled) {
|
||||
return;
|
||||
}
|
||||
if (enabled) {
|
||||
mSensorHandler.enable();
|
||||
} else {
|
||||
mSensorHandler.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static float[] getDeviceMotionValue() {
|
||||
return sDeviceMotionValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorDataModified(CategoryMotionData sensorEvent) {
|
||||
CategoryMotion type = sensorEvent.getSensor();
|
||||
if(type == null) return;
|
||||
final int sensorId = type.getSensorId();
|
||||
if (sensorId == mAcceleration.getSensorId()) {
|
||||
sDeviceMotionValues[0] = sensorEvent.values[0];
|
||||
sDeviceMotionValues[1] = sensorEvent.values[1];
|
||||
// Issue https://github.com/cocos-creator/2d-tasks/issues/2532
|
||||
// use negative event.acceleration.z to match iOS value
|
||||
sDeviceMotionValues[2] = -sensorEvent.values[2];
|
||||
} else if (sensorId == mAccelerationIncludingGravity.getSensorId()) {
|
||||
sDeviceMotionValues[3] = sensorEvent.values[0];
|
||||
sDeviceMotionValues[4] = sensorEvent.values[1];
|
||||
sDeviceMotionValues[5] = sensorEvent.values[2];
|
||||
} else if (sensorId == mGyroscope.getSensorId()) {
|
||||
// The unit is rad/s, need to be converted to deg/s
|
||||
sDeviceMotionValues[6] = (float) Math.toDegrees(sensorEvent.values[0]);
|
||||
sDeviceMotionValues[7] = (float) Math.toDegrees(sensorEvent.values[1]);
|
||||
sDeviceMotionValues[8] = (float) Math.toDegrees(sensorEvent.values[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyDataModified(CategoryMotion categoryMotion, int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandCompleted(CategoryMotion categoryMotion) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2013 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.multimodalinput.event.MmiPoint;
|
||||
import ohos.multimodalinput.event.TouchEvent;
|
||||
|
||||
public class CocosTouchHandler {
|
||||
public final static HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP,0, "CocosTouchHandler");
|
||||
private boolean mStopHandleTouchAndKeyEvents = false;
|
||||
|
||||
public CocosTouchHandler() {
|
||||
|
||||
}
|
||||
|
||||
boolean onTouchEvent(TouchEvent pMotionEvent) {
|
||||
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||
final int pointerNumber = pMotionEvent.getPointerCount();
|
||||
final int[] ids = new int[pointerNumber];
|
||||
final float[] xs = new float[pointerNumber];
|
||||
final float[] ys = new float[pointerNumber];
|
||||
|
||||
for (int i = 0; i < pointerNumber; i++) {
|
||||
ids[i] = pMotionEvent.getPointerId(i);
|
||||
MmiPoint pos = pMotionEvent.getPointerPosition(i);
|
||||
xs[i] = pos.getX();
|
||||
ys[i] = pos.getY();
|
||||
}
|
||||
|
||||
int action = pMotionEvent.getAction();
|
||||
|
||||
HiLog.debug(TAG, "Touch event: " + action);
|
||||
switch (action) {
|
||||
case TouchEvent.PRIMARY_POINT_DOWN:
|
||||
case TouchEvent.OTHER_POINT_DOWN:
|
||||
if (mStopHandleTouchAndKeyEvents) {
|
||||
// Cocos2dxEditBox.complete();
|
||||
return true;
|
||||
}
|
||||
|
||||
final int indexPointerDown = pMotionEvent.getIndex();
|
||||
final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
|
||||
MmiPoint pos = pMotionEvent.getPointerPosition(indexPointerDown);
|
||||
final float xPointerDown = pos.getX();
|
||||
final float yPointerDown = pos.getY();
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleActionDown(idPointerDown, xPointerDown, yPointerDown);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case TouchEvent.POINT_MOVE:
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleActionMove(ids, xs, ys);
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case TouchEvent.PRIMARY_POINT_UP:
|
||||
case TouchEvent.OTHER_POINT_UP:
|
||||
|
||||
final int indexPointUp = pMotionEvent.getIndex();
|
||||
final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
|
||||
MmiPoint posUP = pMotionEvent.getPointerPosition(indexPointUp);
|
||||
final float xPointerUp = posUP.getX();
|
||||
final float yPointerUp = posUP.getY();
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleActionUp(idPointerUp, xPointerUp, yPointerUp);
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case TouchEvent.CANCEL:
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleActionCancel(ids, xs, ys);
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
HiLog.debug(TAG, "Unhandled touch event: " + action);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
public void setStopHandleTouchAndKeyEvents(boolean value) {
|
||||
mStopHandleTouchAndKeyEvents = value;
|
||||
}
|
||||
|
||||
native void handleActionDown(final int id, final float x, final float y);
|
||||
|
||||
native void handleActionMove(final int[] ids, final float[] xPointerList, final float[] yPointerList);
|
||||
|
||||
native void handleActionUp(final int id, final float x, final float y);
|
||||
|
||||
native void handleActionCancel(final int[] ids, final float[] xPointerList, final float[] yPointerList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
import com.cocos.lib.CocosVideoView.OnVideoEventListener;
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
import ohos.agp.components.Component;
|
||||
import ohos.agp.components.StackLayout;
|
||||
import ohos.eventhandler.EventHandler;
|
||||
import ohos.eventhandler.EventRunner;
|
||||
import ohos.eventhandler.InnerEvent;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.media.image.common.Rect;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class CocosVideoHelper {
|
||||
|
||||
private StackLayout mRootLayout = null;
|
||||
private AbilitySlice mActivity = null;
|
||||
private static WeakHashMap<Integer, CocosVideoView> sVideoViews = null;
|
||||
static VideoHandler mVideoHandler = null;
|
||||
|
||||
private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0, "CocosVideoHelper");
|
||||
|
||||
CocosVideoHelper(AbilitySlice activity, StackLayout layout)
|
||||
{
|
||||
mActivity = activity;
|
||||
mRootLayout = layout;
|
||||
|
||||
mVideoHandler = new VideoHandler(this);
|
||||
sVideoViews = new WeakHashMap<>();
|
||||
}
|
||||
|
||||
private static int videoTag = 0;
|
||||
private final static int VideoTaskCreate = 0;
|
||||
private final static int VideoTaskRemove = 1;
|
||||
private final static int VideoTaskSetSource = 2;
|
||||
private final static int VideoTaskSetRect = 3;
|
||||
private final static int VideoTaskStart = 4;
|
||||
private final static int VideoTaskPause = 5;
|
||||
private final static int VideoTaskResume = 6;
|
||||
private final static int VideoTaskStop = 7;
|
||||
private final static int VideoTaskSeek = 8;
|
||||
private final static int VideoTaskSetVisible = 9;
|
||||
private final static int VideoTaskRestart = 10;
|
||||
private final static int VideoTaskKeepRatio = 11;
|
||||
private final static int VideoTaskFullScreen = 12;
|
||||
private final static int VideoTaskSetVolume = 13;
|
||||
|
||||
final static int KeyEventBack = 1000;
|
||||
|
||||
static class VideoHandler extends EventHandler {
|
||||
WeakReference<CocosVideoHelper> mReference;
|
||||
|
||||
VideoHandler(CocosVideoHelper helper){
|
||||
super(EventRunner.getMainEventRunner());
|
||||
mReference = new WeakReference<CocosVideoHelper>(helper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEvent(InnerEvent event) {
|
||||
CocosVideoHelper helper = mReference.get();
|
||||
Message msg = (Message) event.object;
|
||||
switch (msg.what) {
|
||||
case VideoTaskCreate: {
|
||||
helper._createVideoView(msg.arg1);
|
||||
break;
|
||||
}
|
||||
case VideoTaskRemove: {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._removeVideoView(msg.arg1));
|
||||
break;
|
||||
}
|
||||
case VideoTaskSetSource: {
|
||||
helper._setVideoURL(msg.arg1, msg.arg2, (String)msg.obj);
|
||||
break;
|
||||
}
|
||||
case VideoTaskStart: {
|
||||
helper._startVideo(msg.arg1);
|
||||
break;
|
||||
}
|
||||
case VideoTaskSetRect: {
|
||||
Rect rect = (Rect)msg.obj;
|
||||
CocosHelper.ruOnUIThreadSync(
|
||||
()->helper._setVideoRect(msg.arg1, rect.minX, rect.minY, rect.width , rect.height)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case VideoTaskFullScreen:{
|
||||
if (msg.arg2 == 1) {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setFullScreenEnabled(msg.arg1, true));
|
||||
} else {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setFullScreenEnabled(msg.arg1, false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VideoTaskPause: {
|
||||
helper._pauseVideo(msg.arg1);
|
||||
break;
|
||||
}
|
||||
|
||||
case VideoTaskStop: {
|
||||
helper._stopVideo(msg.arg1);
|
||||
break;
|
||||
}
|
||||
case VideoTaskSeek: {
|
||||
helper._seekVideoTo(msg.arg1, msg.arg2);
|
||||
break;
|
||||
}
|
||||
case VideoTaskSetVisible: {
|
||||
if (msg.arg2 == 1) {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setVideoVisible(msg.arg1, true));
|
||||
} else {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setVideoVisible(msg.arg1, false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VideoTaskKeepRatio: {
|
||||
if (msg.arg2 == 1) {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setVideoKeepRatio(msg.arg1, true));
|
||||
} else {
|
||||
CocosHelper.ruOnUIThreadSync(()->helper._setVideoKeepRatio(msg.arg1, false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KeyEventBack: {
|
||||
helper.onBackKeyEvent();
|
||||
break;
|
||||
}
|
||||
case VideoTaskSetVolume: {
|
||||
float volume = (float) msg.arg2 / 10;
|
||||
helper._setVolume(msg.arg1, volume);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
super.processEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
public static native void nativeExecuteVideoCallback(int index,int event);
|
||||
|
||||
OnVideoEventListener videoEventListener = new OnVideoEventListener() {
|
||||
|
||||
@Override
|
||||
public void onVideoEvent(int tag,int event) {
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeExecuteVideoCallback(tag, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
static class Message {
|
||||
public int what =0;
|
||||
public int arg1 = 0;
|
||||
public int arg2 = 0;
|
||||
public Object obj = null;
|
||||
}
|
||||
|
||||
public static int createVideoWidget() {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskCreate;
|
||||
msg.arg1 = videoTag;
|
||||
dispatchMessage(msg);
|
||||
|
||||
return videoTag++;
|
||||
}
|
||||
|
||||
private static void dispatchMessage(Message msg) {
|
||||
InnerEvent event = InnerEvent.get(msg.what, msg.arg1, msg);
|
||||
mVideoHandler.distributeEvent(event);
|
||||
}
|
||||
|
||||
|
||||
private void _createVideoView(int index) {
|
||||
CocosVideoView videoView = new CocosVideoView(mActivity,index);
|
||||
sVideoViews.put(index, videoView);
|
||||
StackLayout.LayoutConfig lParams = new StackLayout.LayoutConfig(
|
||||
StackLayout.LayoutConfig.MATCH_CONTENT,
|
||||
StackLayout.LayoutConfig.MATCH_CONTENT);
|
||||
CocosHelper.runOnUIThread(()->{
|
||||
mRootLayout.addComponent(videoView, lParams);
|
||||
});
|
||||
videoView.setVideoViewEventListener(videoEventListener);
|
||||
}
|
||||
|
||||
public static void removeVideoWidget(int index){
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskRemove;
|
||||
msg.arg1 = index;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _removeVideoView(int index) {
|
||||
CocosVideoView view = sVideoViews.get(index);
|
||||
if (view != null) {
|
||||
view.stopPlayback();
|
||||
sVideoViews.remove(index);
|
||||
mRootLayout.removeComponent(view);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVideoUrl(int index, int videoSource, String videoUrl) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskSetSource;
|
||||
msg.arg1 = index;
|
||||
msg.arg2 = videoSource;
|
||||
msg.obj = videoUrl;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _setVideoURL(int index, int videoSource, String videoUrl) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
switch (videoSource) {
|
||||
case 0:
|
||||
videoView.setVideoFileName(videoUrl);
|
||||
break;
|
||||
case 1:
|
||||
videoView.setVideoURL(videoUrl);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskSetRect;
|
||||
msg.arg1 = index;
|
||||
msg.obj = new Rect(left, top, maxWidth, maxHeight);
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.setVideoRect(left, top, maxWidth, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setFullScreenEnabled(int index, boolean enabled) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskFullScreen;
|
||||
msg.arg1 = index;
|
||||
if (enabled) {
|
||||
msg.arg2 = 1;
|
||||
} else {
|
||||
msg.arg2 = 0;
|
||||
}
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _setFullScreenEnabled(int index, boolean enabled) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.setFullScreenEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void onBackKeyEvent() {
|
||||
for(Integer key : sVideoViews.keySet()) {
|
||||
CocosVideoView videoView = sVideoViews.get(key);
|
||||
if (videoView != null) {
|
||||
videoView.setFullScreenEnabled(false);
|
||||
CocosHelper.runOnGameThreadAtForeground(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeExecuteVideoCallback(key, KeyEventBack);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startVideo(int index) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskStart;
|
||||
msg.arg1 = index;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _startVideo(int index) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void pauseVideo(int index) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskPause;
|
||||
msg.arg1 = index;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _pauseVideo(int index) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.pause();
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopVideo(int index) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskStop;
|
||||
msg.arg1 = index;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _stopVideo(int index) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static void seekVideoTo(int index,int msec) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskSeek;
|
||||
msg.arg1 = index;
|
||||
msg.arg2 = msec;
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _seekVideoTo(int index,int msec) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.seekTo(msec);
|
||||
}
|
||||
}
|
||||
|
||||
public static float getCurrentTime(final int index) {
|
||||
CocosVideoView video = sVideoViews.get(index);
|
||||
float currentPosition = -1;
|
||||
if (video != null) {
|
||||
currentPosition = video.getCurrentPosition() / 1000.0f;
|
||||
}
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
public static float getDuration(final int index) {
|
||||
CocosVideoView video = sVideoViews.get(index);
|
||||
float duration = -1;
|
||||
if (video != null) {
|
||||
duration = video.getDuration() / 1000.0f;
|
||||
}
|
||||
if (duration <= 0) {
|
||||
HiLog.error(LABEL, "Video player's duration is not ready to get now!");
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
public static void setVideoVisible(int index, boolean visible) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskSetVisible;
|
||||
msg.arg1 = index;
|
||||
if (visible) {
|
||||
msg.arg2 = 1;
|
||||
} else {
|
||||
msg.arg2 = 0;
|
||||
}
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _setVideoVisible(int index, boolean visible) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
if (visible) {
|
||||
videoView.fixSizeAsync();
|
||||
videoView.setVisibility(Component.VISIBLE);
|
||||
} else {
|
||||
videoView.setVisibility(Component.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVideoKeepRatioEnabled(int index, boolean enable) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskKeepRatio;
|
||||
msg.arg1 = index;
|
||||
if (enable) {
|
||||
msg.arg2 = 1;
|
||||
} else {
|
||||
msg.arg2 = 0;
|
||||
}
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
|
||||
private void _setVideoKeepRatio(int index, boolean enable) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.setKeepRatio(enable);
|
||||
}
|
||||
}
|
||||
|
||||
private void _setVolume(final int index, final float volume) {
|
||||
CocosVideoView videoView = sVideoViews.get(index);
|
||||
if (videoView != null) {
|
||||
videoView.setVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setVolume(final int index, final float volume) {
|
||||
Message msg = new Message();
|
||||
msg.what = VideoTaskSetVolume;
|
||||
msg.arg1 = index;
|
||||
msg.arg2 = (int) (volume * 10);
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,634 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
* Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
import ohos.aafwk.ability.Lifecycle;
|
||||
import ohos.aafwk.ability.LifecycleStateObserver;
|
||||
import ohos.aafwk.content.Intent;
|
||||
import ohos.agp.components.Component;
|
||||
import ohos.agp.components.StackLayout;
|
||||
import ohos.agp.components.surfaceprovider.SurfaceProvider;
|
||||
import ohos.agp.graphics.SurfaceOps;
|
||||
import ohos.agp.utils.Rect;
|
||||
import ohos.agp.window.dialog.BaseDialog;
|
||||
import ohos.agp.window.dialog.PopupDialog;
|
||||
import ohos.agp.window.dialog.ToastDialog;
|
||||
import ohos.global.resource.RawFileDescriptor;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
import ohos.media.audio.AudioManager;
|
||||
import ohos.media.common.Source;
|
||||
import ohos.media.player.Player;
|
||||
import ohos.multimodalinput.event.TouchEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class CocosVideoView extends SurfaceProvider implements Component.TouchEventListener, LifecycleStateObserver {
|
||||
|
||||
// ===========================================================
|
||||
// Internal classes and interfaces.
|
||||
// ===========================================================
|
||||
|
||||
public interface OnVideoEventListener {
|
||||
void onVideoEvent(int tag, int event);
|
||||
}
|
||||
|
||||
private enum State {
|
||||
IDLE,
|
||||
ERROR,
|
||||
INITIALIZED,
|
||||
PREPARING,
|
||||
PREPARED,
|
||||
STARTED,
|
||||
PAUSED,
|
||||
STOPPED,
|
||||
PLAYBACK_COMPLETED,
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Constants
|
||||
// ===========================================================
|
||||
private static final String AssetResourceRoot = "@assets/";
|
||||
private static final String OHOSResourceRoot = "entry/resources/rawfile/";
|
||||
|
||||
// ===========================================================
|
||||
// Fields
|
||||
// ===========================================================
|
||||
|
||||
private HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0, "CocosVideoView");
|
||||
|
||||
private Source mVideoUri;
|
||||
private int mDuration;
|
||||
private int mPosition;
|
||||
|
||||
private State mCurrentState = State.IDLE;
|
||||
|
||||
// All the stuff we need for playing and showing a video
|
||||
private Player mMediaPlayer = null;
|
||||
private int mVideoWidth = 0;
|
||||
private int mVideoHeight = 0;
|
||||
|
||||
private OnVideoEventListener mOnVideoEventListener;
|
||||
|
||||
// recording the seek position while preparing
|
||||
private int mSeekWhenPrepared = 0;
|
||||
|
||||
protected AbilitySlice mAbility = null;
|
||||
|
||||
protected int mViewLeft = 0;
|
||||
protected int mViewTop = 0;
|
||||
protected int mViewWidth = 0;
|
||||
protected int mViewHeight = 0;
|
||||
|
||||
protected int mVisibleLeft = 0;
|
||||
protected int mVisibleTop = 0;
|
||||
protected int mVisibleWidth = 0;
|
||||
protected int mVisibleHeight = 0;
|
||||
|
||||
protected boolean mFullScreenEnabled = false;
|
||||
|
||||
private boolean mIsAssetRouse = false;
|
||||
private String mVideoFilePath = null;
|
||||
|
||||
private int mViewTag = 0;
|
||||
private boolean mKeepRatio = false;
|
||||
private boolean mMetaUpdated = false;
|
||||
|
||||
// MediaPlayer will be released when surface view is destroyed, so should record the position,
|
||||
// and use it to play after MedialPlayer is created again.
|
||||
private int mPositionBeforeRelease = 0;
|
||||
|
||||
// ===========================================================
|
||||
// Constructors
|
||||
// ===========================================================
|
||||
|
||||
public CocosVideoView(AbilitySlice activity, int tag) {
|
||||
super(activity);
|
||||
|
||||
mViewTag = tag;
|
||||
mAbility = activity;
|
||||
mMediaPlayer = new Player(getContext());
|
||||
mMediaPlayer.setPlayerCallback(mPlayerCallback);
|
||||
initVideoView();
|
||||
|
||||
pinToZTop(true);
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Getter & Setter
|
||||
// ===========================================================
|
||||
|
||||
public void setVideoRect(int left, int top, int maxWidth, int maxHeight) {
|
||||
if (mViewLeft == left && mViewTop == top && mViewWidth == maxWidth && mViewHeight == maxHeight)
|
||||
return;
|
||||
|
||||
mViewLeft = left;
|
||||
mViewTop = top;
|
||||
mViewWidth = maxWidth;
|
||||
mViewHeight = maxHeight;
|
||||
|
||||
fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);
|
||||
}
|
||||
|
||||
public void setFullScreenEnabled(boolean enabled) {
|
||||
if (mFullScreenEnabled != enabled) {
|
||||
mFullScreenEnabled = enabled;
|
||||
fixSizeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVolume(float volume) {
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer.setVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
public void setKeepRatio(boolean enabled) {
|
||||
mKeepRatio = enabled;
|
||||
fixSizeAsync();
|
||||
}
|
||||
|
||||
public void setVideoURL(String url) {
|
||||
mIsAssetRouse = false;
|
||||
setVideoURI(new Source(url), null);
|
||||
}
|
||||
|
||||
public void setVideoFileName(String path) {
|
||||
if (path.startsWith(AssetResourceRoot)) {
|
||||
path = path.replaceFirst(AssetResourceRoot, OHOSResourceRoot);
|
||||
}
|
||||
|
||||
if (path.startsWith("/")) {
|
||||
mIsAssetRouse = false;
|
||||
setVideoURI(new Source(path), null);
|
||||
} else {
|
||||
|
||||
mVideoFilePath = path;
|
||||
mIsAssetRouse = true;
|
||||
setVideoURI(new Source(path), null);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentPosition() {
|
||||
if (!(mCurrentState == State.IDLE ||
|
||||
mCurrentState == State.ERROR ||
|
||||
mCurrentState == State.INITIALIZED ||
|
||||
mCurrentState == State.STOPPED ||
|
||||
mMediaPlayer == null)) {
|
||||
mPosition = mMediaPlayer.getCurrentTime();
|
||||
}
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
if (!(mCurrentState == State.IDLE ||
|
||||
mCurrentState == State.ERROR ||
|
||||
mCurrentState == State.INITIALIZED ||
|
||||
mCurrentState == State.STOPPED ||
|
||||
mMediaPlayer == null)) {
|
||||
mDuration = mMediaPlayer.getDuration();
|
||||
}
|
||||
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be invoked when some video event triggered.
|
||||
*
|
||||
* @param l The callback that will be run
|
||||
*/
|
||||
public void setVideoViewEventListener(OnVideoEventListener l) {
|
||||
mOnVideoEventListener = l;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Overrides
|
||||
// ===========================================================
|
||||
|
||||
@Override
|
||||
public void setVisibility(int visibility) {
|
||||
super.setVisibility(visibility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
|
||||
if ((touchEvent.getAction() & TouchEvent.PRIMARY_POINT_UP) == TouchEvent.PRIMARY_POINT_UP) {
|
||||
this.sendEvent(EVENT_CLICKED);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Public functions
|
||||
// ===========================================================
|
||||
|
||||
public void stop() {
|
||||
if (!(mCurrentState == State.IDLE || mCurrentState == State.INITIALIZED || mCurrentState == State.ERROR || mCurrentState == State.STOPPED)
|
||||
&& mMediaPlayer != null) {
|
||||
mCurrentState = State.STOPPED;
|
||||
mMediaPlayer.stop();
|
||||
this.sendEvent(EVENT_STOPPED);
|
||||
|
||||
// after the video is stop, it shall prepare to be playable again
|
||||
try {
|
||||
mMediaPlayer.prepare();
|
||||
this.showFirstFrame();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopPlayback() {
|
||||
this.removeFromWindow();
|
||||
this.release();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if ((mCurrentState == State.PREPARED ||
|
||||
mCurrentState == State.PAUSED ||
|
||||
mCurrentState == State.PLAYBACK_COMPLETED) &&
|
||||
mMediaPlayer != null) {
|
||||
|
||||
mCurrentState = State.STARTED;
|
||||
mMediaPlayer.play();
|
||||
this.sendEvent(EVENT_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if ((mCurrentState == State.STARTED || mCurrentState == State.PLAYBACK_COMPLETED) &&
|
||||
mMediaPlayer != null) {
|
||||
mCurrentState = State.PAUSED;
|
||||
mMediaPlayer.pause();
|
||||
this.sendEvent(EVENT_PAUSED);
|
||||
}
|
||||
}
|
||||
|
||||
public void seekTo(int ms) {
|
||||
if (mCurrentState == State.IDLE || mCurrentState == State.INITIALIZED ||
|
||||
mCurrentState == State.STOPPED || mCurrentState == State.ERROR ||
|
||||
mMediaPlayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean rewindResult = mMediaPlayer.rewindTo(ms * 1000);
|
||||
System.out.println("Player seek to " + ms + "ms, " + getCurrentPosition() + "ms/"+getDuration() + "ms, rewind result "+ rewindResult);
|
||||
}
|
||||
|
||||
public void fixSizeAsync() {
|
||||
CocosHelper.ruOnUIThreadSync(this::fixSizeUIThread);
|
||||
}
|
||||
|
||||
private void fixSizeUIThread() {
|
||||
if (mFullScreenEnabled) {
|
||||
Rect rect = mAbility.getWindow().getBoundRect();
|
||||
fixSize(rect.left, rect.top, rect.getWidth(), rect.getHeight());
|
||||
} else {
|
||||
if(mViewWidth == 0 || mViewHeight == 0) {
|
||||
CocosHelper.runOnUIThread(this::fixSizeUIThread, true);
|
||||
return;
|
||||
}
|
||||
fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public void fixSize(int left, int top, int width, int height) {
|
||||
if (mVideoWidth == 0 || mVideoHeight == 0) {
|
||||
mVisibleLeft = left;
|
||||
mVisibleTop = top;
|
||||
mVisibleWidth = width;
|
||||
mVisibleHeight = height;
|
||||
} else if (width != 0 && height != 0) {
|
||||
if (mKeepRatio && !mFullScreenEnabled) {
|
||||
if (mVideoWidth * height > width * mVideoHeight) {
|
||||
mVisibleWidth = width;
|
||||
mVisibleHeight = width * mVideoHeight / mVideoWidth;
|
||||
} else if (mVideoWidth * height < width * mVideoHeight) {
|
||||
mVisibleWidth = height * mVideoWidth / mVideoHeight;
|
||||
mVisibleHeight = height;
|
||||
}
|
||||
mVisibleLeft = left + (width - mVisibleWidth) / 2;
|
||||
mVisibleTop = top + (height - mVisibleHeight) / 2;
|
||||
} else {
|
||||
mVisibleLeft = left;
|
||||
mVisibleTop = top;
|
||||
mVisibleWidth = width;
|
||||
mVisibleHeight = height;
|
||||
}
|
||||
} else {
|
||||
mVisibleLeft = left;
|
||||
mVisibleTop = top;
|
||||
mVisibleWidth = mVideoWidth;
|
||||
mVisibleHeight = mVideoHeight;
|
||||
}
|
||||
|
||||
setComponentSize(mVideoWidth, mVideoHeight);
|
||||
|
||||
StackLayout.LayoutConfig lParams = new StackLayout.LayoutConfig(StackLayout.LayoutConfig.MATCH_CONTENT,
|
||||
StackLayout.LayoutConfig.MATCH_CONTENT);
|
||||
lParams.setMarginLeft(mVisibleLeft);
|
||||
lParams.setMarginTop(mVisibleTop);
|
||||
lParams.width = mVisibleWidth;
|
||||
lParams.height = mVisibleHeight;
|
||||
setLayoutConfig(lParams);
|
||||
}
|
||||
|
||||
public int resolveAdjustedSize(int desiredSize, int measureSpec) {
|
||||
int result = desiredSize;
|
||||
int specMode = EstimateSpec.getMode(measureSpec);
|
||||
int specSize = EstimateSpec.getSize(measureSpec);
|
||||
|
||||
switch (specMode) {
|
||||
case EstimateSpec.UNCONSTRAINT:
|
||||
/* Parent says we can be as big as we want. Just don't be larger
|
||||
* than max size imposed on ourselves.
|
||||
*/
|
||||
result = desiredSize;
|
||||
break;
|
||||
|
||||
case EstimateSpec.NOT_EXCEED:
|
||||
/* Parent says we can be as big as we want, up to specSize.
|
||||
* Don't be larger than specSize, and don't be larger than
|
||||
* the max size imposed on ourselves.
|
||||
*/
|
||||
result = Math.min(desiredSize, specSize);
|
||||
break;
|
||||
|
||||
case EstimateSpec.PRECISE:
|
||||
// No choice. Do what we are told.
|
||||
result = specSize;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Private functions
|
||||
// ===========================================================
|
||||
|
||||
private void initVideoView() {
|
||||
mVideoWidth = 0;
|
||||
mVideoHeight = 0;
|
||||
if(this.getSurfaceOps().isPresent()) {
|
||||
getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceOps surfaceOps) {
|
||||
CocosVideoView.this.mMediaPlayer.setVideoSurface(surfaceOps.getSurface());
|
||||
openVideo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
|
||||
CocosVideoView.this.mMediaPlayer.setVideoSurface(surfaceOps.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceOps surfaceOps) {
|
||||
// after we return from this we can't use the surface any more
|
||||
mPositionBeforeRelease = getCurrentPosition();
|
||||
CocosVideoView.this.doRelease();
|
||||
}
|
||||
});
|
||||
}
|
||||
mCurrentState = State.IDLE;
|
||||
setTouchEventListener(this);
|
||||
setFocusable(FOCUS_ADAPTABLE);
|
||||
setTouchFocusable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
private void setVideoURI(Source uri, Map<String, String> headers) {
|
||||
mVideoUri = uri;
|
||||
mVideoWidth = 0;
|
||||
mVideoHeight = 0;
|
||||
}
|
||||
|
||||
private void openVideo() {
|
||||
if (!getSurfaceOps().isPresent() || getSurfaceOps().get().getSurface() == null) {
|
||||
// not ready for playback just yet, will try again later
|
||||
return;
|
||||
}
|
||||
if (mIsAssetRouse) {
|
||||
if (mVideoFilePath == null)
|
||||
return;
|
||||
} else if (mVideoUri == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this.pausePlaybackService();
|
||||
|
||||
try {
|
||||
mMediaPlayer.setSurfaceOps(getSurfaceOps().get());
|
||||
// mMediaPlayer.setAudioStreamType(AudioManager.AudioVolumeType.STREAM_MUSIC.getValue());
|
||||
getSurfaceOps().get().setKeepScreenOn(true);
|
||||
|
||||
if (mIsAssetRouse) {
|
||||
RawFileDescriptor afd = mAbility.getResourceManager().getRawFileEntry(mVideoFilePath).openRawFileDescriptor();
|
||||
mMediaPlayer.setSource(afd);
|
||||
} else {
|
||||
mMediaPlayer.setSource(mVideoUri);
|
||||
}
|
||||
mCurrentState = State.INITIALIZED;
|
||||
|
||||
|
||||
// Use Prepare() instead of PrepareAsync to make things easy.
|
||||
// CompletableFuture.runAsync(()->{
|
||||
mMediaPlayer.prepare();
|
||||
CocosHelper.ruOnUIThreadSync(this::showFirstFrame);
|
||||
// });
|
||||
// mMediaPlayer.prepareAsync();
|
||||
} catch (IOException ex) {
|
||||
HiLog.error(TAG, "Unable to open content: " + mVideoUri + ex);
|
||||
mCurrentState = State.ERROR;
|
||||
mPlayerCallback.onError(Player.PLAYER_ERROR_UNKNOWN, 0);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
HiLog.error(TAG, "Unable to open content: " + mVideoUri + ex);
|
||||
mCurrentState = State.ERROR;
|
||||
mPlayerCallback.onError(Player.PLAYER_ERROR_UNKNOWN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private final Player.IPlayerCallback mPlayerCallback = new Player.IPlayerCallback() {
|
||||
@Override
|
||||
public void onPrepared() {
|
||||
mVideoWidth = mMediaPlayer.getVideoWidth();
|
||||
mVideoHeight = mMediaPlayer.getVideoHeight();
|
||||
|
||||
if (mVideoWidth != 0 && mVideoHeight != 0) {
|
||||
fixSizeAsync();
|
||||
}
|
||||
|
||||
if (!mMetaUpdated) {
|
||||
CocosVideoView.this.sendEvent(EVENT_META_LOADED);
|
||||
CocosVideoView.this.sendEvent(EVENT_READY_TO_PLAY);
|
||||
mMetaUpdated = true;
|
||||
}
|
||||
|
||||
mCurrentState = State.PREPARED;
|
||||
|
||||
if (mPositionBeforeRelease > 0) {
|
||||
CocosVideoView.this.start();
|
||||
CocosVideoView.this.seekTo(mPositionBeforeRelease);
|
||||
mPositionBeforeRelease = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(int i, int i1) {
|
||||
HiLog.debug(TAG, "Message "+ i + ", "+ i1);
|
||||
}
|
||||
|
||||
String translateErrorMessage(int errorType, int errorCode) {
|
||||
String msg = "";
|
||||
switch (errorType) {
|
||||
case Player.PLAYER_ERROR_UNKNOWN:
|
||||
msg += "type: PLAYER_ERROR_UNKNOWN, ";
|
||||
break;
|
||||
case Player.PLAYER_ERROR_SERVER_DIED:
|
||||
msg += "type: PLAYER_ERROR_SERVER_DIED, ";
|
||||
break;
|
||||
default:
|
||||
msg += "type: " + errorType+ ", ";
|
||||
break;
|
||||
}
|
||||
switch (errorCode) {
|
||||
case Player.PLAYER_ERROR_IO:
|
||||
msg += "code: PLAYER_ERROR_IO";
|
||||
break;
|
||||
case Player.PLAYER_ERROR_MALFORMED:
|
||||
msg += "code: PLAYER_ERROR_MALFORMED";
|
||||
break;
|
||||
case Player.PLAYER_ERROR_UNSUPPORTED:
|
||||
msg += "code: PLAYER_ERROR_UNSUPPORTED";
|
||||
break;
|
||||
case Player.PLAYER_ERROR_TIMED_OUT:
|
||||
msg += "code: PLAYER_ERROR_TIMED_OUT";
|
||||
break;
|
||||
case Player.PLAYER_ERROR_SYSTEM:
|
||||
msg += "code: PLAYER_ERROR_SYSTEM";
|
||||
default:
|
||||
msg += "code: " + errorCode+ ", ";
|
||||
break;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int errorType, int errorCode) {
|
||||
mCurrentState = State.ERROR;
|
||||
|
||||
//TODO: i18n
|
||||
CocosHelper.runOnUIThread(()->{
|
||||
ToastDialog dialog = new ToastDialog(getContext());
|
||||
dialog.setText("Video:" + translateErrorMessage(errorType, errorCode));
|
||||
dialog.setDuration(5000);
|
||||
dialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResolutionChanged(int i, int i1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayBackComplete() {
|
||||
mCurrentState = State.PLAYBACK_COMPLETED;
|
||||
CocosVideoView.this.sendEvent(EVENT_COMPLETED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRewindToComplete() {
|
||||
System.out.println("rewind complete");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBufferingChange(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onStateChanged(Lifecycle.Event event, Intent intent) {
|
||||
switch (event) {
|
||||
case ON_START:
|
||||
break;
|
||||
case ON_ACTIVE:
|
||||
mMediaPlayer.play();
|
||||
break;
|
||||
case ON_INACTIVE:
|
||||
mMediaPlayer.pause();
|
||||
break;
|
||||
case ON_BACKGROUND:
|
||||
mMediaPlayer.stop();
|
||||
break;
|
||||
case ON_STOP:
|
||||
mMediaPlayer.release();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static final int EVENT_PLAYING = 0;
|
||||
private static final int EVENT_PAUSED = 1;
|
||||
private static final int EVENT_STOPPED = 2;
|
||||
private static final int EVENT_COMPLETED = 3;
|
||||
private static final int EVENT_META_LOADED = 4;
|
||||
private static final int EVENT_CLICKED = 5;
|
||||
private static final int EVENT_READY_TO_PLAY = 6;
|
||||
|
||||
/*
|
||||
* release the media player in any state
|
||||
*/
|
||||
private void doRelease() {
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer.release();
|
||||
mMediaPlayer = null;
|
||||
mCurrentState = State.IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
private void showFirstFrame() {
|
||||
mMediaPlayer.rewindTo(1);
|
||||
}
|
||||
|
||||
private void sendEvent(int event) {
|
||||
if (this.mOnVideoEventListener != null) {
|
||||
this.mOnVideoEventListener.onVideoEvent(this.mViewTag, event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2017-2021 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.agp.components.PositionLayout;
|
||||
import ohos.agp.components.webengine.*;
|
||||
import ohos.app.Context;
|
||||
import ohos.hiviewdfx.HiLog;
|
||||
import ohos.hiviewdfx.HiLogLabel;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
|
||||
public class CocosWebView extends WebView {
|
||||
private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0, CocosWebViewHelper.class.getSimpleName());
|
||||
|
||||
private int mViewTag;
|
||||
private String mJSScheme;
|
||||
|
||||
public CocosWebView(Context context, int viewTag) {
|
||||
super(context);
|
||||
this.mViewTag = viewTag;
|
||||
this.mJSScheme = "";
|
||||
this.setWebAgent(new Cocos2dxWebViewClient());
|
||||
|
||||
|
||||
WebConfig cfg = getWebConfig();
|
||||
cfg.setJavaScriptPermit(true);
|
||||
cfg.setDataAbilityPermit(true);
|
||||
cfg.setLoadsImagesPermit(true);
|
||||
cfg.setWebStoragePermit(true);
|
||||
cfg.setViewPortFitScreen(true);
|
||||
cfg.setTextAutoSizing(true);
|
||||
|
||||
// setTouchFocusable(true);
|
||||
// setFocusable(FOCUS_ENABLE);
|
||||
// requestFocus();
|
||||
}
|
||||
|
||||
public void setJavascriptInterfaceScheme(String scheme) {
|
||||
this.mJSScheme = scheme != null ? scheme : "";
|
||||
}
|
||||
|
||||
public void setScalesPageToFit(boolean scalesPageToFit) {
|
||||
this.getWebConfig().setViewPortFitScreen(scalesPageToFit);
|
||||
}
|
||||
|
||||
class Cocos2dxWebViewClient extends WebAgent {
|
||||
@Override
|
||||
public boolean isNeedLoadUrl(WebView view, ResourceRequest request) {
|
||||
String urlString = request.getRequestUrl().toString();
|
||||
try {
|
||||
URI uri = new URI(request.getRequestUrl().toString());
|
||||
if (uri.getScheme().equals(mJSScheme)) {
|
||||
CocosHelper.runOnGameThreadAtForeground(
|
||||
() -> CocosWebViewHelper._onJsCallback(mViewTag, urlString)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
HiLog.debug(TAG, "Failed to create URI from url");
|
||||
}
|
||||
|
||||
FutureTask<Boolean> shouldStartLoadingCB = new FutureTask<>(
|
||||
()-> CocosWebViewHelper._shouldStartLoading(mViewTag, urlString)
|
||||
);
|
||||
|
||||
// run worker on cocos thread
|
||||
CocosHelper.runOnGameThreadAtForeground(shouldStartLoadingCB);
|
||||
// wait for result from cocos thread
|
||||
|
||||
try {
|
||||
return shouldStartLoadingCB.get();
|
||||
} catch (InterruptedException ex) {
|
||||
HiLog.debug(TAG, "'shouldOverrideUrlLoading' failed");
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageLoaded(WebView view, final String url) {
|
||||
super.onPageLoaded(view, url);
|
||||
|
||||
CocosHelper.runOnGameThreadAtForeground(
|
||||
() -> CocosWebViewHelper._didFinishLoading(mViewTag, url)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebView view, ResourceRequest request, ResourceError error) {
|
||||
super.onError(view, request, error);
|
||||
final String failingUrl = request.getRequestUrl().toString();
|
||||
CocosHelper.runOnGameThreadAtForeground(
|
||||
() -> CocosWebViewHelper._didFailLoading(mViewTag, failingUrl)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void setWebViewRect(int left, int top, int maxWidth, int maxHeight) {
|
||||
PositionLayout.LayoutConfig layoutParams = new PositionLayout.LayoutConfig(
|
||||
PositionLayout.LayoutConfig.MATCH_CONTENT,
|
||||
PositionLayout.LayoutConfig.MATCH_CONTENT);
|
||||
layoutParams.setMarginLeft(left);
|
||||
layoutParams.setMarginTop(top);
|
||||
layoutParams.width = maxWidth;
|
||||
layoutParams.height = maxHeight;
|
||||
this.setLayoutConfig(layoutParams);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2010-2011 cocos2d-x.org
|
||||
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
|
||||
import ohos.agp.colors.RgbColor;
|
||||
import ohos.agp.components.Component;
|
||||
import ohos.agp.components.DirectionalLayout;
|
||||
import ohos.agp.components.StackLayout;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
|
||||
public class CocosWebViewHelper {
|
||||
private static final String TAG = CocosWebViewHelper.class.getSimpleName();
|
||||
|
||||
private static StackLayout sLayout;
|
||||
|
||||
private static ConcurrentHashMap<Integer, CocosWebView> webViews;
|
||||
private static int viewTag = 0;
|
||||
|
||||
public CocosWebViewHelper(StackLayout layout) {
|
||||
|
||||
CocosWebViewHelper.sLayout = layout;
|
||||
|
||||
CocosWebViewHelper.webViews = new ConcurrentHashMap<Integer, CocosWebView>();
|
||||
}
|
||||
|
||||
private static native boolean shouldStartLoading(int index, String message);
|
||||
private static native void didFinishLoading(int index, String message);
|
||||
private static native void didFailLoading(int index, String message);
|
||||
private static native void onJsCallback(int index, String message);
|
||||
|
||||
public static boolean _shouldStartLoading(int index, String message) { return shouldStartLoading(index, message); }
|
||||
public static void _didFinishLoading(int index, String message) { didFinishLoading(index, message); }
|
||||
public static void _didFailLoading(int index, String message) { didFailLoading(index, message); }
|
||||
public static void _onJsCallback(int index, String message) { onJsCallback(index, message); }
|
||||
|
||||
public static int createWebView() {
|
||||
final int index = viewTag;
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = new CocosWebView(CocosHelper.getContext(), index);
|
||||
DirectionalLayout.LayoutConfig lParams = new DirectionalLayout.LayoutConfig(
|
||||
DirectionalLayout.LayoutConfig.MATCH_CONTENT,
|
||||
DirectionalLayout.LayoutConfig.MATCH_CONTENT);
|
||||
sLayout.addComponent(webView, lParams);
|
||||
|
||||
webViews.put(index, webView);
|
||||
}
|
||||
});
|
||||
return viewTag++;
|
||||
}
|
||||
|
||||
public static void removeWebView(final int index) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webViews.remove(index);
|
||||
sLayout.removeComponent(webView);
|
||||
webView.release();
|
||||
webView = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setVisible(final int index, final boolean visible) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.setVisibility(visible ? Component.VISIBLE : Component.HIDE);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setWebViewRect(final int index, final int left, final int top, final int maxWidth, final int maxHeight) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.setWebViewRect(left, top, maxWidth, maxHeight);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setBackgroundTransparent(final int index, final boolean isTransparent) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
RgbColor color = isTransparent ? new RgbColor(255, 255, 255, 0 ): new RgbColor(255, 255, 255, 255);
|
||||
// Element bg = webView.getResourceManager().getElement(isTransparent ? ResourceTable.Graphic_bg_webview_transparent : ResourceTable.Graphic_bg_webview_white);
|
||||
webView.setWebViewBackground(color);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setJavascriptInterfaceScheme(final int index, final String scheme) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.setJavascriptInterfaceScheme(scheme);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void loadData(final int index, final String data, final String mimeType, final String encoding, final String baseURL) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.load(data, mimeType, encoding, baseURL, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void loadHTMLString(final int index, final String data, final String baseUrl) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.load(data, null, null, baseUrl, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void loadUrl(final int index, final String url) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.load(url);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void loadFile(final int index, final String filePath) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.load(filePath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void stopLoading(final int index) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
// FIXME: stop
|
||||
// webView.abo();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static void reload(final int index) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T callInMainThread(Callable<T> call) throws ExecutionException, InterruptedException {
|
||||
FutureTask<T> task = new FutureTask<T>(call);
|
||||
CocosHelper.runOnUIThread(task);
|
||||
return task.get();
|
||||
}
|
||||
|
||||
public static boolean canGoBack(final int index) throws InterruptedException {
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
return webView != null && webView.getNavigator().canGoBack();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return callInMainThread(callable);
|
||||
} catch (ExecutionException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canGoForward(final int index) throws InterruptedException {
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
return webView != null && webView.getNavigator().canGoForward();
|
||||
}
|
||||
};
|
||||
try {
|
||||
return callInMainThread(callable);
|
||||
} catch (ExecutionException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void goBack(final int index) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.getNavigator().goBack();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void goForward(final int index) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.getNavigator().goForward();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void evaluateJS(final int index, final String js) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
// webView.load("javascript:" + js);
|
||||
webView.executeJs(js, null);;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setScalesPageToFit(final int index, final boolean scalesPageToFit) {
|
||||
CocosHelper.runOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CocosWebView webView = webViews.get(index);
|
||||
if (webView != null) {
|
||||
webView.setScalesPageToFit(scalesPageToFit);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
import ohos.aafwk.ability.AbilitySlice;
|
||||
|
||||
public class GlobalObject {
|
||||
private static AbilitySlice sActivity = null;
|
||||
|
||||
public static void setAbilitySlice(AbilitySlice activity) {
|
||||
GlobalObject.sActivity = activity;
|
||||
}
|
||||
|
||||
public static AbilitySlice getAbilitySlice() {
|
||||
return GlobalObject.sActivity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018-2021 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
public class JsbBridge {
|
||||
public interface ICallback{
|
||||
/**
|
||||
* Applies this callback to the given argument.
|
||||
*
|
||||
* @param arg0 as input
|
||||
* @param arg1 as input
|
||||
*/
|
||||
void onScript(String arg0, String arg1);
|
||||
}
|
||||
private static ICallback callback;
|
||||
|
||||
private static void callByScript(String arg0, String arg1){
|
||||
if(JsbBridge.callback != null)
|
||||
callback.onScript(arg0, arg1);
|
||||
}
|
||||
|
||||
/**Add a callback which you would like to apply
|
||||
* @param f ICallback, the method which will be actually applied. multiple calls will override
|
||||
* */
|
||||
public static void setCallback(ICallback f){
|
||||
JsbBridge.callback = f;
|
||||
}
|
||||
/**
|
||||
* Java dispatch Js event, use native c++ code
|
||||
* @param arg0 input values
|
||||
*/
|
||||
private static native void nativeSendToScript(String arg0, String arg1);
|
||||
public static void sendToScript(String arg0, String arg1){
|
||||
nativeSendToScript(arg0, arg1);
|
||||
}
|
||||
public static void sendToScript(String arg0){
|
||||
nativeSendToScript(arg0, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2018-2021 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated engine source code (the "Software"), a limited,
|
||||
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||
not use Cocos Creator software for developing other software or tools that's
|
||||
used for developing games. You are not granted to publish, distribute,
|
||||
sublicense, and/or sell copies of Cocos Creator.
|
||||
|
||||
The software or tools in this License Agreement are licensed, not sold.
|
||||
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
package com.cocos.lib;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class JsbBridgeWrapper {
|
||||
//Interface for listener, should be implemented and dispatched
|
||||
public interface OnScriptEventListener {
|
||||
void onScriptEvent(String arg);
|
||||
}
|
||||
/**
|
||||
* Get the instance of JsbBridgetWrapper
|
||||
*/
|
||||
public static JsbBridgeWrapper getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new JsbBridgeWrapper();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
/**
|
||||
* Add a listener to specified event, if the event does not exist, the wrapper will create one. Concurrent listener will be ignored
|
||||
*/
|
||||
public void addScriptEventListener(String eventName, OnScriptEventListener listener) {
|
||||
if (eventMap.get(eventName) == null) {
|
||||
eventMap.put(eventName, new ArrayList<OnScriptEventListener>());
|
||||
}
|
||||
eventMap.get(eventName).add(listener);
|
||||
}
|
||||
/**
|
||||
* Remove listener for specified event, concurrent event will be deleted. Return false only if the event does not exist
|
||||
*/
|
||||
public boolean removeScriptEventListener(String eventName, OnScriptEventListener listener) {
|
||||
ArrayList<OnScriptEventListener> arr = eventMap.get(eventName);
|
||||
if (arr == null) {
|
||||
return false;
|
||||
}
|
||||
arr.remove(listener);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Remove all listener for event specified.
|
||||
*/
|
||||
public void removeAllListenersForEvent(String eventName) {
|
||||
this.eventMap.remove(eventName);
|
||||
}
|
||||
/**
|
||||
* Remove all event registered. Use it carefully!
|
||||
*/
|
||||
public void removeAllListeners() {
|
||||
this.eventMap.clear();
|
||||
}
|
||||
/**
|
||||
* Dispatch the event with argument, the event should be registered in javascript, or other script language in future.
|
||||
*/
|
||||
public void dispatchEventToScript(String eventName, String arg) {
|
||||
JsbBridge.sendToScript(eventName, arg);
|
||||
}
|
||||
/**
|
||||
* Dispatch the event which is registered in javascript, or other script language in future.
|
||||
*/
|
||||
public void dispatchEventToScript(String eventName) {
|
||||
JsbBridge.sendToScript(eventName);
|
||||
}
|
||||
|
||||
private JsbBridgeWrapper() {
|
||||
JsbBridge.setCallback(new JsbBridge.ICallback() {
|
||||
@Override
|
||||
public void onScript(String arg0, String arg1) {
|
||||
triggerEvents(arg0, arg1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final HashMap<String, ArrayList<OnScriptEventListener>> eventMap = new HashMap<>();
|
||||
private static JsbBridgeWrapper instance;
|
||||
|
||||
private void triggerEvents(String eventName, String arg) {
|
||||
ArrayList<OnScriptEventListener> arr = eventMap.get(eventName);
|
||||
if (arr == null)
|
||||
return;
|
||||
for (OnScriptEventListener m : arr) {
|
||||
m.onScriptEvent(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
0
cocos/platform/ohos/libcocos/src/main/res/.keep
Normal file
0
cocos/platform/ohos/libcocos/src/main/res/.keep
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "lib_name",
|
||||
"value": "cocos"
|
||||
},
|
||||
{
|
||||
"name": "done",
|
||||
"value": "Done"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:ohos="http://schemas.huawei.com/res/ohos"
|
||||
ohos:shape="rectangle">
|
||||
|
||||
<corners
|
||||
ohos:radius="5"/>
|
||||
|
||||
<solid
|
||||
ohos:width="2"
|
||||
ohos:color="#FFF"/>
|
||||
<stroke
|
||||
ohos:width="1"
|
||||
ohos:color="#C2C2C2"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:ohos="http://schemas.huawei.com/res/ohos"
|
||||
ohos:shape="rectangle"
|
||||
>
|
||||
<fill
|
||||
ohos:color="#00FFFFFF"
|
||||
/>
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:ohos="http://schemas.huawei.com/res/ohos"
|
||||
ohos:shape="rectangle"
|
||||
>
|
||||
<fill
|
||||
ohos:color="#FFFFFFFF"
|
||||
/>
|
||||
</shape>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:ohos="http://schemas.huawei.com/res/ohos"
|
||||
ohos:shape="rectangle">
|
||||
|
||||
<corners
|
||||
ohos:radius="5"/>
|
||||
|
||||
<solid
|
||||
ohos:color="#1fa014"/>
|
||||
|
||||
</shape>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<DependentLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
|
||||
ohos:id="$+id:editbox_container"
|
||||
ohos:height="match_parent"
|
||||
ohos:width="match_parent"
|
||||
ohos:alpha="0"
|
||||
ohos:orientation="vertical">
|
||||
|
||||
<StackLayout
|
||||
ohos:height="40vp"
|
||||
ohos:width="match_parent"
|
||||
ohos:align_parent_bottom="true"
|
||||
>
|
||||
|
||||
<TextField
|
||||
ohos:id="$+id:editbox_textField"
|
||||
ohos:hint_color="#888888"
|
||||
ohos:height="match_parent"
|
||||
ohos:width="match_parent"
|
||||
ohos:background_element="$graphic:bg_common_unpress_btn"
|
||||
ohos:text_alignment="vertical_center"
|
||||
ohos:text_color="#333"
|
||||
ohos:text_size="16fp"
|
||||
ohos:weight="1"
|
||||
/>
|
||||
<Button
|
||||
ohos:id="$+id:editbox_enterBtn"
|
||||
ohos:background_element="$graphic:darkgreen_roundrect"
|
||||
ohos:height="match_parent"
|
||||
ohos:width="match_content"
|
||||
ohos:min_width="60vp"
|
||||
|
||||
ohos:right_margin="0vp"
|
||||
ohos:layout_alignment="right"
|
||||
ohos:text_alignment="center"
|
||||
ohos:text_color="#FFF"
|
||||
ohos:text_size="16fp"
|
||||
ohos:weight="2"
|
||||
ohos:text="OK"
|
||||
/>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
</DependentLayout>
|
||||
38
cocos/platform/ohos/modules/Screen.cpp
Normal file
38
cocos/platform/ohos/modules/Screen.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "platform/ohos/modules/Screen.h"
|
||||
#include "platform/java/jni/JniImp.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
int Screen::getDPI() const {
|
||||
static int dpi = -1;
|
||||
if (dpi == -1) {
|
||||
dpi = getDPIJNI();
|
||||
}
|
||||
return dpi;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
36
cocos/platform/ohos/modules/Screen.h
Normal file
36
cocos/platform/ohos/modules/Screen.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform/java/modules/CommonScreen.h"
|
||||
|
||||
namespace cc {
|
||||
|
||||
class Screen : public CommonScreen {
|
||||
public:
|
||||
int getDPI() const override;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
35
cocos/platform/ohos/modules/System.cpp
Normal file
35
cocos/platform/ohos/modules/System.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "platform/ohos/modules/System.h"
|
||||
|
||||
namespace cc {
|
||||
System::System() = default;
|
||||
System::~System() = default;
|
||||
|
||||
System::OSType System::getOSType() const {
|
||||
return OSType::OHOS;
|
||||
}
|
||||
|
||||
} // namespace cc
|
||||
41
cocos/platform/ohos/modules/System.h
Normal file
41
cocos/platform/ohos/modules/System.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform/java/modules/CommonSystem.h"
|
||||
|
||||
class ANativeWindow;
|
||||
|
||||
namespace cc {
|
||||
|
||||
class System : public CommonSystem {
|
||||
public:
|
||||
System();
|
||||
~System() override;
|
||||
|
||||
OSType getOSType() const override;
|
||||
};
|
||||
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user