diff --git a/DFX/Debug/.gitignore b/DFX/Debug/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dc4e6353bf3caf74c5953d0bec81c72a3635bf33 --- /dev/null +++ b/DFX/Debug/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy \ No newline at end of file diff --git a/DFX/Debug/AppScope/app.json5 b/DFX/Debug/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..25277f37ef6113ae61a485cdfe564a87ec96347e --- /dev/null +++ b/DFX/Debug/AppScope/app.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "app": { + "bundleName": "ohos.samples.debug", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true, + "singleton": true + } +} diff --git a/DFX/Debug/AppScope/resources/base/element/string.json b/DFX/Debug/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..5346f14fc7dc2acc788c133130c9fdca54177946 --- /dev/null +++ b/DFX/Debug/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "Debug" + } + ] +} diff --git a/DFX/Debug/AppScope/resources/base/media/app_icon.png b/DFX/Debug/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/DFX/Debug/AppScope/resources/base/media/app_icon.png differ diff --git a/DFX/Debug/README.md b/DFX/Debug/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2000a3751c0360d12e219f0c7cb62843d2e52cf3 --- /dev/null +++ b/DFX/Debug/README.md @@ -0,0 +1,33 @@ +# HiDebug + +### Introduction + +This sample shows how to use HiDebug APIs to obtain the memory usage of an application. The display effect is as follows: + +![](screenshots/device/index.jpeg) ![](screenshots/device/data.jpeg) + +### Concepts + +**HiDebug**: a module that allows you to obtain the memory usage of an application, including the static heap memory (native heap) and proportional set size (PSS) occupied by the application process. It also allows you to export VM memory slices and collect VM CPU profiling data. + +**Stack**: a component that provides a stack container where child components are successively stacked and the latter one overwrites the previous one. + +**@Builder**: a decorator used for a method to define the declarative UI description of a component and quickly generate multiple layouts in a custom component. + +### Required Permissions + +N/A + +### Usage + +1. Touch the **Debug** icon in the upper right corner of the page. The debugging information page is displayed, showing the memory usage of the application. + +2. Touch the **Debug** icon again. The debugging information page disappears. + +### Constraints + +1. This sample can only be run on standard-system devices. + +2. This sample is based on the stage model, which is supported from API version 9. + +3. DevEco Studio 3.1 Canary1 (Build Version: 3.1.0.100) must be used. diff --git a/DFX/Debug/README_zh.md b/DFX/Debug/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..c7ec6333837366e245b81ea80833a9e5178d066b --- /dev/null +++ b/DFX/Debug/README_zh.md @@ -0,0 +1,52 @@ +# Debug + +### 介绍 + +本示例通过使用[@ohos.hidebug](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-hidebug.md) 接口来获取当前应用内存使用情况。 + +### 效果预览 + +|主页|Debug数据| +|--------------------------------|--------------------------------| +|![](screenshots/device/index.jpeg)|![](screenshots/device/data.jpeg)| + +使用说明 + +1.点击界面右上方Debug图标,弹出Debug信息界面,显示当前应用内存使用情况; + +2.再次点击右上方Debug图标,Debug信息界面消失。 + +### 工程目录 + +``` +entry/src/main/ets/ +|---Application +|---component +| |---DebugInfo.ets // Debug信息页面 +|---data +| |---Logger.ts // 日志工具 +|---MainAbility +|---pages +| |---Index.ets // 首页 +``` +### 具体实现 + +* 本实例获取Debug信息的功能结主要封装在Index,源码参考:[Index.ets](https://gitee.com/openharmony/applications_app_samples/blob/master/code/BasicFeature/DFX/Debug/entry/src/main/ets/pages/Index.ets) 。 + * 获取Debug信息:在Index页面中通过点击事件调用hidebug.getPss()、hidebug.getSharedDirty()、hidebug.getPrivateDirty()等方法能够获取应用进程实际使用的物理内存大小、进程的共享脏内存大小、进程的私有脏内存大小。 + +### 相关权限 + +不涉及。 + +### 依赖 + +不涉及。 + +### 约束与限制 + +1.本示例仅支持在标准系统上运行,支持设备:华为手机或者运行在DevEco Studio上的华为手机模拟器。 + +2.本示例为Stage模型,从API version 9开始支持。 + +3.本示例需要使用DevEco Studio 3.1 Beta1 (Build Version:3.1.0.200)及以上才可编译运行。 + diff --git a/DFX/Debug/build-profile.json5 b/DFX/Debug/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..956b202bee75f50ae79d7ff01ce70751673429bd --- /dev/null +++ b/DFX/Debug/build-profile.json5 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "app": { + "signingConfigs": [], + "compileSdkVersion": 9, + "compatibleSdkVersion": 9, + "products": [ + { + "name": "default", + "signingConfig": "default", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} diff --git a/DFX/Debug/entry/.gitignore b/DFX/Debug/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5a6ba80fa3d9498a23ae8ae7d9518f8743fa8a96 --- /dev/null +++ b/DFX/Debug/entry/.gitignore @@ -0,0 +1,4 @@ +/node_modules +/.preview +/build +/.cxx \ No newline at end of file diff --git a/DFX/Debug/entry/build-profile.json5 b/DFX/Debug/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..1eecc81311c0227d8309059966c94d3b02fb5d26 --- /dev/null +++ b/DFX/Debug/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} diff --git a/DFX/Debug/entry/hvigorfile.js b/DFX/Debug/entry/hvigorfile.js new file mode 100644 index 0000000000000000000000000000000000000000..d7720ee6a7aad5c617d1fd2f6fc8c87067bfa32c --- /dev/null +++ b/DFX/Debug/entry/hvigorfile.js @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks diff --git a/DFX/Debug/entry/hvigorfile.ts b/DFX/Debug/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..80e4ec5b81689f238c34614b167a0b9e9c83e8d9 --- /dev/null +++ b/DFX/Debug/entry/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/DFX/Debug/entry/package.json b/DFX/Debug/entry/package.json new file mode 100644 index 0000000000000000000000000000000000000000..29732ffea047ab4e9d897d4cc7092f5e7fe3493f --- /dev/null +++ b/DFX/Debug/entry/package.json @@ -0,0 +1,14 @@ +{ + "license": "ISC", + "devDependencies": {}, + "name": "entry", + "ohos": { + "org": "huawei", + "directoryLevel": "module", + "buildTool": "hvigor" + }, + "description": "example description", + "repository": {}, + "version": "1.0.0", + "dependencies": {} +} diff --git a/DFX/Debug/entry/src/main/ets/Application/MyAbilityStage.ts b/DFX/Debug/entry/src/main/ets/Application/MyAbilityStage.ts new file mode 100644 index 0000000000000000000000000000000000000000..52af3317e96e15084e23dd906831a874aafa5201 --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/Application/MyAbilityStage.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import AbilityStage from '@ohos.app.ability.AbilityStage' +import Logger from '../data/Logger' + +const TAG: string = 'AbilityStage' + +export default class MyAbilityStage extends AbilityStage { + onCreate() { + Logger.info(TAG, '[Demo] MyAbilityStage onCreate') + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/ets/MainAbility/MainAbility.ts b/DFX/Debug/entry/src/main/ets/MainAbility/MainAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..588080b66a81cdcfc5adb8bedf74836e26bd0bcf --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/MainAbility/MainAbility.ts @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import UIAbility from '@ohos.app.ability.UIAbility' +import Logger from '../data/Logger' + +const TAG: string = 'MainAbility' + +export default class MainAbility extends UIAbility { + onCreate(want, launchParam) { + Logger.info(TAG, '[Demo] MainAbility onCreate') + } + + onDestroy() { + Logger.info(TAG, '[Demo] MainAbility onDestroy') + } + + onWindowStageCreate(windowStage) { + // Main window is created, set main page for this ability + Logger.info(TAG, '[Demo] MainAbility onWindowStageCreate') + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Logger.error(TAG, `Failed to load the content. Cause: ${JSON.stringify(err)}`) + return + } + Logger.info(TAG, `Succeeded in loading the content. Data: ${JSON.stringify(data)}`) + }) + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + Logger.info(TAG, '[Demo] MainAbility onWindowStageDestroy') + } + + onForeground() { + // Ability has brought to foreground + Logger.info(TAG, '[Demo] MainAbility onForeground') + } + + onBackground() { + // Ability has back to background + Logger.info(TAG, '[Demo] MainAbility onBackground') + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/ets/component/DebugInfo.ets b/DFX/Debug/entry/src/main/ets/component/DebugInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..478a481089d287dc2a6fbff4cd426d26aee3574c --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/component/DebugInfo.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +@Component +export default struct DebugInfo { + @Prop debugWindow: boolean + @Link pssMemory: number + @Link sharedMemory: number + @Link privateMemory: number + + build() { + Stack({ alignContent: Alignment.Top }) { + Text($r('app.string.navigation_information')) + .fontSize(25) + .width('80%') + .lineHeight(40) + .margin({ top: '5%' }) + .fontWeight(FontWeight.Bold) + + if (this.debugWindow) { + Column() { + this.showDebug($r('app.string.pss'), this.pssMemory) + this.showDebug($r('app.string.sharedDirty'), this.sharedMemory) + this.showDebug($r('app.string.privateDirty'), this.privateMemory) + } + .width('85%') + .height('25%') + .margin({ top: '35%' }) + .padding({ bottom: '5%', top: '5%' }) + .backgroundColor(Color.White) + .border({ width: 2, radius: 10 }) + } + } + .width('100%') + .height('100%') + } + + @Builder + // Debug显示信息复用组件 + showDebug(title: Resource, data: number) { + Row() { + Text(title) + .fontSize(20) + .width('60%') + .margin({ left: 6 }) + .textAlign(TextAlign.End) + + Text(`${data}KB`) + .fontSize(20) + } + .width('100%') + .margin({ top: 10 }) + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/ets/data/Logger.ts b/DFX/Debug/entry/src/main/ets/data/Logger.ts new file mode 100644 index 0000000000000000000000000000000000000000..8ffe703bccf3b2ea59b2e56d2bbbb070501d4069 --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/data/Logger.ts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import hilog from '@ohos.hilog' + +export class Logger { + private domain: number + private prefix: string + private format: string = `%{public}s, %{public}s` + + constructor(prefix: string) { + this.prefix = prefix + this.domain = 0xFF00 + } + + debug(...args: any[]) { + hilog.debug(this.domain, this.prefix, this.format, args) + } + + info(...args: any[]) { + hilog.info(this.domain, this.prefix, this.format, args) + } + + warn(...args: any[]) { + hilog.warn(this.domain, this.prefix, this.format, args) + } + + error(...args: any[]) { + hilog.error(this.domain, this.prefix, this.format, args) + } + + fatal(...args: any[]) { + hilog.fatal(this.domain, this.prefix, this.format, args) + } +} + +export default new Logger('[Sample_Debug]') \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/ets/entryability/EntryAbility.ts b/DFX/Debug/entry/src/main/ets/entryability/EntryAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..28ce3bc1d6f0d0d3f1b720ebddf8189e1c279e5d --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/entryability/EntryAbility.ts @@ -0,0 +1,41 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import hilog from '@ohos.hilog'; +import window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground() { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground() { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/DFX/Debug/entry/src/main/ets/pages/Index.ets b/DFX/Debug/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba7b7306af3b6576217dfe02c1eb82dc11795765 --- /dev/null +++ b/DFX/Debug/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +import hidebug from '@ohos.hidebug' +import DebugInfo from '../component/DebugInfo' + +@Entry +@Component +struct Index { + @State pssMemory: number = 0 + @State sharedMemory: number = 0 + @State privateMemory: number = 0 + @State debugWindow: boolean = false + + build() { + Column() { + Row() { + Text($r('app.string.MainAbility_label')) + .margin(4) + .fontSize(20) + .fontColor(Color.White) + .textAlign(TextAlign.Center) + + Blank() + + Image($r('app.media.debug')) + .key('btnDebug') + .width('10%') + .margin({ right: 4 }) + .objectFit(ImageFit.Contain) + .onClick(() => { + this.debugWindow = !this.debugWindow + if (this.debugWindow) { + let pss = hidebug.getPss() + this.pssMemory = Number(pss !== null ? pss : -1) // -1代表getPss()接口返回值错误 + let sharedDirty = hidebug.getSharedDirty() + this.sharedMemory = Number(sharedDirty !== null ? sharedDirty : -1) // -1代表getSharedDirty()接口返回值错误 + let privateDirty = hidebug.getPrivateDirty() + this.privateMemory = Number(privateDirty !== null ? privateDirty : -1) // -1代表getPrivateDirty()接口返回值错误 + } + }) + } + .height('6%') + .width('100%') + .padding({ right: 10 }) + .backgroundColor('#0D9FFB') + .constraintSize({ minHeight: 50 }) + + // 显示Debug信息窗口 + DebugInfo({ + pssMemory: $pssMemory, + sharedMemory: $sharedMemory, + debugWindow: this.debugWindow, + privateMemory: $privateMemory + }) + } + .width('100%') + .height('100%') + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/module.json5 b/DFX/Debug/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6267f62cda9c12f13bf7781aa5045721bff7f7a2 --- /dev/null +++ b/DFX/Debug/entry/src/main/module.json5 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "srcEntrance": "./ets/Application/MyAbilityStage.ts", + "description": "$string:entry_desc", + "mainElement": "MainAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "uiSyntax": "ets", + "metadata": [ + { + "name": "ArkTSPartialUpdate", + "value": "true" + } + ], + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/MainAbility/MainAbility.ts", + "description": "$string:MainAbility_desc", + "icon": "$media:icon", + "label": "$string:MainAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} diff --git a/DFX/Debug/entry/src/main/resources/base/element/color.json b/DFX/Debug/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..1bbc9aa9617e97c45440e1d3d66afc1154837012 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/resources/base/element/string.json b/DFX/Debug/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0b60aeffe8cc222114d7df1ba38cbf2ad42747a8 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/base/element/string.json @@ -0,0 +1,32 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "Debug" + }, + { + "name": "pss", + "value": "PSS size:" + }, + { + "name": "sharedDirty", + "value": "Shared dirty memory size:" + }, + { + "name": "privateDirty", + "value": "Private dirty memory size:" + }, + { + "name": "navigation_information", + "value": "Please click the Debug icon button at the top right to view or close the debug information:" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/resources/base/media/debug.png b/DFX/Debug/entry/src/main/resources/base/media/debug.png new file mode 100644 index 0000000000000000000000000000000000000000..165b14a71ef44369ad9018bfcc961ff511b68a88 Binary files /dev/null and b/DFX/Debug/entry/src/main/resources/base/media/debug.png differ diff --git a/DFX/Debug/entry/src/main/resources/base/media/icon.png b/DFX/Debug/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/DFX/Debug/entry/src/main/resources/base/media/icon.png differ diff --git a/DFX/Debug/entry/src/main/resources/base/profile/main_pages.json b/DFX/Debug/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/DFX/Debug/entry/src/main/resources/en/element/string.json b/DFX/Debug/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0b60aeffe8cc222114d7df1ba38cbf2ad42747a8 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/en/element/string.json @@ -0,0 +1,32 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "Debug" + }, + { + "name": "pss", + "value": "PSS size:" + }, + { + "name": "sharedDirty", + "value": "Shared dirty memory size:" + }, + { + "name": "privateDirty", + "value": "Private dirty memory size:" + }, + { + "name": "navigation_information", + "value": "Please click the Debug icon button at the top right to view or close the debug information:" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/resources/en_US/element/string.json b/DFX/Debug/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/resources/zh/element/string.json b/DFX/Debug/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..271a060792372dafab28d23d508f70c10fda6c35 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,32 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "Debug调试" + }, + { + "name": "pss", + "value": "应用进程PSS内存:" + }, + { + "name": "sharedDirty", + "value": "进程的共享脏内存大小:" + }, + { + "name": "privateDirty", + "value": "进程的私有脏内存大小:" + }, + { + "name": "navigation_information", + "value": "请点击右上方的Debug图标按钮查看或关闭debug信息:" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/main/resources/zh_CN/element/string.json b/DFX/Debug/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/DFX/Debug/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/Application/TestAbilityStage.ts b/DFX/Debug/entry/src/ohosTest/ets/Application/TestAbilityStage.ts new file mode 100644 index 0000000000000000000000000000000000000000..87cde7ba9135814090a1b5f14b0fa9b39b8d8c22 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import AbilityStage from "@ohos.application.AbilityStage" + +export default class TestAbilityStage extends AbilityStage { + onCreate() { + console.log("[Demo] TestAbilityStage onCreate") + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/test/Ability.test.ets b/DFX/Debug/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..8abf7f2f44c0e56110df8c09b2524a4ca37bc993 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/test/App.test.ets b/DFX/Debug/entry/src/ohosTest/ets/test/App.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..55b53b408f67f0d6acdceb3b8d8f39515c058cd5 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/test/App.test.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import { UiDriver, BY, UiComponent, MatchPattern } from '@ohos.uitest' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import hilog from '@ohos.hilog' + +const BUNDLE = "Debug" +const TAG = '[Sample_Debug]' +const DOMAIN = 0xF811 + +export default function appTest() { + describe('appTest', function () { + it(BUNDLE + '_startAbility', 0, async function (done) { + hilog.info(DOMAIN, TAG, BUNDLE + '_startAbility start') + let want = { + bundleName: "ohos.samples.debug", + abilityName: "MainAbility" + } + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + await abilityDelegator.startAbility(want, (err, data) => { + hilog.info(DOMAIN, TAG, BUNDLE + '_startAbility get err ' + JSON.stringify(err)) + expect(0).assertEqual(err.code) + done() + hilog.info(DOMAIN, TAG, BUNDLE + '_startAbility end') + }) + }) + /** + * debug接口信息的显示与隐藏 + */ + it(BUNDLE + '_IndexPage_BtnDebugIcon', 0, async () => { + hilog.info(DOMAIN, TAG, BUNDLE + '_IndexPage_MsgShow start') + let driver = await UiDriver.create() + await driver.delayMs(1000) + // 点击显示信息 + await driver.assertComponentExist(BY.key('btnDebug')) + let msgShow = await driver.findComponent(BY.key('btnDebug')) + await msgShow.click() + await driver.delayMs(1000) + hilog.info(DOMAIN, TAG, BUNDLE + '_IndexPage_MsgShow end') + // 点击隐藏信息 + hilog.info(DOMAIN, TAG, BUNDLE + '_IndexPage_MsgDispay start') + await driver.assertComponentExist(BY.key('btnDebug')) + let msgDisplay = await driver.findComponent(BY.key('btnDebug')) + await msgDisplay.click() + await driver.delayMs(1000) + hilog.info(DOMAIN, TAG, BUNDLE + '_IndexPage_MsgDispay end') + }) + }) +} diff --git a/DFX/Debug/entry/src/ohosTest/ets/test/List.test.ets b/DFX/Debug/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..b5e347398c32b2caf8e019c59f0df71c863a6aaf --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import appTest from './App.test' + +export default function testsuite() { + appTest() +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ets b/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..e3f6e911d3fffba1e1795c60ed1ee4db15b386fd --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,48 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ts b/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..f8e5366ea62823fea7f2819cb7ed2a756d38e9d7 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/testability/TestAbility.ts @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import Ability from '@ohos.application.Ability' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import { Hypium } from '@ohos/hypium' +import testsuite from '../test/List.test' + +export default class TestAbility extends Ability { + onCreate(want, launchParam) { + console.log('TestAbility onCreate') + } + + onDestroy() { + console.log('TestAbility onDestroy') + } + + onWindowStageCreate(windowStage) { + console.log('TestAbility onWindowStageCreate') + windowStage.loadContent("TestAbility/pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)) + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }) + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + console.info('start run testcase!!!') + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onWindowStageDestroy() { + console.log('TestAbility onWindowStageDestroy') + } + + onForeground() { + console.log('TestAbility onForeground') + } + + onBackground() { + console.log('TestAbility onBackground') + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/testability/pages/index.ets b/DFX/Debug/entry/src/ohosTest/ets/testability/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c4fc4c805ac9650c80d382dd7b95a382703d7ec --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/testability/pages/index.ets @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import router from '@ohos.router'; + +@Entry +@Component +struct Index { + aboutToAppear() { + console.info('TestAbility index aboutToAppear') + } + + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + } + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(() => { + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/DFX/Debug/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..0124a87e3847a3b346c2e7cbff3848c7f1190ba4 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import TestRunner from '@ohos.application.testRunner' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +function translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s it', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun' + ]) + let targetParams = ''; + for (const key in parameters) { + if (keySet.has(key)) { + targetParams = `${targetParams} ${key} ${parameters[key]}` + } + } + return targetParams.trim() +} + +async function onAbilityCreateCallback() { + console.log("onAbilityCreateCallback"); +} + +async function addAbilityMonitorCallback(err: any) { + console.info("addAbilityMonitorCallback : " + JSON.stringify(err)) +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + console.info("OpenHarmonyTestRunner OnPrepare ") + } + + async onRun() { + console.log('OpenHarmonyTestRunner onRun run') + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + cmd += ' ' + translateParamsToString(abilityDelegatorArguments.parameters) + var debug = abilityDelegatorArguments.parameters["-D"] + if (debug == 'true') { + cmd += ' -D' + } + console.info('cmd : ' + cmd) + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + console.info('executeShellCommand : err : ' + JSON.stringify(err)); + console.info('executeShellCommand : data : ' + d.stdResult); + console.info('executeShellCommand : data : ' + d.exitCode); + }) + console.info('OpenHarmonyTestRunner onRun end') + } +}; \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/module.json5 b/DFX/Debug/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..60a4ec89e07f3f86707ac6c1def79a8930608788 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/module.json5 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +{ + "module": { + "name": "entry_test", + "type": "feature", + "srcEntrance": "./ets/Application/TestAbilityStage.ts", + "description": "$string:entry_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "TestAbility", + "srcEntrance": "./ets/TestAbility/TestAbility.ts", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "visible": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/DFX/Debug/entry/src/ohosTest/resources/base/element/color.json b/DFX/Debug/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..1bbc9aa9617e97c45440e1d3d66afc1154837012 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/resources/base/element/string.json b/DFX/Debug/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..36d4230c53e9f5a07ae343ad8dc9808341975e3b --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/DFX/Debug/entry/src/ohosTest/resources/base/media/icon.png b/DFX/Debug/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/DFX/Debug/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/DFX/Debug/entry/src/ohosTest/resources/base/profile/test_pages.json b/DFX/Debug/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..fcef82b4dfc18e28106ff9ecd1c8b48ec74d18a4 --- /dev/null +++ b/DFX/Debug/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "TestAbility/pages/index" + ] +} diff --git a/DFX/Debug/hvigorfile.ts b/DFX/Debug/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..6478186902c0c1ad7c966a929c7d6b7d8ae7a9f3 --- /dev/null +++ b/DFX/Debug/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/DFX/Debug/package.json b/DFX/Debug/package.json new file mode 100644 index 0000000000000000000000000000000000000000..2560f2d9ca2f5590c1ec28a4d758beab1c65bf70 --- /dev/null +++ b/DFX/Debug/package.json @@ -0,0 +1,18 @@ +{ + "license": "ISC", + "devDependencies": {}, + "name": "debug", + "ohos": { + "org": "huawei", + "directoryLevel": "project", + "buildTool": "hvigor" + }, + "description": "example description", + "repository": {}, + "version": "1.0.0", + "dependencies": { + "@ohos/hypium": "1.0.5", + "@ohos/hvigor-ohos-plugin": "1.4.0", + "@ohos/hvigor": "1.4.0" + } +} diff --git a/DFX/Debug/screenshots/device/data.jpeg b/DFX/Debug/screenshots/device/data.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8d4dacf4a99779f375e4de544d28320c54796989 Binary files /dev/null and b/DFX/Debug/screenshots/device/data.jpeg differ diff --git a/DFX/Debug/screenshots/device/index.jpeg b/DFX/Debug/screenshots/device/index.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fda58f71feaea153cd3ef26117247cf32ebdda68 Binary files /dev/null and b/DFX/Debug/screenshots/device/index.jpeg differ diff --git a/media/GamePuzzle/.gitignore b/media/GamePuzzle/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dc4e6353bf3caf74c5953d0bec81c72a3635bf33 --- /dev/null +++ b/media/GamePuzzle/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy \ No newline at end of file diff --git a/media/GamePuzzle/AppScope/app.json5 b/media/GamePuzzle/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..282e5e02eda18cbce528a6c2187db21f7ccb83a7 --- /dev/null +++ b/media/GamePuzzle/AppScope/app.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "app": { + "bundleName": "ohos.samples.gamepuzzle", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true + } +} diff --git a/media/GamePuzzle/AppScope/resources/base/element/string.json b/media/GamePuzzle/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..cca8b9277b5aa593aef68f08df0c49b77c4c51a7 --- /dev/null +++ b/media/GamePuzzle/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "GamePuzzle" + } + ] +} diff --git a/media/GamePuzzle/AppScope/resources/base/media/app_icon.png b/media/GamePuzzle/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/media/GamePuzzle/AppScope/resources/base/media/app_icon.png differ diff --git a/media/GamePuzzle/README.md b/media/GamePuzzle/README.md new file mode 100644 index 0000000000000000000000000000000000000000..4eb59b8b52f520af75a3d00e9ef58a51efdb47e9 --- /dev/null +++ b/media/GamePuzzle/README.md @@ -0,0 +1,35 @@ +# Puzzle Game + +### Introduction + +This puzzle game app is developed based on the **\** component. It uses the `Image` and `MediaLibrary` APIs to obtain and crop images. Below shows the sample app. + +![running](screenshot/devices/change.jpeg) + +### Concepts + +`ImagePacker`: a class that provides APIs to pack images. Before calling any API in `ImagePacker`, you must use `createImagePacker` to create an `ImagePacker` instance. + +`MediaLibrary`: a class that provides APIs to access and modify media data such as audios, videos, images, and documents. + +### Required Permissions + +ohos.permission.READ_MEDIA + +### Usage + +1. The sample app reads the image files on the local device and displays the first image it obtains. If there is no image on the local device, a blank is displayed. + +2. Touch **Start**, and the countdown begins. If you fail to finish the puzzle within the specified time, the game ends. You can touch **Restart** to play the game again. + +3. When the game is in progress, you can touch any image around the gray grid to swap the position of the image and highlighted grid cell, until you get a complete image. + +4. When the game is not in progress, you can touch the large image on the top and select another image for the game. + +### Constraints + +1. This sample can only be run on standard-system devices. + +2. This sample demonstrates the stage model, which supports only API version 10. + +3. This sample requires DevEco Studio 3.1 Canary1 (Build Version: 3.1.0.100) to compile and run. diff --git a/media/GamePuzzle/README_zh.md b/media/GamePuzzle/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..d9bdcf8828fd5af298b8e50c1c998d37d02c3994 --- /dev/null +++ b/media/GamePuzzle/README_zh.md @@ -0,0 +1,53 @@ +# 拼图 + +### 介绍 + +该示例通过[@ohos.multimedia.image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-image.md)和[@ohos.multimedia.mediaLibrary](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-medialibrary.md)接口实现获取图片,以及图片裁剪分割的功能。 + +### 效果预览 +|首页|运行| +|---|---| +|![running](screenshot/devices/running.jpeg)|![running](screenshot/devices/change.jpeg)| + +使用说明: +1. 使用预置相机拍照后启动应用,应用首页会读取设备内的图片文件并展示获取到的第一个图片,没有图片时图片位置显示空白; +2. 点击Start开始后,时间开始倒计时,在规定时间内未完成拼图则游戏结束。在游戏中,玩家点击Restart进行游戏重置; +3. 点击开始游戏后,玩家可以根据上方的大图,点击灰格周围的图片移动,点击后图片和灰格交换位置,最终拼成完整的图片; +4. 不在游戏中时,玩家可以点击上方大图,选择自定义图片来进行拼图游戏。 + +### 工程目录 +``` +VideoComponent/src/main/ets/components +|---common +| |---ImagePicker.ets // 图片选择 +|---model +| |---GameRules.ts // 游戏规则 +| |---ImageModel.ts // 图片操作 +| |---Logger.ts // 日志 +| |---PictureItem.ts // 分解的图片 +|---pages +| |---Index.ets // 首页 +``` +### 具体实现 ++ 游戏中图片裁剪分割的效果实现在ImageModel中,源码参考[ImageModel](entry/src/main/ets/model/ImageModel.ts): + + 获取本地图片:首先使用getMediaLibrary获取媒体库实例,然后使用getFileAssets方法获取文件资源,最后使用getAllObject获取检索结果中的所有文件资产方便展示; + + 裁剪图片准备:裁剪图片需要使用[@ohos.multimedia.image](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-image.md)接口,裁剪前需要申请图片编辑权限,使用[requestPermissionsFromUser](https://gitee.com/openharmony/docs/blob/monthly_20221018/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md)申请,源码参考[Index.ets](entry/src/main/ets/pages/Index.ets); + + 图片编辑:首先使用createImagePacker创建ImagePacker实例,然后使用fileAsset.open打开文件,调用createImageSource接口创建图片源实例方便操作图片,接下来使用getImageInfo方法获取图片大小便于分割,最后使用createPixelMap方法传入每一份的尺寸参数完成图片裁剪。 + +### 相关权限 + +[ohos.permission.READ_MEDIA](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md) + +[ohos.permission.MEDIA_LOCATION](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md) + +### 依赖 + +不涉及。 + +### 约束与限制 + +1.本示例仅支持在标准系统上运行,支持设备:华为手机或者运行在DevEco Studio上的华为手机模拟器。 + +2.本示例为Stage模型,从API version 9开始支持。 + +3.本示例需要使用DevEco Studio 3.1 Beta1 (Build Version:3.1.0.200)及以上才可编译运行。 diff --git a/media/GamePuzzle/build-profile.json5 b/media/GamePuzzle/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f641e1aaa9a8de486f17b22b3d6630779225bf8e --- /dev/null +++ b/media/GamePuzzle/build-profile.json5 @@ -0,0 +1,40 @@ +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_GamePuzzle2_ohos.samples.gamepuzzle.cer", + "storePassword": "0000001BDDFF7E93D17D853A472C195AAEC4FEE615D92BFB14D04B65F08A7D64768DB165E0773322A621A5", + "keyAlias": "debugKey", + "keyPassword": "0000001BB24F5C465717DA881498190DF8EDAAF61BE84D9B74C078908B4B91E53FF498E662058AEA63E61F", + "profile": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_GamePuzzle2_ohos.samples.gamepuzzle.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\Administrator\\.ohos\\config\\openharmony\\auto_ohos_default_GamePuzzle2_ohos.samples.gamepuzzle.p12" + } + } + ], + "compileSdkVersion": 9, + "compatibleSdkVersion": 9, + "products": [ + { + "name": "default", + "signingConfig": "default", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/.gitignore b/media/GamePuzzle/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..5a6ba80fa3d9498a23ae8ae7d9518f8743fa8a96 --- /dev/null +++ b/media/GamePuzzle/entry/.gitignore @@ -0,0 +1,4 @@ +/node_modules +/.preview +/build +/.cxx \ No newline at end of file diff --git a/media/GamePuzzle/entry/build-profile.json5 b/media/GamePuzzle/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f00f788a9989ab18677ef502d319558a81baffe2 --- /dev/null +++ b/media/GamePuzzle/entry/build-profile.json5 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} diff --git a/media/GamePuzzle/entry/hvigorfile.js b/media/GamePuzzle/entry/hvigorfile.js new file mode 100644 index 0000000000000000000000000000000000000000..d7720ee6a7aad5c617d1fd2f6fc8c87067bfa32c --- /dev/null +++ b/media/GamePuzzle/entry/hvigorfile.js @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks diff --git a/media/GamePuzzle/entry/hvigorfile.ts b/media/GamePuzzle/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..80e4ec5b81689f238c34614b167a0b9e9c83e8d9 --- /dev/null +++ b/media/GamePuzzle/entry/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/media/GamePuzzle/entry/package.json b/media/GamePuzzle/entry/package.json new file mode 100644 index 0000000000000000000000000000000000000000..29732ffea047ab4e9d897d4cc7092f5e7fe3493f --- /dev/null +++ b/media/GamePuzzle/entry/package.json @@ -0,0 +1,14 @@ +{ + "license": "ISC", + "devDependencies": {}, + "name": "entry", + "ohos": { + "org": "huawei", + "directoryLevel": "module", + "buildTool": "hvigor" + }, + "description": "example description", + "repository": {}, + "version": "1.0.0", + "dependencies": {} +} diff --git a/media/GamePuzzle/entry/src/main/ets/Application/AbilityStage.ts b/media/GamePuzzle/entry/src/main/ets/Application/AbilityStage.ts new file mode 100644 index 0000000000000000000000000000000000000000..8518e2177d6dbc581b482542c8e4378dcf8ab18f --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/Application/AbilityStage.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import AbilityStage from '@ohos.app.ability.AbilityStage'; +import Logger from '../model/Logger'; + +export default class MyAbilityStage extends AbilityStage { + onCreate() { + Logger.info('MyAbilityStage', 'onCreate'); + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/MainAbility/MainAbility.ts b/media/GamePuzzle/entry/src/main/ets/MainAbility/MainAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..7d9f6e3997c4345be6276f5e4374a7966c04c872 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/MainAbility/MainAbility.ts @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import UIAbility from '@ohos.app.ability.UIAbility' +import Logger from '../model/Logger' + +const TAG: string = 'MainAbility' + +export default class MainAbility extends UIAbility { + onCreate(want, launchParam) { + Logger.info(TAG, 'MainAbility onCreate') + } + + onDestroy() { + Logger.info(TAG, 'MainAbility onDestroy') + } + + onWindowStageCreate(windowStage) { + // Main window is created, set main page for this ability + Logger.info(TAG, 'MainAbility onWindowStageCreate') + windowStage.setUIContent(this.context, "pages/Index", null) + } + + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + Logger.info(TAG, 'MainAbility onWindowStageDestroy') + } + + onForeground() { + // Ability has brought to foreground + Logger.info(TAG, 'MainAbility onForeground') + } + + onBackground() { + // Ability has back to background + Logger.info(TAG, 'MainAbility onBackground') + } +} diff --git a/media/GamePuzzle/entry/src/main/ets/common/ImagePicker.ets b/media/GamePuzzle/entry/src/main/ets/common/ImagePicker.ets new file mode 100644 index 0000000000000000000000000000000000000000..a74fa82e97d15f2361b61dfd76e85a5ca2c16ea4 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/common/ImagePicker.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import mediaLibrary from '@ohos.multimedia.mediaLibrary' + +@CustomDialog +export default struct ImagePicker { + private imageDatas: Array = [] + private selected: number = 0 + public controller: CustomDialogController + @Link index: number + + aboutToAppear() { + this.selected = this.index + } + + build() { + Column() { + List({ space: 5 }) { + ForEach(this.imageDatas, (item, index) => { + ListItem() { + Stack({ alignContent: Alignment.TopEnd }) { + Image(item.uri).width(180).height(150).margin({ left: 2, right: 2, top: 5, bottom: 5 }) + Radio({ value: 'Radio3', group: 'radioGroup' }).checked(index === this.index ? true : false) + .onChange(() => { + this.selected = index + }) + } + } + }) + } + .width('95%') + .height(160) + .listDirection(Axis.Horizontal) + + Row() { + Button($r('app.string.cancel')) + .margin({ right: '25%' }) + .onClick(() => { + this.controller.close() + }) + Button($r('app.string.conform')) + .onClick(() => { + this.index = this.selected + }) + } + .margin({ bottom: 10 }) + } + .width('100%') + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/model/GameRules.ts b/media/GamePuzzle/entry/src/main/ets/model/GameRules.ts new file mode 100644 index 0000000000000000000000000000000000000000..f1170ddf7ff0c16376b8b7c76efac54c0b163156 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/model/GameRules.ts @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ +import PictureItem from '../model/PictureItem' + +const EMPTY_PICTURE: PictureItem = new PictureItem(9, undefined) + +export default class GameRules { + public numArray: PictureItem[] + + itemChange(index: number, pictures: PictureItem[]) { + let emptyIndex = this.findEmptyIndex(pictures) + let temp: PictureItem = pictures[index] + pictures[index] = EMPTY_PICTURE + pictures[emptyIndex] = new PictureItem(temp.index, temp.pixelMap) + return pictures + } + + findEmptyIndex(pictures: PictureItem[]) { + for (let i = 0;i < pictures.length; i++) { + if (pictures[i].index === EMPTY_PICTURE.index) { + return i + } + } + return -1 + } + + gameInit(i: number, pictures: PictureItem[]) { + let emptyIndex = this.findEmptyIndex(pictures) + let isGameStart: boolean = AppStorage.Get('isGameStart'); + if (isGameStart) { + switch (emptyIndex) { + case 0: + if (i === 1 || i === 3) { + pictures = this.itemChange(i, pictures) + } + break; + case 2: + if (i === 1 || i === 5) { + pictures = this.itemChange(i, pictures) + } + break; + case 6: + if (i === 3 || i === 7) { + pictures = this.itemChange(i, pictures) + } + break; + case 8: + if (i === 5 || i === 7) { + pictures = this.itemChange(i, pictures) + } + break; + case 3: + switch (i) { + case emptyIndex + 1: + case emptyIndex - 3: + case emptyIndex + 3: + pictures = this.itemChange(i, pictures) + } + break; + case 1: + switch (i) { + case emptyIndex + 1: + case emptyIndex - 1: + case emptyIndex + 3: + pictures = this.itemChange(i, pictures) + } + break; + case 5: + switch (i) { + case emptyIndex + 3: + case emptyIndex - 3: + case emptyIndex - 1: + pictures = this.itemChange(i, pictures) + } + break; + case 7: + switch (i) { + case emptyIndex + 1: + case emptyIndex - 3: + case emptyIndex - 1: + pictures = this.itemChange(i, pictures) + } + break; + case 4: + switch (i) { + case emptyIndex + 1: + case emptyIndex - 3: + case emptyIndex - 1: + case emptyIndex + 3: + pictures = this.itemChange(i, pictures) + } + break; + } + } + return pictures + } + + gameBegin(pictures: PictureItem[]) { + AppStorage.Set('isGameStart', true); + let len = pictures.length + let index, temp + while (len > 0) { + index = Math.floor(Math.random() * len) + temp = pictures[len-1] + pictures[len-1] = pictures[index] + pictures[index] = temp + len-- + } + return pictures + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/model/ImageModel.ts b/media/GamePuzzle/entry/src/main/ets/model/ImageModel.ts new file mode 100644 index 0000000000000000000000000000000000000000..10cc0a3aadd9a01af0a80fd77e61643018e20dc4 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/model/ImageModel.ts @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import image from '@ohos.multimedia.image' +import mediaLibrary from '@ohos.multimedia.mediaLibrary' +import Logger from './Logger' +import PictureItem from '../model/PictureItem' + +const TAG = '[ImageModel]' +const SPLIT_COUNT: number = 3 // 图片横竖切割的份数 +export default class ImageModel { + private media: mediaLibrary.MediaLibrary = undefined + + constructor(context: any) { + this.media = mediaLibrary.getMediaLibrary(context) + } + + async getAllImg() { + let fileKeyObj = mediaLibrary.FileKey + let fetchOp = { + selections: fileKeyObj.MEDIA_TYPE + '=?', + selectionArgs: [`${mediaLibrary.MediaType.IMAGE}`], + } + let mediaList: Array = [] + const fetchFileResult = await this.media.getFileAssets(fetchOp) + Logger.info(TAG, `queryFile getFileAssetsFromType fetchFileResult.count = ${fetchFileResult.getCount()}`) + if (fetchFileResult.getCount() > 0) { + mediaList = await fetchFileResult.getAllObject() + } + return mediaList + } + + async splitPic(index: number) { + let imagePixelMap: PictureItem[] = [] + let imgDatas: Array = await this.getAllImg() + let imagePackerApi = image.createImagePacker() + let fd = await imgDatas[index].open('r') + let imageSource = image.createImageSource(fd) + let imageInfo = await imageSource.getImageInfo() + Logger.info(TAG, `sizeImg createImageSource ${JSON.stringify(imageSource)}`) + let height = imageInfo.size.height / SPLIT_COUNT + for (let i = 0; i < SPLIT_COUNT; i++) { + for (let j = 0; j < SPLIT_COUNT; j++) { + let picItem + if (i === SPLIT_COUNT - 1 && j === SPLIT_COUNT - 1) { + picItem = new PictureItem(9, undefined) + imagePixelMap.push(picItem) + } else { + Logger.info(TAG, `sizeImg x = ${imageInfo.size.width / SPLIT_COUNT} y = ${height}`) + let decodingOptions: image.DecodingOptions = { + desiredRegion: { + size: { + height: height, width: imageInfo.size.width / SPLIT_COUNT + }, x: j * imageInfo.size.width / SPLIT_COUNT, y: i * height + } + } + picItem = await imageSource.createPixelMap(decodingOptions) + imagePixelMap.push({ + index: i * SPLIT_COUNT + j, pixelMap: picItem + }) + } + } + } + imagePackerApi.release() + await imgDatas[index].close(fd) + return imagePixelMap + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/model/Logger.ts b/media/GamePuzzle/entry/src/main/ets/model/Logger.ts new file mode 100644 index 0000000000000000000000000000000000000000..61d313fd32c3eb35bdaf190241b0ab911c178c25 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/model/Logger.ts @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import hilog from '@ohos.hilog' + +class Logger { + private domain: number + private prefix: string + private format: string = '%{public}s, %{public}s' + + constructor(prefix: string) { + this.prefix = prefix + this.domain = 0xFF00 + } + + debug(...args: any[]) { + hilog.debug(this.domain, this.prefix, this.format, args) + } + + info(...args: any[]) { + hilog.info(this.domain, this.prefix, this.format, args) + } + + warn(...args: any[]) { + hilog.warn(this.domain, this.prefix, this.format, args) + } + + error(...args: any[]) { + hilog.error(this.domain, this.prefix, this.format, args) + } +} + +export default new Logger('[GamePuzzle]') \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/model/PictureItem.ts b/media/GamePuzzle/entry/src/main/ets/model/PictureItem.ts new file mode 100644 index 0000000000000000000000000000000000000000..f70e7a0d89ab97da5d571f08da8986462e31a416 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/model/PictureItem.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ +import image from '@ohos.multimedia.image' + +export default class PictureItem { + public index: number + public pixelMap: image.PixelMap + + constructor(index: number, pixelMap: image.PixelMap) { + this.index = index + this.pixelMap = pixelMap + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/ets/pages/Index.ets b/media/GamePuzzle/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a3a8fe3ab7bd04a3373e639f0f6b4391a51dfa8 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +import mediaQuery from '@ohos.mediaquery' +import mediaLibrary from '@ohos.multimedia.mediaLibrary' +import GameRules from "../model/GameRules" +import ImageModel from "../model/ImageModel" +import ImagePicker from '../common/ImagePicker' +import Logger from '../model/Logger' +import PictureItem from '../model/PictureItem' +import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl' + +const PERMISSIONS: Array = ['ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.MEDIA_LOCATION'] +const IMAGE_SIZE: number = px2vp(640) +const GAME_TIME: number = 300 // 游戏时长 +const TAG: string = 'Index' + +@Entry +@Component +struct Index { + private listener = mediaQuery.matchMediaSync('screen and (min-aspect-ratio: 1.5) or (orientation: landscape)') + private ImageModel: ImageModel = new ImageModel(getContext(this)) + private game: GameRules = new GameRules() + @StorageLink('isGameStart') isGameStart: boolean = false + private timer: number = -1 + private isRefresh: boolean = false + @State numArray: PictureItem[] = [] + @State imgDatas: Array = [] + @State @Watch("onTimeOver") gameTime: number = GAME_TIME + @State @Watch("onImageChange") index: number = 0 + @State isLand: boolean = false + onLand = (mediaQueryResult) => { + console.info(`[eTSMediaQuery.Index]onLand: mediaQueryResult.matches=${mediaQueryResult.matches}`) + this.isLand = mediaQueryResult.matches + } + + async aboutToAppear() { + this.listener.on('change', this.onLand) + await abilityAccessCtrl.createAtManager().requestPermissionsFromUser(getContext(this), PERMISSIONS) + this.imgDatas = await this.ImageModel.getAllImg() + Logger.info(TAG, `images = ${this.imgDatas.length}`) + this.numArray = await this.ImageModel.splitPic(this.index) + } + + onTimeOver() { + if (this.gameTime == 0) { + this.isGameStart = false + AlertDialog.show({ message: 'TimeOver' }) + clearInterval(this.timer) + } + } + + async onImageChange() { + this.isRefresh = true + this.dialogController.close() + this.numArray = [] + this.numArray = await this.ImageModel.splitPic(this.index) + this.init() + this.isRefresh = false + } + + init() { + this.gameTime = GAME_TIME + clearInterval(this.timer) + } + + gameOver() { + let count = 0 + for (let i = 0;i < 7; i++) { + if (this.numArray[i].index == i) { + count++ + } else { + count = 0 + break + } + } + if (count === 7) { + this.isGameStart = false + AlertDialog.show({ message: $r('app.string.congratulations') }) + clearInterval(this.timer) + this.gameTime = GAME_TIME + } + } + + start() { + this.init() + this.timer = setInterval(() => { + this.gameTime-- + }, 1000) + } + + dialogController: CustomDialogController = new CustomDialogController({ + builder: ImagePicker({ + imageDatas: this.imgDatas, + index: $index + }), + autoCancel: true, + gridCount: 12 + }) + + @Builder + ImageShow() { + Image(this.imgDatas[this.index].uri) + .width(IMAGE_SIZE) + .height(275) + .objectFit(ImageFit.Fill) + .onClick(async () => { + if (this.isRefresh) { + return + } + this.imgDatas = await this.ImageModel.getAllImg() + setTimeout(() => { + this.dialogController.open() + }, 200) + }) + } + + @Builder + ImageGrid(leftMargin: number, topMargin: number) { + Grid() { + ForEach(this.numArray, (item, index) => { + GridItem() { + Image(item.pixelMap) + .width('99%') + .objectFit(ImageFit.Fill) + .height(90) + } + .backgroundColor(item.pixelMap === undefined ? "#f5f5f5" : "#ffdead") + .onClick(() => { + if (this.isRefresh) { + return + } + if (this.isGameStart) { + this.isRefresh = true + this.numArray = this.game.gameInit(index, this.numArray) + this.gameOver() + this.isRefresh = false + } + }) + }) + } + .columnsTemplate('1fr 1fr 1fr') + .columnsGap(2) + .rowsGap(2) + .width(IMAGE_SIZE) + .height(275) + .margin({ left: leftMargin, top: topMargin }) + } + + build() { + Column() { + Row() { + Text(`Time:0${Math.floor(this.gameTime / 60)}:${this.gameTime % 60 < 10 ? '0' + this.gameTime % 60 : this.gameTime % 60}`) + .margin({ top: 5, bottom: 5 }) + } + + if (this.imgDatas.length > 0) { + if (this.isLand) { + Row() { + this.ImageShow() + this.ImageGrid(10, 0) + } + .margin({ top: 5 }) + } else { + Column() { + this.ImageShow() + this.ImageGrid(0, 5) + } + .margin({ top: 5 }) + } + } + Button($r('app.string.start'), { type: ButtonType.Capsule, stateEffect: true }) + .height(50) + .width('100%') + .fontSize(18) + .margin({ top: 5 }) + .backgroundColor(this.isGameStart ? $r('app.color.forbid') : $r('app.color.allow')) + .enabled(!this.isGameStart) + .onClick(() => { + this.isGameStart = true + this.start() + this.numArray = this.game.gameBegin(this.numArray) + }) + + Button($r('app.string.restart'), { type: ButtonType.Capsule, stateEffect: true }) + .height(50) + .width('100%') + .fontSize(18) + .margin({ top: 5 }) + .backgroundColor(this.isGameStart ? $r('app.color.allow') : $r('app.color.forbid')) + .enabled(this.isGameStart) + .onClick(() => { + this.isGameStart = true + this.start() + this.numArray = this.game.gameBegin(this.numArray) + }) + } + .width('100%') + .height('100%') + .padding({ left: '1%', right: '1%' }) + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/module.json5 b/media/GamePuzzle/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5638aa4245efe9eb18444258469e32b60370af0a --- /dev/null +++ b/media/GamePuzzle/entry/src/main/module.json5 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2023 Huawei Device 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. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "srcEntrance": "./ets/Application/AbilityStage.ts", + "description": "$string:entry_desc", + "mainElement": "MainAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "metadata": [ + { + "name": "ArkTSPartialUpdate", + "value": "true" + } + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/MainAbility/MainAbility.ts", + "description": "$string:MainAbility_desc", + "icon": "$media:icon", + "label": "$string:MainAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + { + "name": "ohos.permission.READ_MEDIA" + }, + { + "name": "ohos.permission.WRITE_MEDIA" + }, + { + "name": "ohos.permission.MEDIA_LOCATION" + } + ] + } +} diff --git a/media/GamePuzzle/entry/src/main/resources/base/element/color.json b/media/GamePuzzle/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..5ec698badb6f68373c2030be3d92ff969710ea17 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/base/element/color.json @@ -0,0 +1,16 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + }, + { + "name": "forbid", + "value": "#E5E5E5" + }, + { + "name": "allow", + "value": "#0D9FFB" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/resources/base/element/string.json b/media/GamePuzzle/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..4dc840f96d6f3d00dbbd76c920fb16700b83743a --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/base/element/string.json @@ -0,0 +1,36 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "GamePuzzle" + }, + { + "name": "start", + "value": "Start" + }, + { + "name": "restart", + "value": "Restart" + }, + { + "name": "cancel", + "value": "Cancel" + }, + { + "name": "conform", + "value": "Conform" + }, + { + "name": "congratulations", + "value": "Congratulations!" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/resources/base/media/icon.png b/media/GamePuzzle/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/media/GamePuzzle/entry/src/main/resources/base/media/icon.png differ diff --git a/media/GamePuzzle/entry/src/main/resources/base/profile/main_pages.json b/media/GamePuzzle/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/media/GamePuzzle/entry/src/main/resources/en/element/string.json b/media/GamePuzzle/entry/src/main/resources/en/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..936d7161126709c786e11ad3767a5a0bc5b83145 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/en/element/string.json @@ -0,0 +1,36 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "Description" + }, + { + "name": "MainAbility_desc", + "value": "Description" + }, + { + "name": "MainAbility_label", + "value": "Game Puzzle" + }, + { + "name": "start", + "value": "Start" + }, + { + "name": "restart", + "value": "Restart" + }, + { + "name": "cancel", + "value": "Cancel" + }, + { + "name": "conform", + "value": "OK" + }, + { + "name": "congratulations", + "value": "Congratulations!" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/resources/en_US/element/string.json b/media/GamePuzzle/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/resources/zh/element/string.json b/media/GamePuzzle/entry/src/main/resources/zh/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..e6c30927a34b389320eac6ee14252149feda044b --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/zh/element/string.json @@ -0,0 +1,36 @@ +{ + "string": [ + { + "name": "entry_desc", + "value": "description" + }, + { + "name": "MainAbility_desc", + "value": "description" + }, + { + "name": "MainAbility_label", + "value": "GamePuzzle" + }, + { + "name": "start", + "value": "开始" + }, + { + "name": "restart", + "value": "重新开始" + }, + { + "name": "cancel", + "value": "取消" + }, + { + "name": "conform", + "value": "提交" + }, + { + "name": "congratulations", + "value": "恭喜您!" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/main/resources/zh_CN/element/string.json b/media/GamePuzzle/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/media/GamePuzzle/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/Application/TestAbilityStage.ts b/media/GamePuzzle/entry/src/ohosTest/ets/Application/TestAbilityStage.ts new file mode 100644 index 0000000000000000000000000000000000000000..166eb514175ff07369849cd4b33313069de561ad --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/Application/TestAbilityStage.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import AbilityStage from '@ohos.app.ability.AbilityStage'; + +export default class TestAbilityStage extends AbilityStage { + onCreate() { + console.log("[Demo] TestAbilityStage onCreate") + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/test/Ability.test.ets b/media/GamePuzzle/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..8abf7f2f44c0e56110df8c09b2524a4ca37bc993 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/test/List.test.ets b/media/GamePuzzle/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd0ef790a0e6756eaa7edd6cd3f3425ed60211af --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import appTest from './app.test' + +export default function testsuite() { + appTest() +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/test/app.test.ets b/media/GamePuzzle/entry/src/ohosTest/ets/test/app.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..78b9e7800b51fe1c76019b116ec58eb1093d5045 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/test/app.test.ets @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' +import { UiDriver, BY, UiComponent, MatchPattern } from '@ohos.uitest' +import featureAbility from '@ohos.ability.featureAbility' +import hilog from '@ohos.hilog' + +const TAG = '[Sample_GamePuzzle]' +const DOMAIN = 0xF811 +const BUNDLE = 'GamePuzzle_' + +export default function appTest() { + describe('appTest', function () { + it(BUNDLE + 'StartAbility_001', 0, async function (done) { + let want = { + bundleName: "ohos.samples.gamepuzzle", + abilityName: "MainAbility" + } + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + abilityDelegator.startAbility(want, (err, data) => { + hilog.info(DOMAIN, TAG, BUNDLE + 'StartAbility_001,err.code:' + err.code) + expect(0).assertEqual(err.code) + done() + hilog.info(DOMAIN, TAG, BUNDLE + 'StartAbility_001 end') + }) + }) + + /** + * 进入页面 + */ + it(BUNDLE + 'CreateFunction_001', 0, async function () { + hilog.info(DOMAIN, TAG, BUNDLE + 'CreateFunction_001 begin') + let driver = await UiDriver.create() + await driver.delayMs(1000) + // 点击允许进入 + hilog.info(DOMAIN, TAG, BUNDLE + 'CreateFunction_001 enter') + await driver.assertComponentExist(BY.text('允许')) + let btnCreate = await driver.findComponent(BY.text('允许')) + await btnCreate.click() + await driver.delayMs(1000) + hilog.info(DOMAIN, TAG, BUNDLE + 'CreateFunction_001 end') + }) + }) +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ets b/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..e3f6e911d3fffba1e1795c60ed1ee4db15b386fd --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,48 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ts b/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ts new file mode 100644 index 0000000000000000000000000000000000000000..a92a8df1fc9d4af0df528804fbe87189babcd384 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/testability/TestAbility.ts @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import Ability from '@ohos.app.ability.Ability'; +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; + +export default class TestAbility extends Ability { + onCreate(want, launchParam) { + console.log('TestAbility onCreate'); + } + + onDestroy() { + console.log('TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage) { + console.log('TestAbility onWindowStageCreate'); + windowStage.loadContent("TestAbility/pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)); + }) + + let abilityDelegator: any; + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); + let abilityDelegatorArguments: any; + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments(); + console.info('start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite); + } + + onWindowStageDestroy() { + console.log('TestAbility onWindowStageDestroy'); + } + + onForeground() { + console.log('TestAbility onForeground'); + } + + onBackground() { + console.log('TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/testability/pages/index.ets b/media/GamePuzzle/entry/src/ohosTest/ets/testability/pages/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..7d93696fbcc27bfa21f70894e650da12023734ca --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/testability/pages/index.ets @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import router from '@ohos.router' + +@Entry +@Component +struct Index { + aboutToAppear() { + console.info('TestAbility index aboutToAppear') + } + + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + } + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(() => { + }) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/media/GamePuzzle/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b0f409c3e76cdbfac374a5fed8463a5d6ec9834 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +import TestRunner from '@ohos.application.testRunner' +import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +function translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s it', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun' + ]) + let targetParams = '' + for (const key in parameters) { + if (keySet.has(key)) { + targetParams = `${targetParams} ${key} ${parameters[key]}` + } + } + return targetParams.trim() +} + +async function onAbilityCreateCallback() { + console.log("onAbilityCreateCallback") +} + +async function addAbilityMonitorCallback(err: any) { + console.info("addAbilityMonitorCallback : " + JSON.stringify(err)) +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + console.info("OpenHarmonyTestRunner OnPrepare ") + } + + async onRun() { + console.log('OpenHarmonyTestRunner onRun run') + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + } + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + cmd += ' ' + translateParamsToString(abilityDelegatorArguments.parameters) + var debug = abilityDelegatorArguments.parameters["-D"] + if (debug == 'true') { + cmd += ' -D' + } + console.info('cmd : ' + cmd) + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + console.info('executeShellCommand : err : ' + JSON.stringify(err)) + console.info('executeShellCommand : data : ' + d.stdResult) + console.info('executeShellCommand : data : ' + d.exitCode) + }) + console.info('OpenHarmonyTestRunner onRun end') + } +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/module.json5 b/media/GamePuzzle/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a63ae7f49d2053d7220ab8ec46e1c0a04e675db --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/module.json5 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "srcEntrance": "./ets/Application/TestAbilityStage.ts", + "description": "$string:entry_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "uiSyntax": "ets", + "abilities": [ + { + "name": "TestAbility", + "srcEntrance": "./ets/TestAbility/TestAbility.ts", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "visible": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/media/GamePuzzle/entry/src/ohosTest/resources/base/element/color.json b/media/GamePuzzle/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..1bbc9aa9617e97c45440e1d3d66afc1154837012 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "white", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/resources/base/element/string.json b/media/GamePuzzle/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..36d4230c53e9f5a07ae343ad8dc9808341975e3b --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "entry_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/media/GamePuzzle/entry/src/ohosTest/resources/base/media/icon.png b/media/GamePuzzle/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/media/GamePuzzle/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/media/GamePuzzle/entry/src/ohosTest/resources/base/profile/test_pages.json b/media/GamePuzzle/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..fcef82b4dfc18e28106ff9ecd1c8b48ec74d18a4 --- /dev/null +++ b/media/GamePuzzle/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "TestAbility/pages/index" + ] +} diff --git a/media/GamePuzzle/hvigorfile.ts b/media/GamePuzzle/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..6478186902c0c1ad7c966a929c7d6b7d8ae7a9f3 --- /dev/null +++ b/media/GamePuzzle/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/media/GamePuzzle/package.json b/media/GamePuzzle/package.json new file mode 100644 index 0000000000000000000000000000000000000000..93436853c1190bb7cc026ef719fb3de350979134 --- /dev/null +++ b/media/GamePuzzle/package.json @@ -0,0 +1,18 @@ +{ + "license": "ISC", + "devDependencies": {}, + "name": "gamepuzzle", + "ohos": { + "org": "huawei", + "directoryLevel": "project", + "buildTool": "hvigor" + }, + "description": "example description", + "repository": {}, + "version": "1.0.0", + "dependencies": { + "@ohos/hypium": "1.0.5", + "@ohos/hvigor-ohos-plugin": "1.4.0", + "@ohos/hvigor": "1.4.0" + } +} diff --git a/media/GamePuzzle/screenshot/devices/change.jpeg b/media/GamePuzzle/screenshot/devices/change.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..963ec9b91f640573334711e3a2cee8adb198f7a9 Binary files /dev/null and b/media/GamePuzzle/screenshot/devices/change.jpeg differ diff --git a/media/GamePuzzle/screenshot/devices/running.jpeg b/media/GamePuzzle/screenshot/devices/running.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f39ce3107f41b74e4a72346a02b96a518c019f68 Binary files /dev/null and b/media/GamePuzzle/screenshot/devices/running.jpeg differ diff --git a/media/Image/.gitignore b/media/Image/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dc4e6353bf3caf74c5953d0bec81c72a3635bf33 --- /dev/null +++ b/media/Image/.gitignore @@ -0,0 +1,9 @@ +/node_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy \ No newline at end of file diff --git a/media/Image/AppScope/app.json5 b/media/Image/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..105e4ffe36b0bcd3ecfd9ccb975e0a10f3acc800 --- /dev/null +++ b/media/Image/AppScope/app.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Huawei Device 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. + */ + +{ + "app": { + "bundleName": "ohos.samples.image", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true, + "singleton": true + } +} diff --git a/media/Image/AppScope/resources/base/element/string.json b/media/Image/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..939880d470ce40a0daf6cc173a9876b468294e84 --- /dev/null +++ b/media/Image/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "etsImage" + } + ] +} diff --git a/media/Image/AppScope/resources/base/media/app_icon.png b/media/Image/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/media/Image/AppScope/resources/base/media/app_icon.png differ diff --git a/media/Image/README.md b/media/Image/README.md new file mode 100644 index 0000000000000000000000000000000000000000..90a7cee909ec08e70a906c01ec4df01c9c414853 --- /dev/null +++ b/media/Image/README.md @@ -0,0 +1,39 @@ +# Image Processing + +### Introduction + +This sample demonstrates the image processing function. + +In this sample, [\