no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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);
}
}
}

View 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

View 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;
}
}

View 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'
}

Binary file not shown.

Binary file not shown.

View 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.**

View 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"
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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) {
}
}

View File

@@ -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;
}
}

View File

@@ -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) {
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
});
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,12 @@
{
"string": [
{
"name": "lib_name",
"value": "cocos"
},
{
"name": "done",
"value": "Done"
}
]
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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

View 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

View 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

View 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