diff --git a/BptaUseResources/AppScope/app.json5 b/BptaUseResources/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f82344ddd9c9ca6ca1f4c421296f5b9214310dcc --- /dev/null +++ b/BptaUseResources/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.bptauseresources", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/BptaUseResources/AppScope/resources/base/element/string.json b/BptaUseResources/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..d438b02b506772cc4d7087b1c2589b7fee2179b4 --- /dev/null +++ b/BptaUseResources/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "BptaUseResources" + } + ] +} diff --git a/BptaUseResources/AppScope/resources/base/media/background.png b/BptaUseResources/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/BptaUseResources/AppScope/resources/base/media/background.png differ diff --git a/BptaUseResources/AppScope/resources/base/media/foreground.png b/BptaUseResources/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/BptaUseResources/AppScope/resources/base/media/foreground.png differ diff --git a/BptaUseResources/AppScope/resources/base/media/layered_image.json b/BptaUseResources/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/BptaUseResources/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/BptaUseResources/build-profile.json5 b/BptaUseResources/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/BptaUseResources/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/BptaUseResources/entry/.gitignore b/BptaUseResources/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/BptaUseResources/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/BptaUseResources/entry/build-profile.json5 b/BptaUseResources/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/BptaUseResources/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/BptaUseResources/entry/hvigorfile.ts b/BptaUseResources/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/BptaUseResources/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/BptaUseResources/entry/obfuscation-rules.txt b/BptaUseResources/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/BptaUseResources/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/BptaUseResources/entry/oh-package.json5 b/BptaUseResources/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/BptaUseResources/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets b/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/BptaUseResources/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets b/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ec6438cf8ebaf8f61d0b3276bae9f9d5d6f6223 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/Bluetooth.ets @@ -0,0 +1,34 @@ +/** + * 最佳实践:合理使用蓝牙资源 + */ + +// [Start blue_tooth] +import { UIAbility } from '@kit.AbilityKit'; +import { ble } from '@kit.ConnectivityKit'; + +// [StartExclude blue_tooth] +const scanFilter: ble.ScanFilter = {} +const scanOptions: ble.ScanOptions = {} +const setting: ble.AdvertiseSetting = {} +const advData: ble.AdvertiseData = { + serviceUuids: [], + manufactureData: [], + serviceData: [] +} +const advResponse = undefined +// [EndExclude blue_tooth] +export default class EntryAbility extends UIAbility { + // ... + onForeground(): void { + //Initiate Ble scan and broadcast as required by the service at the foreground + ble.startBLEScan([scanFilter], scanOptions); + ble.startAdvertising(setting, advData, advResponse); + } + + onBackground(): void { + // Return to the background to stop the Ble scanning and broadcast, which is the same as the application + ble.stopBLEScan(); + ble.stopAdvertising(); + } +} +// [End blue_tooth] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Gps.ets b/BptaUseResources/entry/src/main/ets/pages/Gps.ets new file mode 100644 index 0000000000000000000000000000000000000000..b43d05d2255d1b3044689f33ac35ab3094565ce1 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/Gps.ets @@ -0,0 +1,37 @@ +/** + * 最佳实践:合理使用GPS资源 + */ + +// [Start gps_resources] +import { UIAbility } from '@kit.AbilityKit'; +import { geoLocationManager } from '@kit.LocationKit'; + +// [StartExclude gps_resources] +let locationChange = (location: geoLocationManager.Location): void => { + console.log('locationChanger:data:' + JSON.stringify(location)); +}; +// [EndExclude gps_resources] + +export default class EntryAbility extends UIAbility { + // ... + onForeground(): void { + // Create a location request based on service requirements at the foreground + let requestInfo: geoLocationManager.LocationRequest = { + 'priority': geoLocationManager.LocationRequestPriority.ACCURACY, + 'timeInterval': 0, + 'distanceInterval': 0, + 'maxAccuracy': 0 + }; + let locationChange = (location: geoLocationManager.Location): void => { + console.log('locationChanger:data:' + JSON.stringify(location)); + }; + //The change of the listening position + geoLocationManager.on('locationChange', requestInfo, locationChange); + } + + onBackground(): void { + //The backstage cancels the listening + geoLocationManager.off('locationChange', locationChange); + } +} +// [End gps_resources] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Https.ets b/BptaUseResources/entry/src/main/ets/pages/Https.ets new file mode 100644 index 0000000000000000000000000000000000000000..04a30f9209197ad6de30c9e48017c40f5e74de7d --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/Https.ets @@ -0,0 +1,25 @@ +/** + * 最佳实践:合理使用网络资源 + */ + +// [Start http_resources] +import { UIAbility } from '@kit.AbilityKit'; +import { http } from '@kit.NetworkKit'; + +export default class EntryAbility extends UIAbility { + // ... + onForeground(): void { + // Create an HTTP request based on the service requirements at the foreground + let httpRequest = http.createHttp(); + // ... + } + + onBackground(): void { + // [StartExclude http_resources] + let httpRequest = http.createHttp(); + // [EndExclude http_resources] + // Go back to the background and release the http request + httpRequest.destroy(); + } +} +// [End http_resources] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Index.ets b/BptaUseResources/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/Sensor.ets b/BptaUseResources/entry/src/main/ets/pages/Sensor.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c2a2b938ec5e38075841f923b0ba55f2be899f8 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/Sensor.ets @@ -0,0 +1,25 @@ +/** + * 最佳实践:合理使用传感器资源 + */ + +// [Start sensor_resources] +import { UIAbility } from '@kit.AbilityKit'; +import { sensor } from '@kit.SensorServiceKit'; + +export default class EntryAbility extends UIAbility { + // ... + onForeground(): void { + //In the foreground, listen to the required type of sensor based on the service requirements + sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => { + console.info("Succeededinobtainingdata.x:" + data.x + "y:" + data.y + "z:" + data.z); + }, { + interval: 100000000 + }); + } + + onBackground(): void { + //The backstage cancels the listening + sensor.off(sensor.SensorId.ACCELEROMETER); + } +} +// [End sensor_resources] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/music/AudioRenderer.ets b/BptaUseResources/entry/src/main/ets/pages/music/AudioRenderer.ets new file mode 100644 index 0000000000000000000000000000000000000000..b58b4e9b4ce845eac5e91f594a41a9e9b00db8d9 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/music/AudioRenderer.ets @@ -0,0 +1,52 @@ +/** + * 最佳实践:合理使用音频资源 + * 场景一:播音场景(audioRenderer) + */ + +// [Start audio_renderer] +import { UIAbility } from '@kit.AbilityKit'; +import { audio } from '@kit.AudioKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +// [StartExclude audio_renderer] +let audioStreamInfo: audio.AudioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, // 采样率。 + channels: audio.AudioChannel.CHANNEL_2, // 通道。 + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式。 + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式。 +}; + +const audioRendererOptions: audio.AudioRendererOptions = { + streamInfo: audioStreamInfo, + rendererInfo: { + usage: audio.StreamUsage.STREAM_USAGE_UNKNOWN, + rendererFlags: 1 + } +} + +let audioRenderer: audio.AudioRenderer + +audio.createAudioRenderer(audioRendererOptions, (err, data) => { + if (err) { + console.error(`Invoke createAudioRenderer failed, code is ${err.code}, message is ${err.message}`); + return; + } else { + console.info('Invoke createAudioRenderer succeeded.'); + let audioRenderer = data; + } +}); +// [EndExclude audio_renderer] + +export default class EntryAbility extends UIAbility { + + // Create an AudioRenderer based on the service requirements at the foreground + onForeground(): void { + audio.createAudioRenderer(audioRendererOptions, ((err: BusinessError) => {})); + } + + onBackground(): void { + // Return to the background to stop or pause + audioRenderer.stop((err: BusinessError) => {}); + } +} +// [End audio_renderer] diff --git a/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets b/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets new file mode 100644 index 0000000000000000000000000000000000000000..d15b2d401e4438544e36a161e5657e0da7b4369a --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/music/AvPlayer.ets @@ -0,0 +1,50 @@ +/** + * 最佳实践:合理使用音频资源 + * 场景二:播音场景(AVPlayer) + */ + +import { fileIo as fs } from '@kit.CoreFileKit'; +// [Start av_player] +import { UIAbility } from '@kit.AbilityKit'; +import { media } from '@kit.MediaKit'; + +// [StartExclude av_player] +let avPlayer: media.AVPlayer +// [EndExclude av_player] + +export default class EntryAbility extends UIAbility { + // ... + onForeground(): void { + //Playing according to service requirements in the foreground + avPlayer.play(); + } + + onBackground(): void { + // Return to the background to stop playing or pause + avPlayer.stop(); // Or pause(); + } +} +// [End av_player] + +/** + * 最佳实践:合理使用音频资源 + * 场景五:播音场景(SoundPool) + */ + +let soundId: number; +let streamId: number; +let uri: string; +let soundPool: media.SoundPool; +const SoundPool = async () => { + // [Start sound_pool] + //Construct the audio stream to play + await fs.open('/test_01.mp3', fs.OpenMode.READ_ONLY).then((file: fs.File) => { + console.info("filefd:" + file.fd); + uri = 'fd://' + (file.fd).toString() + }); // '/test_01.mp3' is used as an example. The path of the file needs to be transferred + soundId = await soundPool.load(uri); + //The foreground scene starts to play + streamId = await soundPool.play(soundId); + //Stop playing in the background scenario: soundPool.stop (streamId); + // [End sound_pool] +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp b/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23a867c9363ded2a61b64c68845df72723b832d1 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/music/OpenSL.cpp @@ -0,0 +1,31 @@ +/** + * 最佳实践:合理使用音频资源 + * 场景三:播音场景(OpenSL ES) + */ + +// [Start open_sl_es] +//The foreground scene starts to play +SLPlayItfplayItf=nullptr; +(*pcmPlayerObject)->GetInterface(pcmPlayerObject,SL_IID_PLAY,&playItf); +(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_PLAYING); +// Stop playing the background scene +(*playItf)->SetPlayState(playItf,SL_PLAYSTATE_STOPPED); +(*pcmPlayerObject)->Destroy(pcmPlayerObject); +(*engineObject)->Destroy(engineObject); +// [End open_sl_es] + +/** + * 最佳实践:合理使用音频资源 + * 场景四:播音场景(OHAudio) + */ + +// [Start oh_audio] +//Construct the audio stream to play +OH_AudioRenderer*audioRenderer; +ret=OH_AudioStreamBuilder_GenerateRenderer(builder,&audioRenderer); + +//The foreground scene starts to play +ret=OH_AudioRenderer_Start(audioRenderer); +// Stop playing the background scene +ret=OH_AudioRenderer_Stop(audioRenderer); +// [End oh_audio] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/ets/pages/music/Recording.ets b/BptaUseResources/entry/src/main/ets/pages/music/Recording.ets new file mode 100644 index 0000000000000000000000000000000000000000..9131f77973c058da893aba3e6f942c5dc92be035 --- /dev/null +++ b/BptaUseResources/entry/src/main/ets/pages/music/Recording.ets @@ -0,0 +1,58 @@ +/** + * 最佳实践:合理使用音频资源 + * 场景六:录音场景 + */ + +// [Start recording_audio_capturer] +import { UIAbility } from '@kit.AbilityKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { audio } from '@kit.AudioKit'; +// [StartExclude recording_audio_capturer] +let audioStreamInfo: audio.AudioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, // 采样率。 + channels: audio.AudioChannel.CHANNEL_2, // 通道。 + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式。 + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式。 +}; + +let audioCapturerInfo: audio.AudioCapturerInfo = { + source: audio.SourceType.SOURCE_TYPE_MIC, // 音源类型:Mic音频源。根据业务场景配置,参考SourceType。 + capturerFlags: 0 // 音频采集器标志。 +}; + +let audioCapturerOptions: audio.AudioCapturerOptions = { + streamInfo: audioStreamInfo, + capturerInfo: audioCapturerInfo +}; +let audioCapturer: audio.AudioCapturer; + +audio.createAudioCapturer(audioCapturerOptions, (err, data) => { + if (err) { + console.error(`Invoke createAudioCapturer failed, code is ${err.code}, message is ${err.message}`); + } else { + console.info('Invoke createAudioCapturer succeeded.'); + let audioCapturer = data; + } +}); +// [EndExclude recording_audio_capturer] +export default class EntryAbility extends UIAbility { + // ... + + onForeground(): void { + //Apply for the resources required by the system, or reapply for the resources released in onBackground () + audio.createAudioCapturer(audioCapturerOptions, (err, data) => { + if (err) { + console.error(`InvokecreateAudioCapturerfailed,codeis${err.code},messageis${err.message}`); + } else { + console.info('InvokecreateAudioCapturersucceeded.'); + } + }); + } + + onBackground(): void { + //Release resources when the UI is invisible + audioCapturer.stop((err: BusinessError) => {}); + //Or pause(); + } +} +// [End recording_audio_capturer] \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/module.json5 b/BptaUseResources/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/BptaUseResources/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/resources/base/element/color.json b/BptaUseResources/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/resources/base/element/float.json b/BptaUseResources/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/BptaUseResources/entry/src/main/resources/base/element/string.json b/BptaUseResources/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/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/BptaUseResources/entry/src/main/resources/base/media/background.png b/BptaUseResources/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/BptaUseResources/entry/src/main/resources/base/media/background.png differ diff --git a/BptaUseResources/entry/src/main/resources/base/media/foreground.png b/BptaUseResources/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/BptaUseResources/entry/src/main/resources/base/media/foreground.png differ diff --git a/BptaUseResources/entry/src/main/resources/base/media/layered_image.json b/BptaUseResources/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/resources/base/media/startIcon.png b/BptaUseResources/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/BptaUseResources/entry/src/main/resources/base/media/startIcon.png differ diff --git a/BptaUseResources/entry/src/main/resources/base/profile/backup_config.json b/BptaUseResources/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/main/resources/base/profile/main_pages.json b/BptaUseResources/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/BptaUseResources/entry/src/main/resources/dark/element/color.json b/BptaUseResources/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/BptaUseResources/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/mock/mock-config.json5 b/BptaUseResources/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/BptaUseResources/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets b/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/BptaUseResources/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets b/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/BptaUseResources/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/ohosTest/module.json5 b/BptaUseResources/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/BptaUseResources/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/BptaUseResources/entry/src/test/List.test.ets b/BptaUseResources/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/BptaUseResources/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/BptaUseResources/entry/src/test/LocalUnit.test.ets b/BptaUseResources/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/BptaUseResources/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/BptaUseResources/hvigor/hvigor-config.json5 b/BptaUseResources/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/BptaUseResources/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/BptaUseResources/oh-package-lock.json5 b/BptaUseResources/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/BptaUseResources/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/BptaUseResources/oh-package.json5 b/BptaUseResources/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a8aff0c5aff22d78aa26fd19c3861f4320e951ff --- /dev/null +++ b/BptaUseResources/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/BptaUseSoftware/AppScope/app.json5 b/BptaUseSoftware/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b45df22b13e2fd1ac2e5308a3ef1a14cadcaa1e6 --- /dev/null +++ b/BptaUseSoftware/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.bptausesoftware", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/BptaUseSoftware/AppScope/resources/base/element/string.json b/BptaUseSoftware/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9d052946416fb366c7efe4fec63c1e5cc4b0f26a --- /dev/null +++ b/BptaUseSoftware/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "BptaUseSoftware" + } + ] +} diff --git a/BptaUseSoftware/AppScope/resources/base/media/background.png b/BptaUseSoftware/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/BptaUseSoftware/AppScope/resources/base/media/background.png differ diff --git a/BptaUseSoftware/AppScope/resources/base/media/foreground.png b/BptaUseSoftware/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/BptaUseSoftware/AppScope/resources/base/media/foreground.png differ diff --git a/BptaUseSoftware/AppScope/resources/base/media/layered_image.json b/BptaUseSoftware/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/BptaUseSoftware/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/BptaUseSoftware/build-profile.json5 b/BptaUseSoftware/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/BptaUseSoftware/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/.gitignore b/BptaUseSoftware/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/BptaUseSoftware/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/BptaUseSoftware/entry/build-profile.json5 b/BptaUseSoftware/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/BptaUseSoftware/entry/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/hvigorfile.ts b/BptaUseSoftware/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/BptaUseSoftware/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/BptaUseSoftware/entry/obfuscation-rules.txt b/BptaUseSoftware/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/BptaUseSoftware/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/BptaUseSoftware/entry/oh-package.json5 b/BptaUseSoftware/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/BptaUseSoftware/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets b/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..625a365d3d936eb5b4abe61d3856f34e8b3ead68 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,46 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext() + AppStorage.setOrCreate('uiContext', uiContext); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/BptaUseSoftware/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets b/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets new file mode 100644 index 0000000000000000000000000000000000000000..edd7b7ebffaced2878a679fdceed10a49d0ba5fb --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/Audio.ets @@ -0,0 +1,51 @@ +/** + * 最佳实践:合理使用音频播放 + */ + +// [Start audio_bpta] +import { fileIo as fs } from '@kit.CoreFileKit'; +// [StartExclude audio_bpta] +import { audio } from '@kit.AudioKit'; + +let audioStreamInfo: audio.AudioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, + channels: audio.AudioChannel.CHANNEL_2, + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW +}; + +let audioRendererInfo: audio.AudioRendererInfo = { + usage: audio.StreamUsage.STREAM_USAGE_MUSIC, + rendererFlags: 0 +}; + +let audioRendererOptions: audio.AudioRendererOptions = { + streamInfo: audioStreamInfo, + rendererInfo: audioRendererInfo +}; +let audioRenderer: audio.AudioRenderer; +audio.createAudioRenderer(audioRendererOptions, (err, data) => { + if (err) { + console.error(`Invoke createAudioRenderer failed, code is ${err.code}, message is ${err.message}`); + return; + } else { + console.info('Invoke createAudioRenderer succeeded.'); + let audioRenderer = data; + } +}); +// [EndExclude audio_bpta] + +const uiContext: UIContext | undefined = AppStorage.get('uiContext'); +let context = uiContext!.getHostContext()!; + +async function read() { + const bufferSize: number = await audioRenderer.getBufferSize(); + let path = context.filesDir; // Path of the file + + const filePath = path + '/voice_call_data.wav'; // Prohibit the file from being played silently + let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY); //Open the file + let buf = new ArrayBuffer(bufferSize); + let readsize: number = await fs.read(file.fd, buf); //Read the file content + let writeSize: number = await audioRenderer.write(buf); //Play the file content +} +// [End audio_bpta] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Download.ets b/BptaUseSoftware/entry/src/main/ets/pages/Download.ets new file mode 100644 index 0000000000000000000000000000000000000000..ebe216c8ba72a5765622998f9a7d5df6162277d5 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/Download.ets @@ -0,0 +1,21 @@ +/** + * 最佳实践:后台合理使用上传下载 + * 场景二:下载 + */ + +import { BusinessError, request } from '@kit.BasicServicesKit'; + +try { + request.downloadFile(getContext(), { + url: 'https://xxxx/xxxxx.hap', //需要下载的文件的服务器地址 + filePath: 'xxx/xxxxx.hap' + }, (err: BusinessError, data: request.DownloadTask) => { + if (err) { + console.error(`Failedtorequestthedownload.Code:${err.code},message:${err.message}`); + return; + } + let downloadTask: request.DownloadTask = data; + }); +} catch (err) { + console.error(`Failedtorequestthedownload.err:${JSON.stringify(err)}`); +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets b/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets new file mode 100644 index 0000000000000000000000000000000000000000..46c3c4f46d75eda0667aa9dde5bd694ec8db7fb4 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/GpsOne.ets @@ -0,0 +1,14 @@ +/** + * 最佳实践:后台合理使用定位导航服务 + * 场景一:方式1 + */ +// [Start bpta_gps_one] +import { geoLocationManager } from '@kit.LocationKit'; + +let requestInfo: geoLocationManager.LocationRequest = { + 'scenario': geoLocationManager.LocationRequestScenario.NO_POWER, + 'timeInterval': 0, + 'distanceInterval': 0, + 'maxAccuracy': 0 +}; +// [End bpta_gps_one] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets b/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets new file mode 100644 index 0000000000000000000000000000000000000000..a3661fd5e8014e3c80410b817e5a8a0c75662ad5 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/GpsTwo.ets @@ -0,0 +1,14 @@ +/** + * 最佳实践:后台合理使用定位导航服务 + * 场景二:方式2 + */ +// [Start bpta_gps_two] +import { geoLocationManager } from '@kit.LocationKit'; + +let requestInfo: geoLocationManager.LocationRequest = { + 'priority': geoLocationManager.LocationRequestPriority.LOW_POWER, + 'timeInterval': 0, + 'distanceInterval': 0, + 'maxAccuracy': 0 +}; +// [End bpta_gps_two] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Index.ets b/BptaUseSoftware/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets b/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets new file mode 100644 index 0000000000000000000000000000000000000000..e0ce546f1396d8ddc9033a13da1bb5ba6d57fb3c --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/LockByApplication.ets @@ -0,0 +1,17 @@ +/** + * 最佳实践:后台合理使用系统资源 + * 场景一:应用直接持锁 + */ +// [Start bpta_lock_by_application] +import { runningLock } from '@kit.BasicServicesKit'; + +// Return to the background to release the lock +runningLock.createRunningLock('running_lock_test', runningLock.RunningLockType.BACKGROUND) + .then((lock: runningLock.RunningLock) => { + lock.unlock(); + console.info('create running lock and unlock success'); + }) + .catch((err: Error) => { + console.error('create running lock failed, err: ' + err); + }); +// [End bpta_lock_by_application] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets b/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets new file mode 100644 index 0000000000000000000000000000000000000000..ba481213a06987c151297f6967ee7eda5af5a0cd --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/LockBySystem.ets @@ -0,0 +1,51 @@ +/** + * 最佳实践:后台合理使用系统资源 + * 场景一:系统帮助应用持锁 + */ + +// [Start bpta_lock_by_system] +import { UIAbility } from '@kit.AbilityKit'; +import { audio } from '@kit.AudioKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +// [StartExclude bpta_lock_by_system] +let audioStreamInfo: audio.AudioStreamInfo = { + samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, + channels: audio.AudioChannel.CHANNEL_2, + sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, + encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW +}; + +let audioRendererInfo: audio.AudioRendererInfo = { + usage: audio.StreamUsage.STREAM_USAGE_MUSIC, + rendererFlags: 0 +}; + +let audioRendererOptions: audio.AudioRendererOptions = { + streamInfo: audioStreamInfo, + rendererInfo: audioRendererInfo +}; +let audioRenderer: audio.AudioRenderer; +audio.createAudioRenderer(audioRendererOptions, (err, data) => { + if (err) { + console.error(`Invoke createAudioRenderer failed, code is ${err.code}, message is ${err.message}`); + return; + } else { + console.info('Invoke createAudioRenderer succeeded.'); + let audioRenderer = data; + } +}); +// [EndExclude bpta_lock_by_system] +export default class EntryAbility extends UIAbility { + // ... + + onForeground(): void { + //Apply for the resources required by the system, or reapply for the resources released in onBackground () + audio.createAudioRenderer(audioRendererOptions,(err: BusinessError) => {}); + } + + onBackground(): void { + //Release resources when the UI is invisible + audioRenderer.stop((err: BusinessError) => {}); + } +} +// [End bpta_lock_by_system] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets b/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets new file mode 100644 index 0000000000000000000000000000000000000000..56f5cb42e1dc13eef4931028aec8a6f32dc47156 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/ets/pages/Upload.ets @@ -0,0 +1,36 @@ +/** + * 最佳实践:后台合理使用上传下载 + * 场景一:上传 + */ +// [Start software_upload] +import { BusinessError, request } from '@kit.BasicServicesKit'; + +const uiContext: UIContext | undefined = AppStorage.get('uiContext'); +let context = uiContext!.getHostContext()!; + +let uploadTask: request.UploadTask; +let uploadConfig: request.UploadConfig = { + url: 'http://www.example.com', //Replace the IP address of the real server manually + header: { 'Accept': '*/*' }, + method: "POST", + files: [{ + filename: "test", + name: "test", + uri: "internal://cache/test.jpg", + type: "jpg" + }], + data: [{ name: "name123", value: "123" }], +}; +try { + //Upload request + request.uploadFile(context, uploadConfig, (err: BusinessError, data: request.UploadTask) => { + if (err) { + console.error(`Failedtorequesttheupload.Code:${err.code},message:${err.message}`); + return; + } + uploadTask = data; + }); +} catch (err) { + console.error(`Failedtorequesttheupload.err:${JSON.stringify(err)}`); +} +// [End software_upload] \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/module.json5 b/BptaUseSoftware/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/resources/base/element/color.json b/BptaUseSoftware/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/resources/base/element/float.json b/BptaUseSoftware/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/BptaUseSoftware/entry/src/main/resources/base/element/string.json b/BptaUseSoftware/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/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/BptaUseSoftware/entry/src/main/resources/base/media/background.png b/BptaUseSoftware/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/BptaUseSoftware/entry/src/main/resources/base/media/background.png differ diff --git a/BptaUseSoftware/entry/src/main/resources/base/media/foreground.png b/BptaUseSoftware/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/BptaUseSoftware/entry/src/main/resources/base/media/foreground.png differ diff --git a/BptaUseSoftware/entry/src/main/resources/base/media/layered_image.json b/BptaUseSoftware/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/resources/base/media/startIcon.png b/BptaUseSoftware/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/BptaUseSoftware/entry/src/main/resources/base/media/startIcon.png differ diff --git a/BptaUseSoftware/entry/src/main/resources/base/profile/backup_config.json b/BptaUseSoftware/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/main/resources/base/profile/main_pages.json b/BptaUseSoftware/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/BptaUseSoftware/entry/src/main/resources/dark/element/color.json b/BptaUseSoftware/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/BptaUseSoftware/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/mock/mock-config.json5 b/BptaUseSoftware/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/BptaUseSoftware/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets b/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/BptaUseSoftware/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets b/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/BptaUseSoftware/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/ohosTest/module.json5 b/BptaUseSoftware/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/BptaUseSoftware/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/BptaUseSoftware/entry/src/test/List.test.ets b/BptaUseSoftware/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/BptaUseSoftware/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/BptaUseSoftware/entry/src/test/LocalUnit.test.ets b/BptaUseSoftware/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/BptaUseSoftware/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/BptaUseSoftware/hvigor/hvigor-config.json5 b/BptaUseSoftware/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/BptaUseSoftware/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/BptaUseSoftware/oh-package-lock.json5 b/BptaUseSoftware/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/BptaUseSoftware/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/BptaUseSoftware/oh-package.json5 b/BptaUseSoftware/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a8aff0c5aff22d78aa26fd19c3861f4320e951ff --- /dev/null +++ b/BptaUseSoftware/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/MemoryDetection/AppScope/app.json5 b/MemoryDetection/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f55ebf3b74153db826890578965cb608c1d4afd3 --- /dev/null +++ b/MemoryDetection/AppScope/app.json5 @@ -0,0 +1,39 @@ +/** + * 最佳实践:使用Asan检测内存错误 + * 场景一:在app.json5中配置环境变量 + */ + +// [Start app_json_environments] +{ + "app": { + "appEnvironments": [ + { + "name": "ASAN_OPTIONS", + "value": "log_exe_name=true abort_on_error=0 print_cmdline=true" // The example is for reference only + }, + ], + // [StartExclude app_json_environments] + "bundleName": "com.example.memorydetection", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + /** + * 最佳实践:使用Asan检测内存错误 + * 场景四:DevEco Studio场景 + */ + // [Start asan_enabled] + "asanEnabled": true, + // [End asan_enabled] + /** + * 最佳实践:使用HWAsan检测内存错误 + * 场景一:配置HWASan-流水线场景 + */ + // [Start hw_asan_enabled] + "hwasanEnabled": true, + // [End hw_asan_enabled] + "icon": "$media:layered_image", + "label": "$string:app_name", + // [EndExclude app_json_environments] + } +} +// [End app_json_environments] \ No newline at end of file diff --git a/MemoryDetection/AppScope/resources/base/element/string.json b/MemoryDetection/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1ec0daf1252e1ff15505bdcea1bcbb3c59ebe4c9 --- /dev/null +++ b/MemoryDetection/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "MemoryDetection" + } + ] +} diff --git a/MemoryDetection/AppScope/resources/base/media/background.png b/MemoryDetection/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/MemoryDetection/AppScope/resources/base/media/background.png differ diff --git a/MemoryDetection/AppScope/resources/base/media/foreground.png b/MemoryDetection/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/MemoryDetection/AppScope/resources/base/media/foreground.png differ diff --git a/MemoryDetection/AppScope/resources/base/media/layered_image.json b/MemoryDetection/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/MemoryDetection/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/MemoryDetection/build-profile.json5 b/MemoryDetection/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9e87e7e6f19020fe21192844709f192cec80fd44 --- /dev/null +++ b/MemoryDetection/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/MemoryDetection/entry/.gitignore b/MemoryDetection/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/MemoryDetection/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/MemoryDetection/entry/build-profile.json5 b/MemoryDetection/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4260b3d220c0c29ff1079f43b1b51649c4f20c9c --- /dev/null +++ b/MemoryDetection/entry/build-profile.json5 @@ -0,0 +1,37 @@ +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + /** + * 最佳实践:使用HWAsan检测内存错误 + * 场景三:配置HWASan-DevEco Studio场景 + */ + // [Start set_arguments] + "arguments": "-DOHOS_ENABLE_HWASAN=ON", + // [End set_arguments] + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/MemoryDetection/entry/hvigorfile.ts b/MemoryDetection/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/MemoryDetection/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/MemoryDetection/entry/obfuscation-rules.txt b/MemoryDetection/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/MemoryDetection/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/MemoryDetection/entry/oh-package.json5 b/MemoryDetection/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..248c3b7541a589682a250f86a6d3ecf7414d2d6a --- /dev/null +++ b/MemoryDetection/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/MemoryDetection/entry/src/main/ets/entryability/EntryAbility.ets b/MemoryDetection/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..508880af8c33aa838016d1cd4b2c68be2f447540 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/MemoryDetection/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e4de99282050bad799ac892eb85ac5449364a51 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/ets/pages/GwpAsan.cpp b/MemoryDetection/entry/src/main/ets/pages/GwpAsan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6248fb68d612ac14ff73f279e99a416ff9f92434 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/pages/GwpAsan.cpp @@ -0,0 +1,147 @@ +/** +* 最佳实践:使用GWP-Asan检测内存错误 +* 场景一:double free +*/ +// [Start gwp_asan_double_free] +*** GWP-ASan detected a memory error *** +Double Free at 0x7f9c31efe0 (a 20-byte allocation) by thread 11725 here: + #0 0x7f9c548958 (/lib/ld-musl-aarch64.so.1+0x1ea958) + #1 0x7f9c548730 (/lib/ld-musl-aarch64.so.1+0x1ea730) + #2 0x7f9c4810f4 (/lib/ld-musl-aarch64.so.1+0x1230f4) + #3 0x7f9c4018d8 (/lib/ld-musl-aarch64.so.1+0xa38d8) + #4 0x7f9c547944 (/lib/ld-musl-aarch64.so.1+0x1e9944) + #5 0x7f9c418c64 (/lib/ld-musl-aarch64.so.1+0xbac64) + #6 0x555dab4f24 (/data/local/tmp/double_free+0x1f24) + #7 0x7f9c4c1668 (/lib/ld-musl-aarch64.so.1+0x163668) + #8 0x555dab4c14 (/data/local/tmp/double_free+0x1c14) +0x7f9c31efe0 was deallocated by thread 11725 here: + #0 0x7f9c5480f8 (/lib/ld-musl-aarch64.so.1+0x1ea0f8) + #1 0x7f9c54799c (/lib/ld-musl-aarch64.so.1+0x1e999c) + #2 0x7f9c418c64 (/lib/ld-musl-aarch64.so.1+0xbac64) + #3 0x555dab4f1c (/data/local/tmp/double_free+0x1f1c) + #4 0x7f9c4c1668 (/lib/ld-musl-aarch64.so.1+0x163668) + #5 0x555dab4c14 (/data/local/tmp/double_free+0x1c14) +0x7f9c31efe0 was allocated by thread 11725 here: + #0 0x7f9c5480f8 (/lib/ld-musl-aarch64.so.1+0x1ea0f8) + #1 0x7f9c547780 (/lib/ld-musl-aarch64.so.1+0x1e9780) + #2 0x7f9c41882c (/lib/ld-musl-aarch64.so.1+0xba82c) + #3 0x555dab4f10 (/data/local/tmp/double_free+0x1f10) + #4 0x7f9c4c1668 (/lib/ld-musl-aarch64.so.1+0x163668) + #5 0x555dab4c14 (/data/local/tmp/double_free+0x1c14) +*** End GWP-ASan report *** +// [End gwp_asan_double_free] + +/** +* 最佳实践:使用GWP-Asan检测内存错误 +* 场景二:use_after_free +*/ + +// [Start gwp_asan_use_after_free] +*** GWP-ASan detected a memory error *** +Use After Free at 0x7fa2ab6000 (0 bytes into a 10-byte allocation at 0x7fa2ab6000) by thread 3594 here: + #0 0x7fa4781f18 (/lib/ld-musl-aarch64.so.1+0x1e9f18) + #1 0x7fa4781cf0 (/lib/ld-musl-aarch64.so.1+0x1e9cf0) + #2 0x7fa46ba6bc (/lib/ld-musl-aarch64.so.1+0x1226bc) + #3 0x7fa463b298 (/lib/ld-musl-aarch64.so.1+0xa3298) + #4 0x5562e886ac (/data/local/tmp/gwp_asan_use_after_free_test+0x16ac) + #5 0x7fa46fac28 (/lib/ld-musl-aarch64.so.1+0x162c28) + #6 0x5562e88654 (/data/local/tmp/gwp_asan_use_after_free_test+0x1654) +0x7fa2ab6000 was deallocated by thread 3594 here: + #0 0x7fa47816b8 (/lib/ld-musl-aarch64.so.1+0x1e96b8) + #1 0x7fa4780f5c (/lib/ld-musl-aarch64.so.1+0x1e8f5c) + #2 0x7fa46522cc (/lib/ld-musl-aarch64.so.1+0xba2cc) + #3 0x5562e886ac (/data/local/tmp/gwp_asan_use_after_free_test+0x16ac) + #4 0x7fa46fac28 (/lib/ld-musl-aarch64.so.1+0x162c28) + #5 0x5562e88654 (/data/local/tmp/gwp_asan_use_after_free_test+0x1654) +0x7fa2ab6000 was allocated by thread 3594 here: + #0 0x7fa47816b8 (/lib/ld-musl-aarch64.so.1+0x1e96b8) + #1 0x7fa4780d40 (/lib/ld-musl-aarch64.so.1+0x1e8d40) + #2 0x7fa4652010 (/lib/ld-musl-aarch64.so.1+0xba010) + #3 0x5562e886a4 (/data/local/tmp/gwp_asan_use_after_free_test+0x16a4) + #4 0x7fa46fac28 (/lib/ld-musl-aarch64.so.1+0x162c28) + #5 0x5562e88654 (/data/local/tmp/gwp_asan_use_after_free_test+0x1654) +*** End GWP-ASan report *** +// [End gwp_asan_use_after_free] + +/** +* 最佳实践:使用GWP-Asan检测内存错误 +* 场景三:invalid free left +*/ +// [Start gwp_asan_invalid_free_left] +*** GWP-ASan detected a memory error *** +Invalid (Wild) Free at 0x7f8551ffff (1 byte to the left of a 1-byte allocation at 0x7f85520000) by thread 11708 here: + #0 0x7f856746b8 (/lib/ld-musl-aarch64.so.1+0x1286b8) + #1 0x7f85674268 (/lib/ld-musl-aarch64.so.1+0x128268) + #2 0x7f856cfbc0 (/lib/ld-musl-aarch64.so.1+0x183bc0) + #3 0x7f855ea1b4 (/lib/ld-musl-aarch64.so.1+0x9e1b4) + #4 0x7f8567349c (/lib/ld-musl-aarch64.so.1+0x12749c) + #5 0x556c5c67a8 (/data/local/tmp/gwp_asan_invalid_free_left_test+0x17a8) + #6 0x7f855ecd74 (/lib/ld-musl-aarch64.so.1+0xa0d74) + #7 0x556c5c6754 (/data/local/tmp/gwp_asan_invalid_free_left_test+0x1754) +0x7f8551ffff was allocated by thread 11708 here: + #0 0x7f85673f20 (/lib/ld-musl-aarch64.so.1+0x127f20) + #1 0x7f85673298 (/lib/ld-musl-aarch64.so.1+0x127298) + #2 0x7f856891b4 (/lib/ld-musl-aarch64.so.1+0x13d1b4) + #3 0x556c5c67a0 (/data/local/tmp/gwp_asan_invalid_free_left_test+0x17a0) + #4 0x7f855ecd74 (/lib/ld-musl-aarch64.so.1+0xa0d74) + #5 0x556c5c6754 (/data/local/tmp/gwp_asan_invalid_free_left_test+0x1754) +*** End GWP-ASan report *** +// [End gwp_asan_invalid_free_left] + +/** +* 最佳实践:使用GWP-Asan检测内存错误 +* 场景四:invalid free right +*/ +// [Start gwp_asan_invalid_free_right] +*** GWP-ASan detected a memory error *** +Invalid (Wild) Free at 0x7fa4e96ff1 (1 byte to the right of a 1-byte allocation at 0x7fa4e96ff0) by thread 11852 here: + #0 0x7fa4fec6b8 (/lib/ld-musl-aarch64.so.1+0x1286b8) + #1 0x7fa4fec268 (/lib/ld-musl-aarch64.so.1+0x128268) + #2 0x7fa5047bc0 (/lib/ld-musl-aarch64.so.1+0x183bc0) + #3 0x7fa4f621b4 (/lib/ld-musl-aarch64.so.1+0x9e1b4) + #4 0x7fa4feb49c (/lib/ld-musl-aarch64.so.1+0x12749c) + #5 0x55625737a8 (/data/local/tmp/gwp_asan_invalid_free_right_test+0x17a8) + #6 0x7fa4f64d74 (/lib/ld-musl-aarch64.so.1+0xa0d74) + #7 0x5562573754 (/data/local/tmp/gwp_asan_invalid_free_right_test+0x1754) +0x7fa4e96ff1 was allocated by thread 11852 here: + #0 0x7fa4febf20 (/lib/ld-musl-aarch64.so.1+0x127f20) + #1 0x7fa4feb298 (/lib/ld-musl-aarch64.so.1+0x127298) + #2 0x7fa50011b4 (/lib/ld-musl-aarch64.so.1+0x13d1b4) + #3 0x55625737a0 (/data/local/tmp/gwp_asan_invalid_free_right_test+0x17a0) + #4 0x7fa4f64d74 (/lib/ld-musl-aarch64.so.1+0xa0d74) + #5 0x5562573754 (/data/local/tmp/gwp_asan_invalid_free_right_test+0x1754) +*** End GWP-ASan report *** +// [End gwp_asan_invalid_free_right] + +/** +* 最佳实践:使用GWP-Asan检测内存错误 +* 场景五:Buffer Underflow +*/ + +// [Start gwp_asan_buffer_underflow] +*** GWP-ASan detected a memory error *** +Buffer Underflow at 0x7f8db1aff1 (4063 bytes to the left of a 48-byte allocation at 0x7f8db1bfd0) by thread 12086 here: + #0 0x7f8dc716b8 (/lib/ld-musl-aarch64.so.1+0x1286b8) + #1 0x7f8dc71268 (/lib/ld-musl-aarch64.so.1+0x128268) + #2 0x7f8dcccbc0 (/lib/ld-musl-aarch64.so.1+0x183bc0) + #3 0x7f8dbe71b4 (/lib/ld-musl-aarch64.so.1+0x9e1b4) + #4 0x55801287f8 (/data/local/tmp/gwp_asan_buffer_overflow_test+0x17f8) + #5 0x7f8dbe9d74 (/lib/ld-musl-aarch64.so.1+0xa0d74) + #6 0x558012879c (/data/local/tmp/gwp_asan_buffer_overflow_test+0x179c) +0x7f8db1aff1 was allocated by thread 12086 here: + #0 0x7f8dc70f20 (/lib/ld-musl-aarch64.so.1+0x127f20) + #1 0x7f8dc70298 (/lib/ld-musl-aarch64.so.1+0x127298) + #2 0x7f8dc861b4 (/lib/ld-musl-aarch64.so.1+0x13d1b4) + #3 0x7f8d4ef4fc (/system/lib64/libc++.so+0xaf4fc) + #4 0x7f8da76818 (/system/lib64/chipset-pub-sdk/libhilog.so+0x36818) + #5 0x7f8da76af8 (/system/lib64/chipset-pub-sdk/libhilog.so+0x36af8) + #6 0x7f8da6f228 (/system/lib64/chipset-pub-sdk/libhilog.so+0x2f228) + #7 0x7f8dbd4d18 (/lib/ld-musl-aarch64.so.1+0x8bd18) + #8 0x7f8dbd8cc4 (/lib/ld-musl-aarch64.so.1+0x8fcc4) + #9 0x7f8dd00370 (/lib/ld-musl-aarch64.so.1+0x1b7370) + #10 0x7f8dbd4d18 (/lib/ld-musl-aarch64.so.1+0x8bd18) + #11 0x7f8dbd4b28 (/lib/ld-musl-aarch64.so.1+0x8bb28) + #12 0x7f8dbe9d58 (/lib/ld-musl-aarch64.so.1+0xa0d58) + #13 0x558012879c (/data/local/tmp/gwp_asan_buffer_overflow_test+0x179c) +*** End GWP-ASan report *** +// [End gwp_asan_buffer_underflow] \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/ets/pages/Index.ets b/MemoryDetection/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/ets/pages/MemoryLeakDetection.ets b/MemoryDetection/entry/src/main/ets/pages/MemoryLeakDetection.ets new file mode 100644 index 0000000000000000000000000000000000000000..64a9d76de952f1943680fbcc5091c1b3153692d4 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/pages/MemoryLeakDetection.ets @@ -0,0 +1,22 @@ +/** + * 最佳实践:内存泄漏检测 + * 场景一:分析Snapshot数据 + */ + +// [Start check_snapshot] +class People { + old: number + name: string + constructor(old: number, name: string) { + this.old = old; + this.name = name; + } + printOld() { + console.log("old = ", this.old); + } + printName() { + console.log("name = ", this.name); + } +}; +let p = new People(20, "Tom"); +// [End check_snapshot] \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/ets/pages/SetAsan.cpp b/MemoryDetection/entry/src/main/ets/pages/SetAsan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..514806fa4ef0854772c1944b6199fc2f494424f8 --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/pages/SetAsan.cpp @@ -0,0 +1,294 @@ +/** + * 最佳实践:使用Asan检测内存错误 + * 场景二:在app.json5中配置环境变量-配置Asan参数时 + */ + +// [Start set_asan] +allow_user_segv_handler=1 +detect_odr_violation=0 +alloc_dealloc_mismatch=0 +allocator_may_return_null=1 +detect_container_overflow=0 +abort_on_error=0 +halt_on_error=0 +report_globals=0 +handle_abort=0 +allow_user_poisoning=1 +log_exe_name=true +handle_segv=0 +detect_stack_use_after_return=0 +print_module_map=2 +handle_sigbus=0 +// [End set_asan] +/** + * 最佳实践:使用Asan检测内存错误 + * 场景三:方式一-流水线场景 + */ + +// [Start pipeline_scenario] +hvigorw [taskNames...] ohos-debug-asan=true +// [End pipeline_scenario] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景五:方拾二-流水线场景 + */ + +// [Start pipeline_scenario_two] +hvigorw [taskNames...] +// [End pipeline_scenario_two] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景五:heap-buffer-overflow-错误示例 + */ + +// [Start heap_buffer_overflow] +int heapBufferOverflow() { + char *buffer; + buffer = (char *)malloc(10); + *(buffer + 11) = 'n'; + *(buffer + 12) = 'n'; + free(buffer); + return buffer[1]; +} +// [End heap_buffer_overflow] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景六:heap-buffer-overflow-定位思路 + */ + +// [Start heap_buffer_overflow_ideas] +Reason:AddressSanitizer:heap-buffer-overflow +Fault thread info: +==appspawn==17140==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x0060019ca8da at pc 0x005ec33c3250 bp 0x007fe9c392f0 sp 0x007fe9c392e8 +WRITE of size 1 at 0x0060019ca8da thread T0 (easandemo_api12) + #0 0x5ec33c324c (/data/storage/el1/bundle/libs/arm64/libentry.so+0x324c) (BuildId: 4f31be36da7e9bc00c9b7bad563e7ccfec4d0347) + #1 0x5ec33c38e0 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x38e0) (BuildId: 4f31be36da7e9bc00c9b7bad563e7ccfec4d0347) + #2 0x7f850b3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) +0x0060019ca8da is located 0 bytes to the right of 10-byte region [0x0060019ca8d0,0x0060019ca8da) +allocated by thread T0 (easandemo_api12) here: + #0 0x7f82652758 (/system/lib64/libclang_rt.asan.so+0xd2758) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ec33c31ec (/data/storage/el1/bundle/libs/arm64/libentry.so+0x31ec) (BuildId: 4f31be36da7e9bc00c9b7bad563e7ccfec4d0347) + #2 0x5ec33c38e0 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x38e0) (BuildId: 4f31be36da7e9bc00c9b7bad563e7ccfec4d0347) + #3 0x7f850b3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) + #4 0x5ec6a1bcd8 (/system/lib64/module/arkcompiler/stub.an+0x1dccd8) + #5 0x5ec6847f4c (/system/lib64/module/arkcompiler/stub.an+0x8f4c) +// [End heap_buffer_overflow_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景七:stack-buffer-overflow-错误示例 + */ + +// [Start stack_buffer_overflow] +int stackBufferOverflow() { + int subscript = 43; + char buffer[42]; + buffer[subscript] = 42; + return 0; +} +// [End stack_buffer_overflow] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景七:stack-buffer-overflow-定位思路 + */ + +// [Start stack_buffer_overflow_ideas] +Reason:ASAN +================================================================= +==appspawn==8518==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffdbb8a1deb at pc 0x7f4d58ec95a6 bp 0x7ffdbb8a1d90 sp 0x7ffdbb8a1d88 +WRITE of size 1 at 0x7ffdbb8a1deb thread T0 (e.mycppasandemo) + #0 0x7f4d58ec95a5 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x95a5) (BuildId: 5f94771f88ac6f3ed4c63d5c52598c94dc7bca66) + #1 0x7f4d58eca203 (/data/storage/el1/bundle/libs/x86_64/libentry.so+0xa203) (BuildId: 5f94771f88ac6f3ed4c63d5c52598c94dc7bca66) + #2 0x7f4dc9c0378f (/system/lib64/platformsdk/libace_napi.z.so+0x4378f) (BuildId: 88b8b49edb64385b2d6b854950877489) + + +Address 0x7ffdbb8a1deb is located in stack of thread T0 (e.mycppasandemo) at offset 75 in frame + #0 0x7f4d58ec948f (/data/storage/el1/bundle/libs/x86_64/libentry.so+0x948f) (BuildId: 5f94771f88ac6f3ed4c63d5c52598c94dc7bca66) +// [End stack_buffer_overflow_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景八:stack-buffer-underflow-错误示例 + */ + +// [Start stack_buffer_underflow] +int stackBufferUnderflow() { + int subscript = -1; + char buffer[42]; + buffer[subscript] = 42; + return 0; +} +// [End stack_buffer_underflow] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景八:stack-buffer-underflow-定位思路 + */ + +// [Start stack_buffer_underflow_ideas] +Reason:AddressSanitizer:stack-buffer-underflow +Fault thread info: +==appspawn==17039==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x007e07c6027f at pc 0x007f1bdc3994 bp 0x007e07c60250 sp 0x007e07c60248 +WRITE of size 1 at 0x007e07c6027f thread T0 (easandemo_api12) + #0 0x7f1bdc3990 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3990) (BuildId: e34349d8024d23ca83c7c7c3b9f69505d2beb3a0) + #1 0x7f1bdc3fa8 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3fa8) (BuildId: e34349d8024d23ca83c7c7c3b9f69505d2beb3a0) + #2 0x7e838339a8 (/system/lib64/platformsdk/libace_napi.z.so+0x339a8) (BuildId: f48b24ee6f099a2107ef30b4ace050de) +Address 0x007e07c6027f is located in stack of thread T0 (easandemo_api12) at offset 31 in frame + #0 0x7f1bdc3820 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3820) (BuildId: e34349d8024d23ca83c7c7c3b9f69505d2beb3a0) +// [End stack_buffer_underflow_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景九:heap-use-after-free-错误示例 + */ + +// [Start heap_use_after_free] +#include +int main() { + int *array = new int[5]; + delete[] array; + return array[5]; +} +// [End heap_use_after_free] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十:heap-use-after-free-定位思路 + */ + +// [Start heap_use_after_free_ideas] +Reason:AddressSanitizer:heap-use-after-free +Fault thread info: +==appspawn==10126==ERROR: AddressSanitizer: heap-use-after-free on address 0x006121870ce4 at pc 0x005ee1ec321c bp 0x007ff5959310 sp 0x007ff5959308 +READ of size 4 at 0x006121870ce4 thread T0 (easandemo_api12) + #0 0x5ee1ec3218 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3218) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #1 0x5ee1ec3714 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3714) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #2 0x7fa9133780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) +0x006121870ce4 is located 0 bytes to the right of 20-byte region [0x006121870cd0,0x006121870ce4) +freed by thread T0 (easandemo_api12) here: + #0 0x7fa569f0c4 (/system/lib64/libclang_rt.asan.so+0xdf0c4) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ee1ec31b8 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x31b8) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #2 0x5ee1ec3714 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3714) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #3 0x7fa9133780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) + #4 0x5ee571bcd8 (/system/lib64/module/arkcompiler/stub.an+0x1dccd8) + #5 0x5ee5547f4c (/system/lib64/module/arkcompiler/stub.an+0x8f4c) +previously allocated by thread T0 (easandemo_api12) here: + #0 0x7fa569e888 (/system/lib64/libclang_rt.asan.so+0xde888) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ee1ec3194 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3194) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #2 0x5ee1ec3714 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3714) (BuildId: 3b906822a911c973ab89188662a589eeedf639a4) + #3 0x7fa9133780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) + #4 0x5ee571bcd8 (/system/lib64/module/arkcompiler/stub.an+0x1dccd8) + #5 0x5ee5547f4c (/system/lib64/module/arkcompiler/stub.an+0x8f4c) +// [End heap_use_after_free_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十一:stack-use-after-scope-错误示例 + */ + +// [Start stack_use_after_scope] +int *gp; +bool b = true; +int stackUseAfterScope() { + if (b) { + int x[5]; + gp = x + 1; + } + return *gp; +} +// [End stack_use_after_scope] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十二:stack-use-after-scope-定位思路 + */ + +// [Start stack_use_after_scope_ideas] +Reason:AddressSanitizer:stack-use-after-scope +Fault thread info: +==appspawn==7494==ERROR: AddressSanitizer: stack-use-after-scope on address 0x007ffa213b44 at pc 0x005ebf0431e4 bp 0x007ffa213b10 sp 0x007ffa213b08 +READ of size 4 at 0x007ffa213b44 thread T0 (easandemo_api12) + #0 0x5ebf0431e0 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x31e0) (BuildId: cf28a04a79da128bc344416e8d5f860e3e22f495) + #1 0x5ebf0437f4 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x37f4) (BuildId: cf28a04a79da128bc344416e8d5f860e3e22f495) + #2 0x7f868b3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) +Address 0x007ffa213b44 is located in stack of thread T0 (easandemo_api12) at offset 36 in frame + #0 0x5ebf043024 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3024) (BuildId: cf28a04a79da128bc344416e8d5f860e3e22f495) +// [End stack_use_after_scope_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十三:attempt-free-nonallocated-memory-错误示例 + */ + +// [Start attempt_free_nonallocated_memory] +int main() { + int value = 42; + free(&value); + return 0; +} +// [End attempt_free_nonallocated_memory] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十四:attempt-free-nonallocated-memory-定位思路 + */ + +// [Start attempt_free_nonallocated_memory_ideas] +Reason:AddressSanitizer:attempting +Fault thread info: +==appspawn==20382==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x007fd59ae8c0 in thread T0 (easandemo_api12) + #0 0x7f83a92630 (/system/lib64/libclang_rt.asan.so+0xd2630) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ec45c3120 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3120) (BuildId: 743109db136e66f875a7bc47db74a8095758d4ff) + #2 0x5ec45c3720 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x3720) (BuildId: 743109db136e66f875a7bc47db74a8095758d4ff) + #3 0x7f8a2f3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) +Address 0x007fd59ae8c0 is located in stack of thread T0 (easandemo_api12) at offset 32 in frame + #0 0x5ec45c2fbc (/data/storage/el1/bundle/libs/arm64/libentry.so+0x2fbc) (BuildId: 743109db136e66f875a7bc47db74a8095758d4ff) +// [End attempt_free_nonallocated_memory_ideas] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十五:double-free-错误示例 + */ + +// [Start double_free] +int main() { + int *x = new int[42]; + delete [] x; + delete [] x; + return 0; +} +// [End double_free] + +/** + * 最佳实践:使用Asan检测内存错误 + * 场景十六:double-free-定位思路 + */ + +// [Start double_free_ideas] +Reason:AddressSanitizer:attempting +Fault thread info: +==appspawn==9596==ERROR: AddressSanitizer: attempting double-free on 0x0061303ecc10 in thread T0 (easandemo_api12): + #0 0x7fb3292630 (/system/lib64/libclang_rt.asan.so+0xd2630) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ef0b82ef4 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x2ef4) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #2 0x5ef0b834bc (/data/storage/el1/bundle/libs/arm64/libentry.so+0x34bc) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #3 0x7fb4af3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) +0x0061303ecc10 is located 0 bytes inside of 32-byte region [0x0061303ecc10,0x0061303ecc30) +freed by thread T0 (easandemo_api12) here: + #0 0x7fb3292630 (/system/lib64/libclang_rt.asan.so+0xd2630) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ef0b82eec (/data/storage/el1/bundle/libs/arm64/libentry.so+0x2eec) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #2 0x5ef0b834bc (/data/storage/el1/bundle/libs/arm64/libentry.so+0x34bc) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #3 0x7fb4af3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) + #4 0x5ef459bcd8 (/system/lib64/module/arkcompiler/stub.an+0x1dccd8) + #5 0x5ef43c7f4c (/system/lib64/module/arkcompiler/stub.an+0x8f4c) +previously allocated by thread T0 (easandemo_api12) here: + #0 0x7fb3292758 (/system/lib64/libclang_rt.asan.so+0xd2758) (BuildId: aeec20776cc4e8f96db6c6b5603bb49748cc20ff) + #1 0x5ef0b82ee0 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x2ee0) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #2 0x5ef0b834bc (/data/storage/el1/bundle/libs/arm64/libentry.so+0x34bc) (BuildId: 5b44777ffb29e6665852feeb6f23712aef424077) + #3 0x7fb4af3780 (/system/lib64/platformsdk/libace_napi.z.so+0x33780) (BuildId: 25f88248f530c20439061db9eb4ed152) + #4 0x5ef459bcd8 (/system/lib64/module/arkcompiler/stub.an+0x1dccd8) + #5 0x5ef43c7f4c (/system/lib64/module/arkcompiler/stub.an+0x8f4c) +// [End double_free_ideas] diff --git a/MemoryDetection/entry/src/main/ets/pages/setHwAsan.cpp b/MemoryDetection/entry/src/main/ets/pages/setHwAsan.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f1d448c4819d2171b6e52f1f7643ce92b7843ad --- /dev/null +++ b/MemoryDetection/entry/src/main/ets/pages/setHwAsan.cpp @@ -0,0 +1,180 @@ +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景二:配置HWASan-流水线场景hvigorw命令 +*/ + +// [Start hw_asan_hvigorw] +hvigorw [taskNames...] -p ohos-enable-hwasan=true +// [End hw_asan_hvigorw] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景四:配置HWASan-方式二 流水线场景hvigorw命令 +*/ + +// [Start hw_asan_hvigorw_two] +hvigorw [taskNames...] +// [End hw_asan_hvigorw_two] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景五:stack tag-mismatch-错误示例 +*/ + +// [Start stack_tag_mismatch] +// stack-buffer-overflow +int stackBufferOverflow() { + int subscript = 43; + char buffer[42]; + buffer[subscript] = 42; + return 0; +} + + +// stack-buffer-underflow +int stackBufferUnderflow() { + int subscript = -1; + char buffer[42]; + buffer[subscript] = 42; + return 0; +} + + +// stack-use-after-return +int *ptr; +__attribute__((noinline)) +void FunctionThatEscapesLocalObject() { + int local[100]; + ptr = &local[0]; +} +int main(int argc, char **argv) { + FunctionThatEscapesLocalObject(); + return ptr[argc]; +} +// [End stack_tag_mismatch] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景六:stack tag-mismatch-定位思路 +*/ + +// [Start stack_tag_mismatch_ideas] +Reason:HWASAN +==appspawn==61390==ERROR: HWAddressSanitizer: tag-mismatch on address 0x007eb11cc05f at pc 0x005acf446438 +WRITE of size 1 at 0x007eb11cc05f tags: f1/00 (ptr/mem) in thread T0 + #0 0x5acf446438 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6438) (BuildId: 4b0b8d2189a7eb99fff81c6bc8889dfefd4af4a1) + #1 0x5acf446c08 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6c08) (BuildId: 4b0b8d2189a7eb99fff81c6bc8889dfefd4af4a1) + #2 0x5ab397cdc8 (/system/lib64/platformsdk/libace_napi.z.so+0x3cdc8) (BuildId: dc293a22b36a4db17dc689ff9413b64e) + + +Cause: stack tag-mismatch +Address 0x007eb11cc05f is located in stack of thread T0 +Thread: T0 0x005b00002000 stack: [0x007eb09d2000,0x007eb11d1000) sz: 8384512 tls: [0x005aacd0fa98,0x005aacd10279) +Previously allocated frames: + record_addr:0x5ab053c788 record:0xcc0a005acf4463c0 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x63c0) (BuildId: 4b0b8d2189a7eb99fff81c6bc8889dfefd4af4a1) + record_addr:0x5ab053c780 record:0xcc1a005acf446a68 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6a68) (BuildId: 4b0b8d2189a7eb99fff81c6bc8889dfefd4af4a1) + record_addr:0x5ab053c778 record:0xcb81005acf4866ac (/data/storage/el1/bundle/libs/arm64/libmainpage.so+0x66ac) (BuildId: 10ffa0d04cbc27e12a59f658b5932674185d63ee) + record_addr:0x5ab053c770 record:0xcc87005acf4465b4 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x65b4) (BuildId: 4b0b8d2189a7eb99fff81c6bc8889dfefd4af4a1) +// [End stack_tag_mismatch_ideas] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景七:heap-buffer-overflow-错误示例 +*/ + +// [Start hw_heap_buffer_overflow] +// heap-buffer-overflow +void heapBufferOverflow() { + char *buffer; + buffer = (char *)malloc(10); + *(buffer + 11) = 'n'; + *(buffer + 12) = 'n'; + free(buffer); +} + +// heap-buffer-underflow +void heapBufferUnderflow() { + char *buffer; + buffer = (char *)malloc(10); + *(buffer - 11) = 'n'; + *(buffer - 12) = 'n'; + free(buffer); +} +// [End hw_heap_buffer_overflow] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景八:heap-buffer-overflow-定位思路 +*/ + +// [Start hw_heap_buffer_overflow_ideas] +Reason:HWASAN +==appspawn==8344==ERROR: HWAddressSanitizer: tag-mismatch on address 0x000100760332 at pc 0x005adb286570 +WRITE of size 1 at 0x000100760332 tags: cb/08(44) (ptr/mem) in thread T0 + #0 0x5adb286570 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6570) (BuildId: 4724eac5a66f4994a03c023a9958da3897de5f16) + #1 0x5adb286c8c (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6c8c) (BuildId: 4724eac5a66f4994a03c023a9958da3897de5f16) + #2 0x5abd63cdc8 (/system/lib64/platformsdk/libace_napi.z.so+0x3cdc8) (BuildId: dc293a22b36a4db17dc689ff9413b64e) + + +[0x000100760320,0x000100760340) is a small allocated heap chunk; size: 32 offset: 18 + + +Cause: heap-buffer-overflow +0x000100760332 is located 110 bytes to the left of 10-byte region [0x0001007603a0,0x0001007603aa) +allocated here: + #0 0x5a394625ec (/system/lib64/libclang_rt.hwasan.so+0x225ec) (BuildId: 2b2455ae77181bfdfbfa9561b4e6e3ea376ec93b) + #1 0x5adb286548 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6548) (BuildId: 4724eac5a66f4994a03c023a9958da3897de5f16) + #2 0x5adb286c8c (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6c8c) (BuildId: 4724eac5a66f4994a03c023a9958da3897de5f16) + #3 0x5abd63cdc8 (/system/lib64/platformsdk/libace_napi.z.so+0x3cdc8) (BuildId: dc293a22b36a4db17dc689ff9413b64e) + #4 0x5ad4373b6c (/system/lib64/module/arkcompiler/stub.an+0x3f3b6c) + #5 0x5ad3f8be8c (/system/lib64/module/arkcompiler/stub.an+0xbe8c) +// [End hw_heap_buffer_overflow_ideas] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景九:Use-after-free-错误示例 +*/ + +// [Start hw_use_after_free] +// heap-use-after-free +int useAfterFree(int argc) { + int *array = new int[100]; + delete[] array; + return array[argc]; +} + +// double free +void doubleFree() { + char *p = (char *)malloc(32 * sizeof(char)); + free(p); + free(p); +} +// [End hw_use_after_free] + +/** +* 最佳实践:使用HWAsan检测内存错误 +* 场景十:Use-after-free-定位思路 +*/ + +// [Start hw_use_after_free_ideas] +Reason:HWASAN +==appspawn==10741==ERROR: HWAddressSanitizer: tag-mismatch on address 0x000d00036a68 at pc 0x005ab24864c4 +READ of size 4 at 0x000d00036a68 tags: ae/6e (ptr/mem) in thread T0 + #0 0x5ab24864c4 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x64c4) (BuildId: e073772c81ab52894a21e4190a263680198f3e9c) + #1 0x5ab2486c84 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6c84) (BuildId: e073772c81ab52894a21e4190a263680198f3e9c) + #2 0x5a96b7cdc8 (/system/lib64/platformsdk/libace_napi.z.so+0x3cdc8) (BuildId: dc293a22b36a4db17dc689ff9413b64e) + + +[0x000d00036a60,0x000d00036c00) is a small unallocated heap chunk; size: 416 offset: 8 + + +Cause: use-after-free +0x000d00036a68 is located 8 bytes inside of 400-byte region [0x000d00036a60,0x000d00036bf0) +freed by thread T0 here: + #0 0x5a90a6844c (/system/lib64/libclang_rt.hwasan.so+0x2844c) (BuildId: 2b2455ae77181bfdfbfa9561b4e6e3ea376ec93b) + #1 0x5ab2486494 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6494) (BuildId: e073772c81ab52894a21e4190a263680198f3e9c) + #2 0x5ab2486c84 (/data/storage/el1/bundle/libs/arm64/libentry.so+0x6c84) (BuildId: e073772c81ab52894a21e4190a263680198f3e9c) + #3 0x5a96b7cdc8 (/system/lib64/platformsdk/libace_napi.z.so+0x3cdc8) (BuildId: dc293a22b36a4db17dc689ff9413b64e) + #4 0x5aab6b3b6c (/system/lib64/module/arkcompiler/stub.an+0x3f3b6c) + #5 0x5aab2cbe8c (/system/lib64/module/arkcompiler/stub.an+0xbe8c) +// [End hw_use_after_free_ideas] \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/module.json5 b/MemoryDetection/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1cea8b6a4560cee7bda7a2db52f310c035ab6c8 --- /dev/null +++ b/MemoryDetection/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/resources/base/element/color.json b/MemoryDetection/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/resources/base/element/float.json b/MemoryDetection/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/MemoryDetection/entry/src/main/resources/base/element/string.json b/MemoryDetection/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/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/MemoryDetection/entry/src/main/resources/base/media/background.png b/MemoryDetection/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/MemoryDetection/entry/src/main/resources/base/media/background.png differ diff --git a/MemoryDetection/entry/src/main/resources/base/media/foreground.png b/MemoryDetection/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/MemoryDetection/entry/src/main/resources/base/media/foreground.png differ diff --git a/MemoryDetection/entry/src/main/resources/base/media/layered_image.json b/MemoryDetection/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/resources/base/media/startIcon.png b/MemoryDetection/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/MemoryDetection/entry/src/main/resources/base/media/startIcon.png differ diff --git a/MemoryDetection/entry/src/main/resources/base/profile/backup_config.json b/MemoryDetection/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/main/resources/base/profile/main_pages.json b/MemoryDetection/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/MemoryDetection/entry/src/main/resources/dark/element/color.json b/MemoryDetection/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/MemoryDetection/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/mock/mock-config.json5 b/MemoryDetection/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/MemoryDetection/entry/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/ohosTest/ets/test/Ability.test.ets b/MemoryDetection/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/MemoryDetection/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/MemoryDetection/entry/src/ohosTest/ets/test/List.test.ets b/MemoryDetection/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/MemoryDetection/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/ohosTest/module.json5 b/MemoryDetection/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..55725a929993a8a18b3808d41ef037759440488b --- /dev/null +++ b/MemoryDetection/entry/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/MemoryDetection/entry/src/test/List.test.ets b/MemoryDetection/entry/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/MemoryDetection/entry/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/MemoryDetection/entry/src/test/LocalUnit.test.ets b/MemoryDetection/entry/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/MemoryDetection/entry/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/MemoryDetection/hvigor/hvigor-config.json5 b/MemoryDetection/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/MemoryDetection/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/MemoryDetection/hvigorfile.ts b/MemoryDetection/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/MemoryDetection/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/MemoryDetection/oh-package-lock.json5 b/MemoryDetection/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7fcf818273347b97063c0c0a151bb14770ca1c79 --- /dev/null +++ b/MemoryDetection/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.21": { + "name": "@ohos/hypium", + "version": "1.0.21", + "integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.21.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/MemoryDetection/oh-package.json5 b/MemoryDetection/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a8aff0c5aff22d78aa26fd19c3861f4320e951ff --- /dev/null +++ b/MemoryDetection/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/Privacy/AppScope/app.json5 b/Privacy/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..59f211fc0ba2482b4e469cc7bd105c5645c58b17 --- /dev/null +++ b/Privacy/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.privacy", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:layered_image", + "label": "$string:app_name" + } +} diff --git a/Privacy/AppScope/resources/base/element/string.json b/Privacy/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..06a6c0f77e69f3cf5d33390a6dae720ce3abcc2d --- /dev/null +++ b/Privacy/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "Privacy" + } + ] +} diff --git a/Privacy/AppScope/resources/base/media/background.png b/Privacy/AppScope/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/Privacy/AppScope/resources/base/media/background.png differ diff --git a/Privacy/AppScope/resources/base/media/foreground.png b/Privacy/AppScope/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/Privacy/AppScope/resources/base/media/foreground.png differ diff --git a/Privacy/AppScope/resources/base/media/layered_image.json b/Privacy/AppScope/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Privacy/AppScope/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Privacy/ContactData/.gitignore b/Privacy/ContactData/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/Privacy/ContactData/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/Privacy/ContactData/build-profile.json5 b/Privacy/ContactData/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/Privacy/ContactData/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactData/hvigorfile.ts b/Privacy/ContactData/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/Privacy/ContactData/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Privacy/ContactData/obfuscation-rules.txt b/Privacy/ContactData/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/Privacy/ContactData/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/Privacy/ContactData/oh-package.json5 b/Privacy/ContactData/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..979c6e016dba34ac67fdf9d87044d79a125662f0 --- /dev/null +++ b/Privacy/ContactData/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "contactdata", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/Privacy/ContactData/src/main/ets/contactdataability/ContactDataAbility.ets b/Privacy/ContactData/src/main/ets/contactdataability/ContactDataAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..253c44e3f38f4a3c53f30fa6582ca770c113f049 --- /dev/null +++ b/Privacy/ContactData/src/main/ets/contactdataability/ContactDataAbility.ets @@ -0,0 +1,43 @@ +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class ContactDataAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/Privacy/ContactData/src/main/ets/pages/Index.ets b/Privacy/ContactData/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/Privacy/ContactData/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/module.json5 b/Privacy/ContactData/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..39009717a3c11b988804f497f7b11204e466f96e --- /dev/null +++ b/Privacy/ContactData/src/main/module.json5 @@ -0,0 +1,35 @@ +{ + "module": { + "name": "ContactData", + "type": "feature", + "description": "$string:module_desc", + "mainElement": "ContactDataAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + /** + * 最佳实践:应用安全编码实践 + * 场景四:对外交互的应用组件应设置合理的访问权限 + */ + // [Start module_json_permissions] + "name": "ContactDataAbility", + "srcEntry": "./ets/contactdataability/ContactDataAbility.ets", + "description": "$string:ContactDataAbility_desc", + "exported": true, + "permissions": ["ohos.permission.READ_CONTACTS"], + // [End module_json_permissions] + "icon": "$media:layered_image", + "label": "$string:ContactDataAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + } + ] + } +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/element/color.json b/Privacy/ContactData/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/Privacy/ContactData/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/element/float.json b/Privacy/ContactData/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/Privacy/ContactData/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/Privacy/ContactData/src/main/resources/base/element/string.json b/Privacy/ContactData/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..4346de3a1d7bd7dd8cfcaa20f5b584e0663e0dac --- /dev/null +++ b/Privacy/ContactData/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "ContactDataAbility_desc", + "value": "description" + }, + { + "name": "ContactDataAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/media/background.png b/Privacy/ContactData/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/Privacy/ContactData/src/main/resources/base/media/background.png differ diff --git a/Privacy/ContactData/src/main/resources/base/media/foreground.png b/Privacy/ContactData/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/Privacy/ContactData/src/main/resources/base/media/foreground.png differ diff --git a/Privacy/ContactData/src/main/resources/base/media/layered_image.json b/Privacy/ContactData/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Privacy/ContactData/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Privacy/ContactData/src/main/resources/base/media/startIcon.png b/Privacy/ContactData/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/Privacy/ContactData/src/main/resources/base/media/startIcon.png differ diff --git a/Privacy/ContactData/src/main/resources/base/profile/main_pages.json b/Privacy/ContactData/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/Privacy/ContactData/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/Privacy/ContactData/src/mock/mock-config.json5 b/Privacy/ContactData/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/Privacy/ContactData/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Privacy/ContactData/src/ohosTest/ets/test/Ability.test.ets b/Privacy/ContactData/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/Privacy/ContactData/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/Privacy/ContactData/src/ohosTest/ets/test/List.test.ets b/Privacy/ContactData/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/Privacy/ContactData/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Privacy/ContactData/src/ohosTest/module.json5 b/Privacy/ContactData/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9fbe04d516042f714b4ba4b68cccb1010c62144f --- /dev/null +++ b/Privacy/ContactData/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "ContactData_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Privacy/ContactData/src/test/List.test.ets b/Privacy/ContactData/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/Privacy/ContactData/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/Privacy/ContactData/src/test/LocalUnit.test.ets b/Privacy/ContactData/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/Privacy/ContactData/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/Privacy/ContactDataError/.gitignore b/Privacy/ContactDataError/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/Privacy/ContactDataError/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/Privacy/ContactDataError/build-profile.json5 b/Privacy/ContactDataError/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/Privacy/ContactDataError/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactDataError/hvigorfile.ts b/Privacy/ContactDataError/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/Privacy/ContactDataError/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Privacy/ContactDataError/obfuscation-rules.txt b/Privacy/ContactDataError/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/Privacy/ContactDataError/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/Privacy/ContactDataError/oh-package.json5 b/Privacy/ContactDataError/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e055afe7d83a42594fe3dd82c7423293106bfc54 --- /dev/null +++ b/Privacy/ContactDataError/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "contactdataerror", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/Privacy/ContactDataError/src/main/ets/contactdataerrorability/ContactDataErrorAbility.ets b/Privacy/ContactDataError/src/main/ets/contactdataerrorability/ContactDataErrorAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..fdfd61a6e0c521dfb8990ffdb5dd53a09a0046e4 --- /dev/null +++ b/Privacy/ContactDataError/src/main/ets/contactdataerrorability/ContactDataErrorAbility.ets @@ -0,0 +1,43 @@ +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class ContactDataErrorAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/Privacy/ContactDataError/src/main/ets/pages/Index.ets b/Privacy/ContactDataError/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/Privacy/ContactDataError/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/module.json5 b/Privacy/ContactDataError/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..12823797c41e1862e440f3e6faa932c08e9472ed --- /dev/null +++ b/Privacy/ContactDataError/src/main/module.json5 @@ -0,0 +1,34 @@ +{ + "module": { + "name": "ContactDataError", + "type": "feature", + "description": "$string:module_desc", + "mainElement": "ContactDataErrorAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + /** + * 最佳实践:应用安全编码实践 + * 场景三:对外交互的应用组件应设置合理的访问权限错误示例 + */ + // [Start module_json_permissions_error] + "name": "ContactDataErrorAbility", + "srcEntry": "./ets/contactdataerrorability/ContactDataErrorAbility.ets", + "description": "$string:ContactDataErrorAbility_desc", + "exported": true, + // [End module_json_permissions_error] + "icon": "$media:layered_image", + "label": "$string:ContactDataErrorAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + } + ] + } +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/resources/base/element/color.json b/Privacy/ContactDataError/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/Privacy/ContactDataError/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/resources/base/element/float.json b/Privacy/ContactDataError/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/Privacy/ContactDataError/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/Privacy/ContactDataError/src/main/resources/base/element/string.json b/Privacy/ContactDataError/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..879ebe3f5a778f5a7b2e5e7c62bcfaf3bca0e899 --- /dev/null +++ b/Privacy/ContactDataError/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "ContactDataErrorAbility_desc", + "value": "description" + }, + { + "name": "ContactDataErrorAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/resources/base/media/background.png b/Privacy/ContactDataError/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/Privacy/ContactDataError/src/main/resources/base/media/background.png differ diff --git a/Privacy/ContactDataError/src/main/resources/base/media/foreground.png b/Privacy/ContactDataError/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/Privacy/ContactDataError/src/main/resources/base/media/foreground.png differ diff --git a/Privacy/ContactDataError/src/main/resources/base/media/layered_image.json b/Privacy/ContactDataError/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Privacy/ContactDataError/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/main/resources/base/media/startIcon.png b/Privacy/ContactDataError/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/Privacy/ContactDataError/src/main/resources/base/media/startIcon.png differ diff --git a/Privacy/ContactDataError/src/main/resources/base/profile/main_pages.json b/Privacy/ContactDataError/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/Privacy/ContactDataError/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/Privacy/ContactDataError/src/mock/mock-config.json5 b/Privacy/ContactDataError/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/Privacy/ContactDataError/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/ohosTest/ets/test/Ability.test.ets b/Privacy/ContactDataError/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/Privacy/ContactDataError/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/Privacy/ContactDataError/src/ohosTest/ets/test/List.test.ets b/Privacy/ContactDataError/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/Privacy/ContactDataError/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/ohosTest/module.json5 b/Privacy/ContactDataError/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..069326abde880f6d052820e6fecac7b65d656cf4 --- /dev/null +++ b/Privacy/ContactDataError/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "ContactDataError_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Privacy/ContactDataError/src/test/List.test.ets b/Privacy/ContactDataError/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/Privacy/ContactDataError/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/Privacy/ContactDataError/src/test/LocalUnit.test.ets b/Privacy/ContactDataError/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/Privacy/ContactDataError/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/Privacy/PrivacyError/.gitignore b/Privacy/PrivacyError/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/Privacy/PrivacyError/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/Privacy/PrivacyError/build-profile.json5 b/Privacy/PrivacyError/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/Privacy/PrivacyError/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/Privacy/PrivacyError/hvigorfile.ts b/Privacy/PrivacyError/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/Privacy/PrivacyError/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Privacy/PrivacyError/obfuscation-rules.txt b/Privacy/PrivacyError/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/Privacy/PrivacyError/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/Privacy/PrivacyError/oh-package.json5 b/Privacy/PrivacyError/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8e434995592c4125beeff568ffbfcc8c9c16c9e3 --- /dev/null +++ b/Privacy/PrivacyError/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "privacyerror", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/Privacy/PrivacyError/src/main/ets/pages/GeolocationAccess.ets b/Privacy/PrivacyError/src/main/ets/pages/GeolocationAccess.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f36cee59b50c7248f1524300b083a81d98f608b --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/GeolocationAccess.ets @@ -0,0 +1,27 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十一:避免在用户同意前返回位置信息错误示例 + */ + +// [Start geolocation_access_error] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController() + + build() { + Column() { + Web({ src: 'www.example.com', controller: this.controller }) + .geolocationAccess(true) + .onGeolocationShow((event) => { + if (event === undefined) { + return + } + event.geolocation.invoke(event.origin, true, true); + }) + } + } +} +// [End geolocation_access_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/Index.ets b/Privacy/PrivacyError/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/JavaScriptProxy.ets b/Privacy/PrivacyError/src/main/ets/pages/JavaScriptProxy.ets new file mode 100644 index 0000000000000000000000000000000000000000..eb72f2fbf05be0ccc46f14ea322fadcfa92076a3 --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/JavaScriptProxy.ets @@ -0,0 +1,46 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十二:避免注册返回含有全局认证凭据的JavaScriptProxy + */ + +// [Start java_script_proxy_error] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController() + + build() { + Column() { + Row() { + Button('registerJavaScriptProxy').onClick(() => { + this.controller.registerJavaScriptProxy( + { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + "objName", + ["getServiceToken"], + ); + this.controller.refresh() + }) + } + + Web({ src: $rawfile('H5CallETS.html'), controller: this.controller }) + .javaScriptAccess(true) + .javaScriptProxy({ + object: { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + name: "objName", + methodList: ["getServiceToken"], + controller: this.controller + }) + } + } +} +// [End java_script_proxy_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/MixedMode.ets b/Privacy/PrivacyError/src/main/ets/pages/MixedMode.ets new file mode 100644 index 0000000000000000000000000000000000000000..8334a59b63a420094d5455e0ce2b8b68be666a8c --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/MixedMode.ets @@ -0,0 +1,21 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十七:避免将mixedMode属性配置成All + */ + +// [Start mixed_mode] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Web({ src:"www.huawei.com", controller: this.controller }) + .mixedMode(MixedMode.All) + } + } +} +// [End mixed_mode] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/NoInfoJumpTo.ets b/Privacy/PrivacyError/src/main/ets/pages/NoInfoJumpTo.ets new file mode 100644 index 0000000000000000000000000000000000000000..32eb4a93abac008b176a9a0ffd9b24990376d8ce --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/NoInfoJumpTo.ets @@ -0,0 +1,32 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景五:建议隐式启动应用组件时避免携带个人数据错误示例 + */ + +// [Start want_info_error] +import { Want } from "@kit.AbilityKit"; +// [StartExclude want_info_error] +import { common } from '@kit.AbilityKit'; +const uiContext: UIContext | undefined = AppStorage.get('uiContext'); +let context = uiContext!.getHostContext()!; +class NoInfo { + private context = context as common.UIAbilityContext + + wantNoInfo(): void { + // [EndExclude want_info_error] + let wantInfo:Want = { + deviceId: '', + action: "ability.want.test", + parameters: { + "password": "xxxxxxxx" + } + } + try{ + let data = this.context.startAbility(wantInfo) + console.info("startAbility success " + JSON.stringify(data)); + } catch (err) { + console.error("startAbility with error message: " + err.message + ", error code: " + err.code); + } + // [End want_info_error] + } +} diff --git a/Privacy/PrivacyError/src/main/ets/pages/OnSslErrorEventReceive.ets b/Privacy/PrivacyError/src/main/ets/pages/OnSslErrorEventReceive.ets new file mode 100644 index 0000000000000000000000000000000000000000..6091ac25f58799d7cee71689ee78c1dbff121f4d --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/OnSslErrorEventReceive.ets @@ -0,0 +1,23 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十九:避免在SSL校验出错时继续加载页面错误示例 + */ + +// [Start on_ssl_error_event_receive_error] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController() + + build() { + Column() { + Web({ src: 'www.example.com', controller: this.controller }) + .onSslErrorEventReceive((event) => { + event.handler.handleConfirm(); + }) + } + } +} +// [End on_ssl_error_event_receive_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/PublicSafeInfo.ets b/Privacy/PrivacyError/src/main/ets/pages/PublicSafeInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..a8220812efa19789763f73ec1c6070c9e0a15ab4 --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/PublicSafeInfo.ets @@ -0,0 +1,22 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景八:避免使用携带个人数据未设置权限的动态公共事件错误示例 + */ + +// [Start public_safe_info_error] +import { commonEventManager } from '@kit.BasicServicesKit'; + +function publishEventWithData() { + let options: commonEventManager.CommonEventPublishData = { + code: 1, + data: "ContactData", // Sending sensitive data + } + commonEventManager.publish("MyCommonEvent", options, (err) => { + if (err.code) { + console.error("publish event error: " + err.code + ", " + err.message + ", " + err.name + ", " + err.stack); + } else { + console.info("publish event with data Succeeded"); + } + }) +} +// [End public_safe_info_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/PublicSensitive.ets b/Privacy/PrivacyError/src/main/ets/pages/PublicSensitive.ets new file mode 100644 index 0000000000000000000000000000000000000000..c90ef5cf1fca20c887623b4962ccb4e322d47fef --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/PublicSensitive.ets @@ -0,0 +1,41 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十:建议对涉及敏感功能的公共事件进行访问权限控制错误示例 + */ + +// [Start public_sensitive_error] +import { commonEventManager } from '@kit.BasicServicesKit'; + +let subscriber: commonEventManager.CommonEventSubscriber; +//Subscriber information +let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { + events: ["event"] +}; + +// Create a subscriber +try { + commonEventManager.createSubscriber(subscribeInfo, (err, commonEventSubscriber) => { + if (!err) { + console.info("createSubscriber Succeed"); + subscriber = commonEventSubscriber; + //Subscribe to public events + try { + commonEventManager.subscribe(subscriber, (err, data) => { + if (err) { + console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); + } else { + //Event processing after receiving public events + // doSomeDangerousThing(data) + } + }); + } catch (err) { + console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); + } + } else { + console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); + } + }); +} catch (err) { + console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); +} +// [End public_sensitive_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/RunJavaScriptTrustList.ets b/Privacy/PrivacyError/src/main/ets/pages/RunJavaScriptTrustList.ets new file mode 100644 index 0000000000000000000000000000000000000000..66f6f19f3d2290b1f5580bf300ac997229ae52eb --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/RunJavaScriptTrustList.ets @@ -0,0 +1,35 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十六:避免加载不可信的JavaScript脚本—加载前进行白名单校验错误示例 + */ + +// [Start check_the_trust_list_error] +import { webview } from '@kit.ArkWeb'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Web({ src: $rawfile('index.html'), controller: this.controller }) + .javaScriptAccess(true) + .onPageEnd(e => { + let jsMethod: string = "alert(`xss`)" // 外部可控字段 + this.controller.runJavaScript(jsMethod) + .then((result) => { + console.log('result: ' + result); + }) + .catch((error: BusinessError) => { + console.error(`ErrorCode: ${error.code}, Message: ${error.message}`); + }) + if (e) { + console.info('url: ', e.url); + } + }) + } + } +} +// [End check_the_trust_list_error] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/UntrustedDataToSQL.ets b/Privacy/PrivacyError/src/main/ets/pages/UntrustedDataToSQL.ets new file mode 100644 index 0000000000000000000000000000000000000000..94554c71c8f1b1208bd85e353adceca262b6ef94 --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/UntrustedDataToSQL.ets @@ -0,0 +1,62 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十八:避免直接使用不可信数据来拼接SQL语句 + */ + +// [Start untrusted_data_to_sql] +import { BusinessError } from '@kit.BasicServicesKit'; + +import { relationalStore } from '@kit.ArkData' + +// [StartExclude untrusted_data_to_sql] +const uiContext: UIContext | undefined = AppStorage.get('uiContext'); +let context = uiContext!.getHostContext()!; +// [EndExclude untrusted_data_to_sql] + +// The sql parameters are from external input +function exesql(sql: string) { + const STORE_CONFIG: relationalStore.StoreConfig = { + name: "RdbTest.db", + securityLevel: relationalStore.SecurityLevel.S1 + }; + let store: relationalStore.RdbStore | undefined = undefined; + relationalStore.getRdbStore(context, STORE_CONFIG, (err: BusinessError, rdbStore: relationalStore.RdbStore) => { + store = rdbStore; + if (err) { + console.error(`Get RdbStore failed, code is ${err.code},message is ${err.message}`); + return; + } + console.info('Get RdbStore successfully.'); + }) + // The external input is used to directly concatenate the SQL statement, and the verification is not performed + let SQL_DELETE_TABLE = "DELETE FROM test WHERE name = " + sql; + if (store != undefined) { + (store as relationalStore.RdbStore).executeSql(SQL_DELETE_TABLE, (err) => { + if (err) { + console.error(`ExecuteSql failed, code is ${err.code},message is ${err.message}`); + return; + } + console.info('Delete table done.'); + }) + } +} +// [End untrusted_data_to_sql] + +/** + * 最佳实践:应用安全编码实践 + * 场景二十九:避免使用未校验的外部数据拼接文件路径 + */ + +// [Start untrusted_data_to_file_name] +// The fileName is from external +function readFile(fileName: string) { + let filePath = "/data/storage/"; + if (fileName.indexOf("..") === -1) { // Anti-splicing verification + let fileAllPath: string = filePath + fileName + // Service processing + } else { + console.info("be attacked") + return + } +} +// [End untrusted_data_to_file_name] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/pages/app_json.md b/Privacy/PrivacyError/src/main/ets/pages/app_json.md new file mode 100644 index 0000000000000000000000000000000000000000..be9a2bd7f7ac32c1fa8333c09ba5afbd7618dcbc --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/pages/app_json.md @@ -0,0 +1,29 @@ +/** +* 最佳实践:应用安全编码实践 +* 场景三十一:建议正确设置发布版本应用调试属性 + */ +// [Start app_json] +// app.json5 +{ + { + "app": { + "bundleName": "com.application.music", + "vendor": "application", + "versionCode": 1, + "versionName": "1.0", + "minCompatibleVersionCode": 1, + "minAPIVersion": 7, + "targetAPIVersion": 8, + "apiReleaseType": "Release", + "debug": false, + "icon": "$media:app_icon", + "label": "$string:app_name", + "description": "$string:description_application", + "distributedNotificationEnabled": true, + "entityType": "game", + "car": { + "apiCompatibleVersion": 8 + } + } +} +// [End app_json] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/ets/privacyerrorability/PrivacyErrorAbility.ets b/Privacy/PrivacyError/src/main/ets/privacyerrorability/PrivacyErrorAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4643ee5d83aa0b8fb7e4ebf366903ac61fecee3b --- /dev/null +++ b/Privacy/PrivacyError/src/main/ets/privacyerrorability/PrivacyErrorAbility.ets @@ -0,0 +1,45 @@ +import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class PrivacyErrorAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + let uiContext: UIContext | undefined = windowStage.getMainWindowSync().getUIContext() + AppStorage.setOrCreate('uiContext', uiContext); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} diff --git a/Privacy/PrivacyError/src/main/module.json5 b/Privacy/PrivacyError/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3a13a59776b696bc317baa8c3a384cac494b8921 --- /dev/null +++ b/Privacy/PrivacyError/src/main/module.json5 @@ -0,0 +1,34 @@ +{ + "module": { + "name": "PrivacyError", + "type": "feature", + "description": "$string:module_desc", + "mainElement": "PrivacyErrorAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + /** + * 最佳实践:应用安全编码实践 + * 场景一:通用组件安全错误示例 + */ + // [Start module_json_abilities_error] + "name": "PrivacyErrorAbility", + "srcEntry": "./ets/privacyerrorability/PrivacyErrorAbility.ets", + "description": "$string:PrivacyErrorAbility_desc", + "exported": true, + // [End module_json_abilities_error] + "icon": "$media:layered_image", + "label": "$string:PrivacyErrorAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + } + ] + } +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/resources/base/element/color.json b/Privacy/PrivacyError/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/resources/base/element/float.json b/Privacy/PrivacyError/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/Privacy/PrivacyError/src/main/resources/base/element/string.json b/Privacy/PrivacyError/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9c1a683cebe1ba33e2cbef9dc76dccf27b69740c --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "PrivacyErrorAbility_desc", + "value": "description" + }, + { + "name": "PrivacyErrorAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/resources/base/media/background.png b/Privacy/PrivacyError/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/Privacy/PrivacyError/src/main/resources/base/media/background.png differ diff --git a/Privacy/PrivacyError/src/main/resources/base/media/foreground.png b/Privacy/PrivacyError/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/Privacy/PrivacyError/src/main/resources/base/media/foreground.png differ diff --git a/Privacy/PrivacyError/src/main/resources/base/media/layered_image.json b/Privacy/PrivacyError/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/resources/base/media/startIcon.png b/Privacy/PrivacyError/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/Privacy/PrivacyError/src/main/resources/base/media/startIcon.png differ diff --git a/Privacy/PrivacyError/src/main/resources/base/profile/main_pages.json b/Privacy/PrivacyError/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/Privacy/PrivacyError/src/main/resources/rawfile/H5CallETS.html b/Privacy/PrivacyError/src/main/resources/rawfile/H5CallETS.html new file mode 100644 index 0000000000000000000000000000000000000000..965fef53f85e2b963011257d4d05d90416bea1e5 --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/rawfile/H5CallETS.html @@ -0,0 +1,23 @@ +/** +* 最佳实践:应用安全编码实践 +* 场景二十三:避免注册返回含有全局认证凭据的JavaScriptProxy-html +*/ + +// [Start java_script_proxy_error_html] + + + + +Hello js call ets interface! +
+ + + + +// [End java_script_proxy_error_html] \ No newline at end of file diff --git a/Privacy/PrivacyError/src/main/resources/rawfile/index.html b/Privacy/PrivacyError/src/main/resources/rawfile/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e6a0866f17585b1128757e54786f6d89dd20b718 --- /dev/null +++ b/Privacy/PrivacyError/src/main/resources/rawfile/index.html @@ -0,0 +1,13 @@ + + + + +Hello world! + + + \ No newline at end of file diff --git a/Privacy/PrivacyError/src/mock/mock-config.json5 b/Privacy/PrivacyError/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/Privacy/PrivacyError/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/ohosTest/ets/test/Ability.test.ets b/Privacy/PrivacyError/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/Privacy/PrivacyError/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/Privacy/PrivacyError/src/ohosTest/ets/test/List.test.ets b/Privacy/PrivacyError/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/Privacy/PrivacyError/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/ohosTest/module.json5 b/Privacy/PrivacyError/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d6e097f5c40fa2cb85e8a22995a9c31f5dff5409 --- /dev/null +++ b/Privacy/PrivacyError/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "PrivacyError_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Privacy/PrivacyError/src/test/List.test.ets b/Privacy/PrivacyError/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/Privacy/PrivacyError/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/Privacy/PrivacyError/src/test/LocalUnit.test.ets b/Privacy/PrivacyError/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/Privacy/PrivacyError/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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/Privacy/build-profile.json5 b/Privacy/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..9836fe5f95babae5dedd4dc1adb30c9b7f3e8bf2 --- /dev/null +++ b/Privacy/build-profile.json5 @@ -0,0 +1,78 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "targetSdkVersion": "5.0.5(17)", + "compatibleSdkVersion": "5.0.5(17)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "privacy", + "srcPath": "./privacy", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "PrivacyError", + "srcPath": "./PrivacyError", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "ContactData", + "srcPath": "./ContactData", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "ContactDataError", + "srcPath": "./ContactDataError", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Privacy/hvigor/hvigor-config.json5 b/Privacy/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5bebc9755447385d82ce4138f54d991b1f85f348 --- /dev/null +++ b/Privacy/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.5", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/Privacy/hvigorfile.ts b/Privacy/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/Privacy/hvigorfile.ts @@ -0,0 +1,6 @@ +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Privacy/oh-package.json5 b/Privacy/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a8aff0c5aff22d78aa26fd19c3861f4320e951ff --- /dev/null +++ b/Privacy/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.5", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/Privacy/privacy/.gitignore b/Privacy/privacy/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/Privacy/privacy/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/Privacy/privacy/build-profile.json5 b/Privacy/privacy/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4d611879c7913fb0610c686e2399258ab3a6dad1 --- /dev/null +++ b/Privacy/privacy/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/Privacy/privacy/hvigorfile.ts b/Privacy/privacy/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/Privacy/privacy/hvigorfile.ts @@ -0,0 +1,6 @@ +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Privacy/privacy/obfuscation-rules.txt b/Privacy/privacy/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/Privacy/privacy/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/Privacy/privacy/oh-package.json5 b/Privacy/privacy/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..77bdd46bfce81baed0c6a51d2c0fb09709cc9cf2 --- /dev/null +++ b/Privacy/privacy/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "privacy", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionAfter.ets b/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionAfter.ets new file mode 100644 index 0000000000000000000000000000000000000000..d108925ead9ec3ba964c3a4b5ce08b1aa20ed8da --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionAfter.ets @@ -0,0 +1,18 @@ +/** + * 最佳实践:应用资产保护设计 + * 场景二:HarmonyOS资产保护关键技术介绍-混淆后 + */ + +// [Start application_asset_protection_after] +function getAgeInfo() { + let c = 0x14; + let b = 'jack'; + if (b) { + return c; + } else { + return -0x1; + } +} + +console['log']('' + getAgeInfo()); +// [End application_asset_protection_after] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionBefore.ets b/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionBefore.ets new file mode 100644 index 0000000000000000000000000000000000000000..73b98f3e57a7aba4cde86385d6a50e757e5bc92d --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/ApplicationAssetProtectionBefore.ets @@ -0,0 +1,18 @@ +/** + * 最佳实践:应用资产保护设计 + * 场景一:HarmonyOS资产保护关键技术介绍-混淆前 + */ + +// [Start application_asset_protection_before] +function getAgeInfo() { + let age = 20; + let name = 'jack'; + if (name) { + return age; + } else { + return -1; + } +} + +console.log('' + getAgeInfo()); +// [End application_asset_protection_before] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/CheckWantOne.ets b/Privacy/privacy/src/main/ets/pages/CheckWantOne.ets new file mode 100644 index 0000000000000000000000000000000000000000..0f9b94b550b66745b0f76d7d39588026e5b763b4 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/CheckWantOne.ets @@ -0,0 +1,32 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十五:建议对跨信任边界传入的Want进行合法性判断-确保访问的对象属性存在 + */ + + +// [Start check_want_one] +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit'; + + +// Check function +function checkWant(want: Want) { + if (want === null || want.parameters === null + || want === undefined || want.parameters === undefined) { + return false; + } + return true; +} + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + if (checkWant(want)) { + console.info("invalid want"); + } else { + console.info("correct want"); + } + } +} +// [End check_want_one] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/CheckWantTwo.ets b/Privacy/privacy/src/main/ets/pages/CheckWantTwo.ets new file mode 100644 index 0000000000000000000000000000000000000000..c1608c3bbf8c92d21149c463d8ef97331a8a92c6 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/CheckWantTwo.ets @@ -0,0 +1,35 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十六:建议对跨信任边界传入的Want进行合法性判断-进行try...catch异常捕获 + */ + +// [Start check_want_two] +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit'; + +// Check function +function checkWant(want: Want) { + try { + if (want.parameters) { + let param = want.parameters["test"] as Want; + let str = param.uri + console.info("get uri string: " + str); + } + } catch (e) { + return false + } + return true; +} + + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + if (checkWant(want)) { + console.info("invalid want"); + } else { + console.info("correct want"); + } + } +} +// [End check_want_two] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/CodeConfusion.cpp b/Privacy/privacy/src/main/ets/pages/CodeConfusion.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98ee3d66fa0f0c4b0a5458447b8be01260c3a2fe --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/CodeConfusion.cpp @@ -0,0 +1,26 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景三十二:正确示例,开启属性混淆例子 + */ + +// [Start code_confusion] +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# 开启对象属性混淆 +-enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope +// [End code_confusion] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/Cybersecurity.cpp b/Privacy/privacy/src/main/ets/pages/Cybersecurity.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5ac7bb67218c4630fd1e52c8c05d2e360eeb752f --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/Cybersecurity.cpp @@ -0,0 +1,112 @@ +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景一:配置信任系统预置的CA证书 + */ +// [Start cybersecurity_ca] +curl_easy_setopt( curl, CURLOPT_CATH, "/etc/security/certificates"); +// [End cybersecurity_ca] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景二:配置不信任用户安装的CA证书 + */ + +// [Start cybersecurity_not_trusting_ca] +{ + "network-security-config": { + ... ... + }, + "trust-global-user-ca": false, //Configure whether to trust the CA certificate manually installed by the enterprise MDM system or device administrator. The default value is true + "trust-current-user-ca": false // Configure whether to trust the CA certificate installed by the current user. The default value is true +} +// [End cybersecurity_not_trusting_ca] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景三:配置信任应用管理的CA证书 + */ + +// [Start cybersecurity_trusting_ca] +{ + "network-security-config": { + "base-config": { + "trust-anchors": [ + { + "certificates": "/res/appCaCert" + } + ] + }, + "domain-config": [ + { + "domains": [ + { + "include-subdomains": true, + "name": "example.com" + } + ], + "trust-anchors": [ + { + "certificates": "/res/domainCaCert" + } + ] + } + ] + } +} +// [End cybersecurity_trusting_ca] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景六:配置信任应用管理的CA证书-应用使用三方库进行网络连接 + */ +// [Start cybersecurity_trusting_ca_others] +curl_easy_setopt( curl, CURLOPT_CATH, "/res/domainCaCert"); +// [End cybersecurity_trusting_ca_others] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景七:配置SSL Pinning证书锁定-通过network_config.json文件进行静态SSL Pinning配置 + */ + +// [Start ssl_pining_json] +{ + "network-security-config": { + "domain-config": [ + { + "domains": [ + { + "include-subdomains": true, + "name": "server.com" + } + ], + "pin-set": { + "expiration": "2024-11-08", + "pin": [ + { + "digest-algorithm": "sha256", + "digest": "g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE=" //服务器证书公钥的hash + } + ] + } + } + ] + } +} +// [End ssl_pining_json] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景八:配置SSL Pinning证书锁定-代码中动态设置进行动态SSL Pinning配置 + */ + +// [Start certificate_pinning] + certificatePinning: [ //Optional, supports dynamic setting of certificate lock configuration information. This property is supported since API 12 + { + publicKeyHash: 'g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE=', // Hash of the server certificate public key + hashAlgorithm: 'SHA-256' + }, { + publicKeyHash: 'MGFiY2UyMDk5ZjEyMzI3MWQ4MDMyY2E4ODEzMmY3EtE=', // Hash of the secondary public key of the server certificate + hashAlgorithm: 'SHA-256' + } + ] +// [End certificate_pinning] diff --git a/Privacy/privacy/src/main/ets/pages/GeolocationAccess.ets b/Privacy/privacy/src/main/ets/pages/GeolocationAccess.ets new file mode 100644 index 0000000000000000000000000000000000000000..aa7d0068d5b3f74dab7a3f5f6106f17209dfbf17 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/GeolocationAccess.ets @@ -0,0 +1,39 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十:避免在用户同意前返回位置信息 + */ + +// [Start geolocation_access] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController() + + build() { + Column() { + Web({ src: 'www.example.com', controller: this.controller }) + .geolocationAccess(true) + .onGeolocationShow((event) => { + if (event === undefined) { + return + } + AlertDialog.show({ + title: 'title', + message: 'text', + confirm: { + value: 'onConfirm', + action: () => { + event.geolocation.invoke(event.origin, true, true); + } + }, + cancel: () => { + event.geolocation.invoke(event.origin, false, true); + } + }) + }) + } + } +} +// [End geolocation_access] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/Index.ets b/Privacy/privacy/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8e2d24ad42693fc877d51bb7820f0a9da68fa135 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/Index.ets @@ -0,0 +1,23 @@ +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + build() { + RelativeContainer() { + Text(this.message) + .id('HelloWorld') + .fontSize($r('app.float.page_text_font_size')) + .fontWeight(FontWeight.Bold) + .alignRules({ + center: { anchor: '__container__', align: VerticalAlign.Center }, + middle: { anchor: '__container__', align: HorizontalAlign.Center } + }) + .onClick(() => { + this.message = 'Welcome'; + }) + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/NetworkTrust.ets b/Privacy/privacy/src/main/ets/pages/NetworkTrust.ets new file mode 100644 index 0000000000000000000000000000000000000000..c63d9836c52c0c732280821704d9877862d7dd24 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/NetworkTrust.ets @@ -0,0 +1,64 @@ +import { BusinessError } from '@kit.BasicServicesKit' +import { http } from '@kit.NetworkKit' +import { rcp } from '@kit.RemoteCommunicationKit'; + +let httpRequest = http.createHttp(); +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景四:配置信任应用管理的CA证书-Network Kit + */ +// [Start cybersecurity_network_trusting_ca] +httpRequest.request( "EXAMPLE_URL", { + method: http.RequestMethod.POST, + header: { + 'Content-Type': 'application/json' + }, + extraData: "data to send", + expectDataType: http.HttpDataType.STRING, + connectTimeout: 60000, + caPath:'/res/domainCaCert', // Specifies the trusted CA certificate path +}, (err: BusinessError, data: http.HttpResponse) => { + // ... +}) +// [End cybersecurity_network_trusting_ca] + +/** + * 最佳实践:网络连接安全配置开发实践 + * 场景五:配置信任应用管理的CA证书-Remote Communication Kit + */ + +// [Start cybersecurity_rcp_trusting_ca] +const caPath: rcp.CertificateAuthority = { + folderPath: '/res/appCaCert', // 指定信任的CA证书路径 +} +const securityConfig: rcp.SecurityConfiguration = { + remoteValidation: caPath +}; +// Use the security configuration in the session creation +const sessionWithSecurityConfig = rcp.createSession({ requestConfiguration: { security: securityConfig } }); +// [End cybersecurity_rcp_trusting_ca] + +let HTTP_SERVER = '1' +const RemoteCommunicationKit = async () => { + /** + * 最佳实践:网络连接安全配置开发实践 + * 场景九:配置SSL Pinning证书锁定-Remote Communication Kit配置动态SSL Pinning + */ + // [Start rcp_ssl_pinning] + const keyHash: string = 'g8CsdcpyAKxmLoWFvMd2hC7ZDUy7L4E2NYOi1i8qEtE='; //服务器证书的公钥 + const session = rcp.createSession(); + const request = new rcp.Request(HTTP_SERVER); + const pin: rcp.CertificatePinning = { + kind: 'public-key', + publicKeyHash: keyHash, + hashAlgorithm: 'SHA-256' + }; + request.configuration = { + security: { + certificatePinning: pin, + } + }; + const resp = await session.fetch(request); + // [End rcp_ssl_pinning] +} + diff --git a/Privacy/privacy/src/main/ets/pages/NoInfoJumpTo.ets b/Privacy/privacy/src/main/ets/pages/NoInfoJumpTo.ets new file mode 100644 index 0000000000000000000000000000000000000000..5aae257b7b576a49dc5fc07d90685530d67e3a35 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/NoInfoJumpTo.ets @@ -0,0 +1,34 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景六:建议隐式启动应用组件时避免携带个人数据 + */ + +// [Start want_info] +import { Want } from "@kit.AbilityKit"; +// [StartExclude want_info] +import { common } from '@kit.AbilityKit'; +const uiContext: UIContext | undefined = AppStorage.get('uiContext'); +let context = uiContext!.getHostContext()!; +class NoInfo { + private context = context as common.UIAbilityContext + + wantNoInfo(): void { + // [EndExclude want_info] + let wantInfo:Want = { + deviceId: '', + action: "ability.want.test", + bundleName:'com.example.myapplication10', + abilityName:'MainAbility1', + parameters: { + "password": "xxxxxxxx" + } + } + try{ + let data = this.context.startAbility(wantInfo) + console.info("startAbility success " + JSON.stringify(data)); + } catch (err) { + console.error("startAbility with error message: " + err.message + ", error code: " + err.code); + } + // [End want_info] + } +} diff --git a/Privacy/privacy/src/main/ets/pages/OnSslErrorEventReceive.ets b/Privacy/privacy/src/main/ets/pages/OnSslErrorEventReceive.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb01e8c746b91a2668a6ec0d21e8ba63dfcf5b8e --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/OnSslErrorEventReceive.ets @@ -0,0 +1,23 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十八:避免在SSL校验出错时继续加载页面 + */ + +// [Start on_ssl_error_event_receive] +import { webview } from '@kit.ArkWeb'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController() + build() { + Column() { + Web({ src: 'www.example.com', controller: this.controller }) + .onSslErrorEventReceive((event) => { + console.info('ssl check failed,error is : ' + event.error.toString()) + event.handler.handleCancel(); + }) + } + } +} +// [End on_ssl_error_event_receive] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/PrivacyMode.ets b/Privacy/privacy/src/main/ets/pages/PrivacyMode.ets new file mode 100644 index 0000000000000000000000000000000000000000..bbf3bf52a626e4343e537d539eb40c82680f3373 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/PrivacyMode.ets @@ -0,0 +1,39 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景七:避免涉及口令输入的应用界面可以被截屏或录屏 + */ +// [Start privacy_mode] +import { router, window } from '@kit.ArkUI'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World'; + + onPageShow(): void { + window.getLastWindow(getContext(this)).then((windowStage: window.Window) => { + windowStage.setWindowPrivacyMode(true); + }); + } + onPageHide(): void { + window.getLastWindow(getContext(this)).then((windowStage: window.Window) => { + windowStage.setWindowPrivacyMode(false); + }); + } + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button('click to start Succ Page') + .onClick(async () => { + router.pushUrl({ url: 'pages/loginSuccPage' }) + }) + } + .width('100%') + } + .height('100%') + } +} +// [End privacy_mode] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/PublicSafeInfo.ets b/Privacy/privacy/src/main/ets/pages/PublicSafeInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..6db0f016eae8c1a20d4af042338a239739493dbd --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/PublicSafeInfo.ets @@ -0,0 +1,23 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景九:避免使用携带个人数据未设置权限的动态公共事件 + */ + +// [Start public_safe_info] +import { commonEventManager } from '@kit.BasicServicesKit'; + +function publishEventWithData() { + let options: commonEventManager.CommonEventPublishData = { + code: 1, + data: "ContactData", // Sending sensitive data + subscriberPermissions: ["ohos.permission.READ_CONTACTS"], // Set the permission + } + commonEventManager.publish("MyCommonEvent", options, (err) => { + if (err.code) { + console.error("publish event error: " + err.code + ", " + err.message + ", " + err.name + ", " + err.stack); + } else { + console.info("publish event with data Succeeded"); + } + }) +} +// [End public_safe_info] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/PublicSensitive.ets b/Privacy/privacy/src/main/ets/pages/PublicSensitive.ets new file mode 100644 index 0000000000000000000000000000000000000000..9267a7ed74ff6161c51dcd8c62025288225f9825 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/PublicSensitive.ets @@ -0,0 +1,42 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十一:建议对涉及敏感功能的公共事件进行访问权限控制 + */ + +// [Start public_sensitive] +import { commonEventManager } from '@kit.BasicServicesKit'; + +let subscriber: commonEventManager.CommonEventSubscriber; +//Subscriber information +let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = { + events: ["event"], + publisherPermission: "ohos.permission.publisherPermission1", // Set the subscription permission +}; + +// Create a subscriber +try { + commonEventManager.createSubscriber(subscribeInfo, (err, commonEventSubscriber) => { + if (!err) { + console.info("createSubscriber"); + subscriber = commonEventSubscriber; + //Subscribe to public events + try { + commonEventManager.subscribe(subscriber, (err, data) => { + if (err) { + console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); + } else { + //Event processing after receiving public events + // doSomeDangerousThing(data) + } + }); + } catch (err) { + console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); + } + } else { + console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); + } + }); +} catch (err) { + console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); +} +// [End public_sensitive] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/RunJavaScript.ets b/Privacy/privacy/src/main/ets/pages/RunJavaScript.ets new file mode 100644 index 0000000000000000000000000000000000000000..f274cf4da4c1a1153834806ffac7fa5ddcb1d249 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/RunJavaScript.ets @@ -0,0 +1,34 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十三:避免加载不可信的JavaScript脚本 + */ + +// [Start run_java_script] +import { webview } from '@kit.ArkWeb'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Web({ src: $rawfile('index.html'), controller: this.controller }) + .javaScriptAccess(true) + .onPageEnd(e => { + this.controller.runJavaScript('test()') + .then((result) => { + console.log('result: ' + result); + }) + .catch((error: BusinessError) => { + console.error(`ErrorCode: ${error.code}, Message: ${error.message}`); + }) + if (e) { + console.info('url: ', e.url); + } + }) + } + } +} +// [End run_java_script] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/RunJavaScriptTrustList.ets b/Privacy/privacy/src/main/ets/pages/RunJavaScriptTrustList.ets new file mode 100644 index 0000000000000000000000000000000000000000..b3c7a9ccab258fbb6cd68ae94c962865f6fb4553 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/RunJavaScriptTrustList.ets @@ -0,0 +1,45 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十五:避免加载不可信的JavaScript脚本—加载前进行白名单校验 + */ + +// [Start check_the_trust_list] +import { webview } from '@kit.ArkWeb'; +import { BusinessError } from '@kit.BasicServicesKit'; + + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + + + build() { + Column() { + Web({ src: $rawfile('index.html'), controller: this.controller }) + .javaScriptAccess(true) + .onPageEnd(e => { + let whiteMethods = ["test()", "test1()"] + let jsMethod: string = "alert(`xss`)" // Externally controllable fields + // Check the trustlist + if (whiteMethods.indexOf(jsMethod) === -1) { + console.error("input method not in whiteList") + return + } + this.controller.runJavaScript(jsMethod) + .then((result) => { + console.log('result: ' + result); + }) + .catch((error: BusinessError) => { + console.error(`ErrorCode: ${error.code}, Message: ${error.message}`); + }) + if (e) { + console.info('url: ', e.url); + } + + + }) + } + } +} +// [End check_the_trust_list] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/SignInfo.cpp b/Privacy/privacy/src/main/ets/pages/SignInfo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f6d95e3ba9f5ae60b42636bfd3e242cab9af7483 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/SignInfo.cpp @@ -0,0 +1,22 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景三十三:建议应用软件应包含的签名信息需要真实有效错误示例 + */ +// [Start sign_info_error] +10-11 17:51:53 WARN - Missing parameter: outproof +10-11 17:51:53 INFO - Find Hap Signing Block success, version: 3, block count: 2 +10-11 17:51:54 INFO - +++++++++++++++++++++++++++certificate #0 +++++++++++++++++++++++++++++++ +10-11 17:51:54 INFO - Subject: C=CN, O=Organization, OU=Unit, CN=ide_demo_app // CN字段无法标识开发组织 +10-11 17:51:54 INFO - Issuer: CN=OpenHarmony Application CA, OU=OpenHarmony Team, O=OpenHarmony, C=CN +// [End sign_info_error] +/** + * 最佳实践:应用安全编码实践 + * 场景三十二:建议应用软件应包含的签名信息需要真实有效 + */ +// [Start sign_info] +10-11 17:51:54 INFO - Issuer: CN=OpenHarmony Application CA, OU=OpenHarmony Team, O=OpenHarmony, C=CN +10-11 17:52:21 WARN - Missing parameter: outproof +10-11 17:52:21 INFO - Find Hap Signing Block success, version: 3, block count: 2 +10-11 17:52:21 INFO - +++++++++++++++++++++++++++certificate #0 +++++++++++++++++++++++++++++++ +10-11 17:52:21 INFO - Subject: CN=应用名称, OU=开发者组织/公司/部门, O=开发者组织/公司/部门, C=CN // CN字段标识开发组织 +// [End sign_info] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/TrustListCheck.ets b/Privacy/privacy/src/main/ets/pages/TrustListCheck.ets new file mode 100644 index 0000000000000000000000000000000000000000..bc6da5080d6249655bc03488f8f87e29f765f6ef --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/TrustListCheck.ets @@ -0,0 +1,73 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十三:避免注册返回含有全局认证凭据的JavaScriptProxy-修改方法一 + */ + +// [Start trust_list_check] +// Index.ets +import { uri } from '@kit.ArkTS'; +import { webview } from '@kit.ArkWeb'; + + +// Check function +function checkUrl(surl: string): boolean { + let tmpUri: uri.URI = new uri.URI(surl); + let res = tmpUri.normalize(); // Note that you need to normalize tmpUri first. Otherwise, security verification will be bypassed + console.info("res.scheme:" + res.scheme) // scheme + console.info("res.host:" + res.host) // host + console.info("res.port:" + res.port) // port + console.info("res.path:" + res.path) // path + console.info("res.ssp:" + res.ssp) + // After obtaining the values of the scheme, host, port, and path parameters, perform security verification based on the service requirements + // The part is omitted here. The verification is performed based on the service requirements + if ("校验成功") { + return true; + } + return false +} + + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController() + + + build() { + Column() { + Row() { + Button('registerJavaScriptProxy').onClick(() => { + this.controller.registerJavaScriptProxy( + { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + "objName", + ["getServiceToken"], + ); + this.controller.refresh() + }) + } + + + Web({ src: $rawfile('H5CallETS.html'), controller: this.controller }) + .javaScriptProxy({ + object: { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + name: "objName", + methodList: ["getServiceToken"], + controller: this.controller + }) + .onLoadIntercept((event) => { + console.info('onLoadIntercept:' + event.data.toString()) + let tempUrl = event.data.toString() + return checkUrl(tempUrl); // Returns true to block the load, otherwise allow the load + }) + } + } +} +// [End trust_list_check] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/UrlListCheck.ets b/Privacy/privacy/src/main/ets/pages/UrlListCheck.ets new file mode 100644 index 0000000000000000000000000000000000000000..1224c90a3287bae1a42407bad42675a35cfa0c9c --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/UrlListCheck.ets @@ -0,0 +1,69 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景二十四:避免注册返回含有全局认证凭据的JavaScriptProxy-修改方法二 + */ + +// [Start url_list_check] +// Index.ets +import { url } from '@kit.ArkTS'; +import { webview } from '@kit.ArkWeb'; + +// Check Function +function checkUrl(surl: string): boolean { + let tmpUrl = url.URL.parseURL(surl); + console.info("res.scheme:" + tmpUrl.protocol) // scheme + console.info("res.host:" + tmpUrl.host) // host + console.info("res.port:" + tmpUrl.port) // port + console.info("res.path:" + tmpUrl.pathname) // path + console.info("res.ssp:" + tmpUrl.hostname) // ssp + // After obtaining the values of the scheme, host, port, and path parameters, perform security verification based on the service requirements + // The part is omitted here. The verification is performed based on the service requirements + if ("校验成功") { + return true; + } + return false +} + +@Entry +@Component +struct Index { + controller: webview.WebviewController = new webview.WebviewController() + + build() { + Column() { + Row() { + Button('registerJavaScriptProxy').onClick(() => { + this.controller.registerJavaScriptProxy( + { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + "objName", + ["getServiceToken"] + ); + this.controller.refresh() + }) + } + + Web({ src: $rawfile('H5CallETS.html'), controller: this.controller }) + .javaScriptAccess(true) + .javaScriptProxy({ + object: { + getServiceToken: () => { + return "DLFJSLDFJALGJLDFJSDDFISLDF323LSDJFLS212DLSFJOEV"; + } + }, + name: "objName", + methodList: ["getServiceToken"], + controller: this.controller + }) + .onLoadIntercept((event) => { + console.info('wzz:onLoadIntercept:' + event.data.toString()) + let tempUrl = event.data.toString() + return checkUrl(tempUrl); // Returns true to block the load, otherwise allow the load + }) + } + } +} +// [End url_list_check] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/WantScene.ts b/Privacy/privacy/src/main/ets/pages/WantScene.ts new file mode 100644 index 0000000000000000000000000000000000000000..88eb73ec6b548b4adac9cf9121e8653e45d216c0 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/WantScene.ts @@ -0,0 +1,27 @@ +import { AbilityConstant, Want } from '@kit.AbilityKit'; +import { rpc } from '@kit.IPCKit'; + +interface WantScene { + /** + * 最佳实践:应用安全编码实践 + * 场景二十七:建议对跨信任边界传入的Want进行合法性判断-在不同场景下获取Want的方式 + */ + + // [Start want_scene] + // Application life cycle: + // @ohos.application.AbilityStage.d.ts + onAcceptWant(want: Want): string; + // ability life cycle: + // @ohos.application.Ability.d.ts + onCreate(want: Want, param: AbilityConstant.LaunchParam): void; + onContinue(wantParam: {}): AbilityConstant.OnContinueResult; + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; + // ServiceExtensionAbility life cycle: + // @ohos.application.ServiceExtensionAbility.d.ts + onCreate(want: Want): void; + onRequest(want: Want, startId: number): void; + onConnect(want: Want): rpc.RemoteObject; + onDisconnect(want: Want): void; + onReconnect(want: Want): void; + // [End want_scene] +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/WebUrlSafe.ets b/Privacy/privacy/src/main/ets/pages/WebUrlSafe.ets new file mode 100644 index 0000000000000000000000000000000000000000..5e77b0678624ea768dbde26a803cc1b351ce5043 --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/WebUrlSafe.ets @@ -0,0 +1,49 @@ +/** + * 最佳实践:应用安全编码实践 + * 场景十二:避免加载不安全的URL或页面 + */ +// [Start web_view_safe_url] +import { uri } from '@kit.ArkTS'; +import { webview } from '@kit.ArkWeb'; + +// Check function +function checkUrl(str: string): boolean { + let tmpUri = new uri.URI(str); + let res = + tmpUri.normalize(); // Note that you need to normalize tmpUri first. Otherwise, security verification will be bypassed + console.info("res.scheme:" + res.scheme) // Protocol + console.info("res.host:" + res.host) // domain name + console.info("res.port:" + res.port) // Ports + console.info("res.path:" + res.path) // Path + console.info("res.ssp:" + res.ssp) + // After obtaining the values of scheme, host, port, and path, perform security verification based on the actual service + // Omit the part here. Perform the verification based on service requirements + if ("校验成功") { + return true; + } + return false +} + +@Entry +@Component +struct WebComponent { + controller: webview.WebviewController = new webview.WebviewController(); + + build() { + Column() { + Button("loadUrl") + .onClick(() => { + this.controller.loadUrl('www.huawei.com') + }) + .margin({ top: 50 }) + Web({ src: 'www.huawei.com', controller: this.controller }) + .onLoadIntercept((event) => { + console.info('onLoadIntercept:' + event.data.toString()) + let tempUrl = event.data.toString() + return checkUrl(tempUrl) // Return true to block the load, otherwise allow the load + }) + } + } +} + +// [End web_view_safe_url] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/pages/app_json.md b/Privacy/privacy/src/main/ets/pages/app_json.md new file mode 100644 index 0000000000000000000000000000000000000000..a1dacbe57516afcc48ee9a139ba4e81572928b0c --- /dev/null +++ b/Privacy/privacy/src/main/ets/pages/app_json.md @@ -0,0 +1,28 @@ +/** +* 最佳实践:应用安全编码实践 +* 场景三十:建议正确设置发布版本应用调试属性错误示例 + */ +// [Start app_json_error] +// app.json5 +{ + "app": { + "bundleName": "com.application.music", + "vendor": "application", + "versionCode": 1, + "versionName": "1.0", + "minCompatibleVersionCode": 1, + "minAPIVersion": 7, + "targetAPIVersion": 8, + "apiReleaseType": "Release", + "debug": true, // debug字段设置 + "icon": "$media:app_icon", + "label": "$string:app_name", + "description": "$string:description_application", + "distributedNotificationEnabled": true, + "entityType": "game", + "car": { + "apiCompatibleVersion": 8 + } + } +} +// [End app_json_error] \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/privacyability/PrivacyAbility.ets b/Privacy/privacy/src/main/ets/privacyability/PrivacyAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8c0cad413628198049a3a231e52ea40f6fa21048 --- /dev/null +++ b/Privacy/privacy/src/main/ets/privacyability/PrivacyAbility.ets @@ -0,0 +1,44 @@ +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +const DOMAIN = 0x0000; + +export default class PrivacyAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err)); + return; + } + hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); + } +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/ets/privacybackupability/PrivacyBackupAbility.ets b/Privacy/privacy/src/main/ets/privacybackupability/PrivacyBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4aa035c51ba541b14f2afa1fe0353968e4889ddc --- /dev/null +++ b/Privacy/privacy/src/main/ets/privacybackupability/PrivacyBackupAbility.ets @@ -0,0 +1,16 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +const DOMAIN = 0x0000; + +export default class PrivacyBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(DOMAIN, 'testTag', 'onBackup ok'); + await Promise.resolve(); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + await Promise.resolve(); + } +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/module.json5 b/Privacy/privacy/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2f1ce9ad0cdaa43b9be2cae7072d3c87704314d4 --- /dev/null +++ b/Privacy/privacy/src/main/module.json5 @@ -0,0 +1,60 @@ +{ + "module": { + "name": "privacy", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "PrivacyAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + /** + * 最佳实践:应用安全编码实践 + * 场景二:通用组件安全正确示例 + */ + + // [Start module_json_abilities] + "name": "PrivacyAbility", + "srcEntry": "./ets/privacyability/PrivacyAbility.ets", + "description": "$string:PrivacyAbility_desc", + "exported": false, + // [End module_json_abilities] + "icon": "$media:layered_image", + "label": "$string:PrivacyAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "PrivacyBackupAbility", + "srcEntry": "./ets/privacybackupability/PrivacyBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ], + } + ] + } +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/base/element/color.json b/Privacy/privacy/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/base/element/float.json b/Privacy/privacy/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..33ea22304f9b1485b5f22d811023701b5d4e35b6 --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/Privacy/privacy/src/main/resources/base/element/string.json b/Privacy/privacy/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..4aeaabf1612bd4f19a3208e044f80a49b0d731d1 --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "PrivacyAbility_desc", + "value": "description" + }, + { + "name": "PrivacyAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/base/media/background.png b/Privacy/privacy/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/Privacy/privacy/src/main/resources/base/media/background.png differ diff --git a/Privacy/privacy/src/main/resources/base/media/foreground.png b/Privacy/privacy/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/Privacy/privacy/src/main/resources/base/media/foreground.png differ diff --git a/Privacy/privacy/src/main/resources/base/media/layered_image.json b/Privacy/privacy/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/base/media/startIcon.png b/Privacy/privacy/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/Privacy/privacy/src/main/resources/base/media/startIcon.png differ diff --git a/Privacy/privacy/src/main/resources/base/profile/backup_config.json b/Privacy/privacy/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/base/profile/main_pages.json b/Privacy/privacy/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/Privacy/privacy/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/Privacy/privacy/src/main/resources/dark/element/color.json b/Privacy/privacy/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/Privacy/privacy/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/rawfile/H5CallETS.html b/Privacy/privacy/src/main/resources/rawfile/H5CallETS.html new file mode 100644 index 0000000000000000000000000000000000000000..a0bf8a2428e3a86d8148736d6f535565f71905a3 --- /dev/null +++ b/Privacy/privacy/src/main/resources/rawfile/H5CallETS.html @@ -0,0 +1,16 @@ + + + + +Hello js call ets interface! +
+ + + + \ No newline at end of file diff --git a/Privacy/privacy/src/main/resources/rawfile/index.html b/Privacy/privacy/src/main/resources/rawfile/index.html new file mode 100644 index 0000000000000000000000000000000000000000..df9d2b2b00f3a7d6467a45fa09a7bf07a3bcac9f --- /dev/null +++ b/Privacy/privacy/src/main/resources/rawfile/index.html @@ -0,0 +1,22 @@ + + +// [Start run_java_script_html] + + + + +Hello world! + + + +// [End run_java_script_html] \ No newline at end of file diff --git a/Privacy/privacy/src/mock/mock-config.json5 b/Privacy/privacy/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7a73a41bfdf76d6f793007240d80983a52f15f97 --- /dev/null +++ b/Privacy/privacy/src/mock/mock-config.json5 @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Privacy/privacy/src/ohosTest/ets/test/Ability.test.ets b/Privacy/privacy/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..85c78f67579d6e31b5f5aeea463e216b9b141048 --- /dev/null +++ b/Privacy/privacy/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // 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/Privacy/privacy/src/ohosTest/ets/test/List.test.ets b/Privacy/privacy/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..794c7dc4ed66bd98fa3865e07922906e2fcef545 --- /dev/null +++ b/Privacy/privacy/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Privacy/privacy/src/ohosTest/module.json5 b/Privacy/privacy/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a5a03a160e21e73f45d015c46d84665ee308b3dc --- /dev/null +++ b/Privacy/privacy/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "privacy_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Privacy/privacy/src/test/List.test.ets b/Privacy/privacy/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..bb5b5c3731e283dd507c847560ee59bde477bbc7 --- /dev/null +++ b/Privacy/privacy/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/Privacy/privacy/src/test/LocalUnit.test.ets b/Privacy/privacy/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..165fc1615ee8618b4cb6a622f144a9a707eee99f --- /dev/null +++ b/Privacy/privacy/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // 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(() => { + // 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(() => { + // 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(() => { + // 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, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + 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