diff --git a/AppScope/app.json b/AppScope/app.json
new file mode 100644
index 0000000..95b0a10
--- /dev/null
+++ b/AppScope/app.json
@@ -0,0 +1,15 @@
+
+
+{
+ "app": {
+ "bundleName": "com.ohos.permissionmanager",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name",
+ "distributedNotificationEnabled": true,
+ "minAPIVersion":9,
+ "targetAPIVersion":9
+ }
+}
diff --git a/AppScope/resources/base/element/string.json b/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000..4fe2f85
--- /dev/null
+++ b/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "权限管理"
+ }
+ ]
+}
diff --git a/AppScope/resources/base/media/app_icon.png b/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000..ce307a8
Binary files /dev/null and b/AppScope/resources/base/media/app_icon.png differ
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..e306802
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,29 @@
+import("//build/ohos.gni")
+
+ohos_hap("pm") {
+ hap_profile = "entry/src/main/module.json"
+ deps = [
+ ":permission_manager_js_assets",
+ ":permission_manager_resources",
+ ]
+ certificate_profile = "signature/pm_5.p7b"
+ hap_name = "pm"
+ part_name = "prebuilt_hap"
+ subsystem_name = "applications"
+}
+
+ohos_app_scope("permission_manager_app_profile") {
+ app_profile = "AppScope/app.json"
+ sources = [ "AppScope/resources" ]
+}
+
+ohos_js_assets("permission_manager_js_assets") {
+ ets2abc = true
+ source_dir = "entry/src/main/ets"
+}
+
+ohos_resources("permission_manager_resources") {
+ sources = [ "entry/src/main/resources" ]
+ deps = [ ":permission_manager_app_profile" ]
+ hap_profile = "entry/src/main/module.json"
+}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..4a45986
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100644
index 0000000..6433eb1
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build-profile.json5 b/build-profile.json5
new file mode 100644
index 0000000..7cba24b
--- /dev/null
+++ b/build-profile.json5
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "app": {
+ "compileSdkVersion": 9,
+ "compatibleSdkVersion": 9,
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default"
+ }
+ ],
+ "signingConfigs": [
+ {
+ "name": "default",
+ "material": {
+ "storePassword": "00000018696E371C175AF00C64950E33E3CC1A8BAF912DDF5AFF91F37C54F75068F765867F383828",
+ "certpath": "C:/Users/shuling/Desktop/pm/pm/pm.cer",
+ "keyAlias": "pm",
+ "keyPassword": "0000001838E443A71A0A95663A34E7D49B8D1BF20E20A97E8F11050CE5E3C5FFD11CBF738EBDA6B9",
+ "profile": "C:/Users/shuling/Desktop/pm/pm/pm_5.p7b",
+ "signAlg": "SHA256withECDSA",
+ "storeFile": "C:/Users/shuling/Desktop/pm/pm/pm.p12"
+ }
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "permissionmanager",
+ "srcPath": "./permissionmanager",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/build-profile.json5 b/entry/build-profile.json5
new file mode 100644
index 0000000..8d4191e
--- /dev/null
+++ b/entry/build-profile.json5
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "apiType": 'stageMode',
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/hvigorfile.js b/entry/hvigorfile.js
new file mode 100644
index 0000000..d7720ee
--- /dev/null
+++ b/entry/hvigorfile.js
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks
diff --git a/entry/package-lock.json b/entry/package-lock.json
new file mode 100644
index 0000000..15bc714
--- /dev/null
+++ b/entry/package-lock.json
@@ -0,0 +1,5 @@
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "lockfileVersion": 1
+}
diff --git a/entry/package.json b/entry/package.json
new file mode 100644
index 0000000..992c771
--- /dev/null
+++ b/entry/package.json
@@ -0,0 +1,14 @@
+{
+ "license":"ISC",
+ "devDependencies":{},
+ "name":"entry",
+ "ohos":{
+ "org":"huawei",
+ "directoryLevel":"module",
+ "buildTool":"hvigor"
+ },
+ "description":"example description",
+ "repository":{},
+ "version":"1.0.0",
+ "dependencies":{}
+}
\ No newline at end of file
diff --git a/entry/src/main/ets/Application/AbilityStage.ts b/entry/src/main/ets/Application/AbilityStage.ts
new file mode 100644
index 0000000..32dfe93
--- /dev/null
+++ b/entry/src/main/ets/Application/AbilityStage.ts
@@ -0,0 +1,7 @@
+import AbilityStage from "@ohos.application.AbilityStage"
+
+export default class MyAbilityStage extends AbilityStage {
+ onCreate() {
+ console.log("[Demo] MyAbilityStage onCreate")
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/ets/MainAbility/MainAbility.ts b/entry/src/main/ets/MainAbility/MainAbility.ts
new file mode 100644
index 0000000..edb9130
--- /dev/null
+++ b/entry/src/main/ets/MainAbility/MainAbility.ts
@@ -0,0 +1,34 @@
+import Ability from '@ohos.application.Ability'
+
+export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log("[Demo] MainAbility onCreate")
+ globalThis.abilityWant = want;
+ }
+
+ onDestroy() {
+ console.log("[Demo] MainAbility onDestroy")
+ }
+
+ onWindowStageCreate(windowStage) {
+ // Main window is created, set main page for this ability
+ console.log("[Demo] MainAbility onWindowStageCreate")
+
+ windowStage.setUIContent(this.context, "pages/index", null)
+ }
+
+ onWindowStageDestroy() {
+ // Main window is destroyed, release UI related resources
+ console.log("[Demo] MainAbility onWindowStageDestroy")
+ }
+
+ onForeground() {
+ // Ability has brought to foreground
+ console.log("[Demo] MainAbility onForeground")
+ }
+
+ onBackground() {
+ // Ability has back to background
+ console.log("[Demo] MainAbility onBackground")
+ }
+};
diff --git a/entry/src/main/ets/pages/index.ets b/entry/src/main/ets/pages/index.ets
new file mode 100644
index 0000000..54bfa30
--- /dev/null
+++ b/entry/src/main/ets/pages/index.ets
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@Entry
+@Component
+struct Index {
+ @State message: string = 'Hello World'
+
+ build() {
+ Row() {
+ Column() {
+ Text(this.message)
+ .fontSize(50)
+ .fontWeight(FontWeight.Bold)
+ }
+ .width('100%')
+ }
+ .height('100%')
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/module.json b/entry/src/main/module.json
new file mode 100644
index 0000000..a2c9221
--- /dev/null
+++ b/entry/src/main/module.json
@@ -0,0 +1,37 @@
+
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "srcEntrance": "./ets/Application/AbilityStage.ts",
+ "description": "$string:entry_desc",
+ "mainElement": "MainAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "uiSyntax": "ets",
+ "abilities": [
+ {
+ "name": "MainAbility",
+ "srcEntrance": "./ets/MainAbility/MainAbility.ts",
+ "description": "$string:MainAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:MainAbility_label",
+ "visible": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..490210a
--- /dev/null
+++ b/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "entry_desc",
+ "value": "description"
+ },
+ {
+ "name": "MainAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "MainAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000..ce307a8
Binary files /dev/null and b/entry/src/main/resources/base/media/icon.png differ
diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000..feec276
--- /dev/null
+++ b/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/index"
+ ]
+}
diff --git a/hvigorfile.js b/hvigorfile.js
new file mode 100644
index 0000000..5f2735e
--- /dev/null
+++ b/hvigorfile.js
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').appTasks
\ No newline at end of file
diff --git a/local.properties b/local.properties
new file mode 100644
index 0000000..d53b63a
--- /dev/null
+++ b/local.properties
@@ -0,0 +1,10 @@
+# This file is automatically generated by DevEco Studio.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file should *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# For customization when using a Version Control System, please read the header note.
+sdk.dir=C:/Users/shuling/AppData/Local/OpenHarmony/Sdk
+nodejs.dir=C:/Program Files/Huawei/DevEco Studio 3.0.0.900/tools/nodejs
+npm.dir=C:/Program Files/Huawei/DevEco Studio 3.0.0.900/tools/nodejs
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..638b410
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1643 @@
+{
+ "name": "permissionmanager",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@ohos/hvigor": {
+ "version": "1.0.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor/-/@ohos/hvigor-1.0.6.tgz",
+ "integrity": "sha512-jjp7vpvUOMW1Nf7TdyhOtonwWHoSyBJLUiZTQqIx/GJV4UJyIqsiURUOqFwncQ4L7PDdeHuWly4uEelknYeWhg==",
+ "requires": {
+ "@ohos/hvigor-base": "1.0.6",
+ "interpret": "1.4.0",
+ "liftoff": "4.0.0",
+ "mute-stdout": "1.0.0",
+ "pretty-hrtime": "1.0.0",
+ "v8flags": "3.2.0",
+ "yargs": "7.1.0"
+ }
+ },
+ "@ohos/hvigor-base": {
+ "version": "1.0.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor-base/-/@ohos/hvigor-base-1.0.6.tgz",
+ "integrity": "sha512-cRDnWICTxmpNiFb9clIioqP5Oik1seLCICztXVhZqultrHuxwTheCRUZrHwlpyWdkSB2Al+FFBqmSwzIgZX4IQ==",
+ "requires": {
+ "json5": "2.2.0",
+ "log4js": "6.4.1",
+ "undertaker": "1.2.1"
+ }
+ },
+ "@ohos/hvigor-ohos-plugin": {
+ "version": "1.0.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor-ohos-plugin/-/@ohos/hvigor-ohos-plugin-1.0.6.tgz",
+ "integrity": "sha512-MAAi8uJxMzODUoSSNfBr+fU4HQ20dfQtkje9I+X4asc7qY2kAplW/q9f5XS8IOvv8zhC8OcSgsAXOAJuLMstOQ==",
+ "requires": {
+ "@ohos/hvigor-base": "1.0.6",
+ "@ohos/sdkmanager-common": "1.1.3",
+ "ajv": "8.10.0",
+ "archiver": "5.3.0",
+ "execa": "5.1.1",
+ "fs-extra": "10.0.0",
+ "glob": "7.2.0",
+ "iconv-lite": "0.6.3",
+ "json5": "2.2.0",
+ "lodash": "4.17.21",
+ "pretty-hrtime": "1.0.3",
+ "resolve-package-path": "4.0.3"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "10.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fs-extra/-/fs-extra-10.0.0.tgz",
+ "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE="
+ }
+ }
+ },
+ "@ohos/sdkmanager-common": {
+ "version": "1.1.3",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/sdkmanager-common/-/@ohos/sdkmanager-common-1.1.3.tgz",
+ "integrity": "sha512-d2uhVauDDJZIUvyyaWWoavG4N/jLyfF5IH5kEXKV6R8HNf3606H1zDQzA+UZtOfwwJFXhD9djRjnVFNB8xc7aw=="
+ },
+ "ajv": {
+ "version": "8.10.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ajv/-/ajv-8.10.0.tgz",
+ "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "archiver": {
+ "version": "5.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/archiver/-/archiver-5.3.0.tgz",
+ "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==",
+ "requires": {
+ "archiver-utils": "^2.1.0",
+ "async": "^3.2.0",
+ "buffer-crc32": "^0.2.1",
+ "readable-stream": "^3.6.0",
+ "readdir-glob": "^1.0.0",
+ "tar-stream": "^2.2.0",
+ "zip-stream": "^4.1.0"
+ }
+ },
+ "archiver-utils": {
+ "version": "2.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/archiver-utils/-/archiver-utils-2.1.0.tgz",
+ "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
+ "requires": {
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.0",
+ "lazystream": "^1.0.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.difference": "^4.5.0",
+ "lodash.flatten": "^4.4.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.union": "^4.6.0",
+ "normalize-path": "^3.0.0",
+ "readable-stream": "^2.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ }
+ }
+ },
+ "arr-filter": {
+ "version": "1.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/arr-filter/-/arr-filter-1.1.2.tgz",
+ "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
+ },
+ "arr-map": {
+ "version": "2.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/arr-map/-/arr-map-2.0.2.tgz",
+ "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8="
+ },
+ "array-initial": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/array-initial/-/array-initial-1.1.0.tgz",
+ "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+ "requires": {
+ "array-slice": "^1.0.0",
+ "is-number": "^4.0.0"
+ }
+ },
+ "array-last": {
+ "version": "1.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "requires": {
+ "is-number": "^4.0.0"
+ }
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="
+ },
+ "async": {
+ "version": "3.2.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/async/-/async-3.2.3.tgz",
+ "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
+ },
+ "async-done": {
+ "version": "1.3.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/async-done/-/async-done-1.3.2.tgz",
+ "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.2",
+ "process-nextick-args": "^2.0.0",
+ "stream-exhaust": "^1.0.1"
+ }
+ },
+ "async-settle": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/async-settle/-/async-settle-1.0.0.tgz",
+ "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+ "requires": {
+ "async-done": "^1.2.2"
+ }
+ },
+ "bach": {
+ "version": "1.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/bach/-/bach-1.2.0.tgz",
+ "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+ "requires": {
+ "arr-filter": "^1.1.1",
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "array-each": "^1.0.0",
+ "array-initial": "^1.0.0",
+ "array-last": "^1.1.1",
+ "async-done": "^1.2.2",
+ "async-settle": "^1.0.0",
+ "now-and-later": "^2.0.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "bl": {
+ "version": "4.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "collection-map": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/collection-map/-/collection-map-1.0.0.tgz",
+ "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+ "requires": {
+ "arr-map": "^2.0.2",
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "compress-commons": {
+ "version": "4.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/compress-commons/-/compress-commons-4.1.1.tgz",
+ "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==",
+ "requires": {
+ "buffer-crc32": "^0.2.13",
+ "crc32-stream": "^4.0.2",
+ "normalize-path": "^3.0.0",
+ "readable-stream": "^3.6.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ },
+ "crc-32": {
+ "version": "1.2.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/crc-32/-/crc-32-1.2.2.tgz",
+ "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
+ },
+ "crc32-stream": {
+ "version": "4.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/crc32-stream/-/crc32-stream-4.0.2.tgz",
+ "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==",
+ "requires": {
+ "crc-32": "^1.2.0",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "dependencies": {
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "d": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/d/-/d-1.0.1.tgz",
+ "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "requires": {
+ "es5-ext": "^0.10.50",
+ "type": "^1.0.1"
+ }
+ },
+ "date-format": {
+ "version": "4.0.6",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/date-format/-/date-format-4.0.6.tgz",
+ "integrity": "sha512-B9vvg5rHuQ8cbUXE/RMWMyX2YA5TecT3jKF5fLtGNlzPlU7zblSPmAm2OImDbWL+LDOQ6pUm+4LOFz+ywS41Zw=="
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "default-resolution": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/default-resolution/-/default-resolution-2.0.0.tgz",
+ "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ="
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc="
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.59",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/es5-ext/-/es5-ext-0.10.59.tgz",
+ "integrity": "sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw==",
+ "requires": {
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.3",
+ "next-tick": "^1.1.0"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/es6-symbol/-/es6-symbol-3.1.3.tgz",
+ "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+ "requires": {
+ "d": "^1.0.1",
+ "ext": "^1.1.2"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.46",
+ "es6-iterator": "^2.0.3",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "ext": {
+ "version": "1.6.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ext/-/ext-1.6.0.tgz",
+ "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
+ "requires": {
+ "type": "^2.5.0"
+ },
+ "dependencies": {
+ "type": {
+ "version": "2.6.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/type/-/type-2.6.0.tgz",
+ "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ=="
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "5.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "fined": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
+ }
+ },
+ "flagged-respawn": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA=="
+ },
+ "flatted": {
+ "version": "3.2.5",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/flatted/-/flatted-3.2.5.tgz",
+ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg=="
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "fs-extra": {
+ "version": "10.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fs-extra/-/fs-extra-10.0.1.tgz",
+ "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+ },
+ "get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.9",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/graceful-fs/-/graceful-fs-4.2.9.tgz",
+ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
+ },
+ "hypium": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/hypium/-/hypium-1.0.0.tgz",
+ "integrity": "sha512-nl+RQVv2AU/5FvFRhsXyWO5wh+2huhdqRZ3bszBWZzW+kpNI3AT4ydvVRYIfaQbYwV4UlX/rSc7BtFjLAezhow=="
+ },
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-core-module": {
+ "version": "2.8.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-core-module/-/is-core-module-2.8.1.tgz",
+ "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ=="
+ },
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+ },
+ "json5": {
+ "version": "2.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
+ },
+ "last-run": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/last-run/-/last-run-1.1.1.tgz",
+ "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
+ "requires": {
+ "default-resolution": "^2.0.0",
+ "es6-weak-map": "^2.0.1"
+ }
+ },
+ "lazystream": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lazystream/-/lazystream-1.0.1.tgz",
+ "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==",
+ "requires": {
+ "readable-stream": "^2.0.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ }
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "liftoff": {
+ "version": "4.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/liftoff/-/liftoff-4.0.0.tgz",
+ "integrity": "sha512-rMGwYF8q7g2XhG2ulBmmJgWv25qBsqRbDn5gH0+wnuyeFt7QBJlHJmtg5qEdn4pN6WVAUMgXnIxytMFRX9c1aA==",
+ "requires": {
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "object.map": "^1.0.1",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
+ },
+ "lodash.difference": {
+ "version": "4.5.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.difference/-/lodash.difference-4.5.0.tgz",
+ "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
+ },
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
+ },
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+ },
+ "lodash.union": {
+ "version": "4.6.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/lodash.union/-/lodash.union-4.6.0.tgz",
+ "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
+ },
+ "log4js": {
+ "version": "6.4.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/log4js/-/log4js-6.4.1.tgz",
+ "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==",
+ "requires": {
+ "date-format": "^4.0.3",
+ "debug": "^4.3.3",
+ "flatted": "^3.2.4",
+ "rfdc": "^1.3.0",
+ "streamroller": "^3.0.2"
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.6",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "mute-stdout": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/mute-stdout/-/mute-stdout-1.0.0.tgz",
+ "integrity": "sha1-WzLqB+tDyd7WEwQ0z5JvRrKn/U0="
+ },
+ "next-tick": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/next-tick/-/next-tick-1.1.0.tgz",
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+ },
+ "now-and-later": {
+ "version": "2.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "requires": {
+ "once": "^1.3.2"
+ }
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "object.reduce": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/object.reduce/-/object.reduce-1.0.1.tgz",
+ "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0="
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pretty-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/pretty-hrtime/-/pretty-hrtime-1.0.0.tgz",
+ "integrity": "sha1-9ualItPmBwRSK/Db5oVu0g515Nw="
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "readdir-glob": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/readdir-glob/-/readdir-glob-1.1.1.tgz",
+ "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==",
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "requires": {
+ "resolve": "^1.20.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
+ },
+ "resolve": {
+ "version": "1.22.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/resolve/-/resolve-1.22.0.tgz",
+ "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
+ "requires": {
+ "is-core-module": "^2.8.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-package-path": {
+ "version": "4.0.3",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/resolve-package-path/-/resolve-package-path-4.0.3.tgz",
+ "integrity": "sha512-SRpNAPW4kewOaNUt8VPqhJ0UMxawMwzJD8V7m1cJfdSTK9ieZwS6K7Dabsm4bmLFM96Z5Y/UznrpG5kt1im8yA==",
+ "requires": {
+ "path-root": "^0.1.1"
+ }
+ },
+ "rfdc": {
+ "version": "1.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/rfdc/-/rfdc-1.3.0.tgz",
+ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.11",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g=="
+ },
+ "stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw=="
+ },
+ "streamroller": {
+ "version": "3.0.6",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/streamroller/-/streamroller-3.0.6.tgz",
+ "integrity": "sha512-Qz32plKq/MZywYyhEatxyYc8vs994Gz0Hu2MSYXXLD233UyPeIeRBZARIIGwFer4Mdb8r3Y2UqKkgyDghM6QCg==",
+ "requires": {
+ "date-format": "^4.0.6",
+ "debug": "^4.3.4",
+ "fs-extra": "^10.0.1"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "requires": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ }
+ }
+ },
+ "type": {
+ "version": "1.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/type/-/type-1.2.0.tgz",
+ "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
+ },
+ "undertaker": {
+ "version": "1.2.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/undertaker/-/undertaker-1.2.1.tgz",
+ "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+ "requires": {
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "bach": "^1.0.0",
+ "collection-map": "^1.0.0",
+ "es6-weak-map": "^2.0.1",
+ "last-run": "^1.1.0",
+ "object.defaults": "^1.0.0",
+ "object.reduce": "^1.0.0",
+ "undertaker-registry": "^1.0.0"
+ }
+ },
+ "undertaker-registry": {
+ "version": "1.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA="
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "v8flags": {
+ "version": "3.2.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "y18n": {
+ "version": "3.2.2",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.1",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/yargs-parser/-/yargs-parser-5.0.1.tgz",
+ "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "requires": {
+ "camelcase": "^3.0.0",
+ "object.assign": "^4.1.0"
+ }
+ },
+ "zip-stream": {
+ "version": "4.1.0",
+ "resolved": "https://repo.huaweicloud.com/repository/npm/zip-stream/-/zip-stream-4.1.0.tgz",
+ "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==",
+ "requires": {
+ "archiver-utils": "^2.1.0",
+ "compress-commons": "^4.1.0",
+ "readable-stream": "^3.6.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..eff7afc
--- /dev/null
+++ b/package.json
@@ -0,0 +1,18 @@
+{
+ "license":"ISC",
+ "devDependencies":{},
+ "name":"permissionmanager",
+ "ohos":{
+ "org":"huawei",
+ "directoryLevel":"project",
+ "buildTool":"hvigor"
+ },
+ "description":"example description",
+ "repository":{},
+ "version":"1.0.0",
+ "dependencies":{
+ "@ohos/hvigor-ohos-plugin":"1.0.6",
+ "hypium":"^1.0.0",
+ "@ohos/hvigor":"1.0.6"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/.gitignore b/permissionmanager/.gitignore
new file mode 100644
index 0000000..4f9a973
--- /dev/null
+++ b/permissionmanager/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/permissionmanager/BUILD.gn b/permissionmanager/BUILD.gn
new file mode 100644
index 0000000..b4a735c
--- /dev/null
+++ b/permissionmanager/BUILD.gn
@@ -0,0 +1,29 @@
+import("//build/ohos.gni")
+
+ohos_hap("pm_really") {
+ hap_profile = "src/main/module.json"
+ deps = [
+ ":permission_manager_js_assets",
+ ":permission_manager_resources",
+ ]
+ certificate_profile = "../signature/pm_5.p7b"
+ hap_name = "pm_really"
+ part_name = "prebuilt_hap"
+ subsystem_name = "applications"
+}
+
+ohos_app_scope("permission_manager_app_profile") {
+ app_profile = "../AppScope/app.json"
+ sources = [ "../AppScope/resources" ]
+}
+
+ohos_js_assets("permission_manager_js_assets") {
+ ets2abc = true
+ source_dir = "src/main/ets"
+}
+
+ohos_resources("permission_manager_resources") {
+ sources = [ "src/main/resources" ]
+ deps = [ ":permission_manager_app_profile" ]
+ hap_profile = "src/main/module.json"
+}
diff --git a/permissionmanager/build-profile.json5 b/permissionmanager/build-profile.json5
new file mode 100644
index 0000000..8d4191e
--- /dev/null
+++ b/permissionmanager/build-profile.json5
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "apiType": 'stageMode',
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permissionmanager/hvigorfile.js b/permissionmanager/hvigorfile.js
new file mode 100644
index 0000000..d7720ee
--- /dev/null
+++ b/permissionmanager/hvigorfile.js
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').hapTasks
diff --git a/permissionmanager/package-lock.json b/permissionmanager/package-lock.json
new file mode 100644
index 0000000..af63425
--- /dev/null
+++ b/permissionmanager/package-lock.json
@@ -0,0 +1,5 @@
+{
+ "name": "permissionmanager",
+ "version": "1.0.0",
+ "lockfileVersion": 1
+}
diff --git a/permissionmanager/package.json b/permissionmanager/package.json
new file mode 100644
index 0000000..215d504
--- /dev/null
+++ b/permissionmanager/package.json
@@ -0,0 +1,14 @@
+{
+ "license":"ISC",
+ "devDependencies":{},
+ "name":"permissionmanager",
+ "ohos":{
+ "org":"huawei",
+ "directoryLevel":"module",
+ "buildTool":"hvigor"
+ },
+ "description":"example description",
+ "repository":{},
+ "version":"1.0.0",
+ "dependencies":{}
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/Application/AbilityStage.ts b/permissionmanager/src/main/ets/Application/AbilityStage.ts
new file mode 100644
index 0000000..c5840e5
--- /dev/null
+++ b/permissionmanager/src/main/ets/Application/AbilityStage.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AbilityStage from "@ohos.application.AbilityStage"
+
+var TAG = "PermissionManager_MainAbility:"
+
+export default class MyAbilityStage extends AbilityStage {
+ onCreate() {
+ console.log(TAG + "MyAbilityStage onCreate.")
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/MainAbility/MainAbility.ts b/permissionmanager/src/main/ets/MainAbility/MainAbility.ts
new file mode 100644
index 0000000..fd4781d
--- /dev/null
+++ b/permissionmanager/src/main/ets/MainAbility/MainAbility.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ability from '@ohos.application.Ability';
+
+var TAG = "PermissionManager_MainAbility:";
+
+export default class MainAbility extends Ability {
+ onCreate(want, launchParam) {
+ console.log(TAG + "MainAbility onCreate, ability name is " + want.abilityName + ".");
+ globalThis.context = this.context;
+ }
+
+ onWindowStageCreate(windowStage) {
+ // Main window is created, set main page for this ability
+ console.log(TAG + "MainAbility onWindowStageCreate.");
+
+ globalThis.context = this.context;
+
+ windowStage.setUIContent(this.context, "pages/authority-management", null);
+ }
+
+ onForeground() {
+ // Ability has brought to foreground
+ console.log(TAG + "MainAbility onForeground.");
+ }
+
+ onBackground() {
+ // Ability has back to background
+ console.log(TAG + "MainAbility onBackground.");
+
+// this.context.terminateSelf();
+ }
+
+ onDestroy() {
+ console.log(TAG + "MainAbility onDestroy.");
+ }
+
+ onWindowStageDestroy() {
+ // Main window is destroyed, release UI related resources
+ console.log(TAG + "MainAbility onWindowStageDestroy.");
+ }
+};
diff --git a/permissionmanager/src/main/ets/ServiceExtAbility/ServiceExtAbility.ts b/permissionmanager/src/main/ets/ServiceExtAbility/ServiceExtAbility.ts
new file mode 100644
index 0000000..bd3544a
--- /dev/null
+++ b/permissionmanager/src/main/ets/ServiceExtAbility/ServiceExtAbility.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import extension from '@ohos.application.ServiceExtensionAbility';
+import window from '@ohos.window';
+import display from '@ohos.display';
+
+var TAG = "PermissionManager_Log:";
+const MAX_WIDTH = 790;
+const MAX_HEIGHT = 1100;
+
+export default class ServiceExtensionAbility extends extension {
+ /**
+ * Lifecycle function, called back when a service extension is started for initialization.
+ */
+ onCreate(want) {
+ console.info(TAG + "ServiceExtensionAbility onCreate, ability name is " + want.abilityName);
+
+ globalThis.extensionContext = this.context;
+ globalThis.windowNum = 0
+ }
+
+ /**
+ * Lifecycle function, called back when a service extension is started or recall.
+ */
+ onRequest(want, startId) {
+ globalThis.abilityWant = want
+ console.info(TAG + "ServiceExtensionAbility onRequest. start id is " + startId);
+ console.info(TAG + "want: " + JSON.stringify(want))
+
+ display.getDefaultDisplay().then(dis => {
+ let navigationBarRect = {
+ left: (dis.width - MAX_WIDTH)/2,
+ top: (dis.height - MAX_HEIGHT)/2,
+ width: MAX_WIDTH,
+ height: MAX_HEIGHT
+ }
+ this.createWindow("permissionDialog" + startId, window.WindowType.TYPE_DIALOG, navigationBarRect)
+ })
+ }
+
+ /**
+ * Lifecycle function, called back before a service extension is destroyed.
+ */
+ onDestroy() {
+ console.info(TAG + "ServiceExtensionAbility onDestroy.");
+ }
+
+ private async createWindow(name: string, windowType: number, rect) {
+ console.info(TAG + "create window")
+ try {
+ const win = await window.create(globalThis.extensionContext, name, windowType)
+ globalThis.extensionWin = win
+ await win.bindDialogTarget(globalThis.abilityWant.parameters['ohos.ability.params.token'].value, () => {
+ win.destroy()
+ globalThis.windowNum --
+ if(globalThis.windowNum == 0) this.context.terminateSelf()
+ })
+ await win.moveTo(rect.left, rect.top)
+ await win.resetSize(rect.width, rect.height)
+ await win.loadContent('pages/dialogPlus')
+ await win.setBackgroundColor('#00000000')
+ await win.show()
+ globalThis.windowNum ++
+ } catch {
+ console.info(TAG + "window create failed!")
+ }
+ }
+};
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/components/alphabeticalIndex.ets b/permissionmanager/src/main/ets/common/components/alphabeticalIndex.ets
new file mode 100644
index 0000000..a8270d1
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/components/alphabeticalIndex.ets
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Constants from '../utils/constant';
+
+@Component
+export struct alphabetIndexerComponent {
+ private value: string[] = [
+ '#',
+ 'A',
+ 'B',
+ 'C',
+ 'D',
+ 'E',
+ 'F',
+ 'G',
+ 'H',
+ 'I',
+ 'J',
+ 'K',
+ 'L',
+ 'M',
+ 'N',
+ 'O',
+ 'P',
+ 'Q',
+ 'R',
+ 'S',
+ 'T',
+ 'U',
+ 'V',
+ 'W',
+ 'X',
+ 'Y',
+ 'Z'
+ ]; // Array of alphabetically indexed names
+ @Link applicationItem: any; // application info array
+ @Link oldApplicationItem: any; // Original application information array
+ @State index: number = 0; // alphabetical index
+
+ build() {
+ AlphabetIndexer({ arrayValue: this.value, selected: this.index })
+ .selectedColor($r('app.color.selected_Color')) // selected color
+ .popupColor($r('app.color.popup_Color')) // popover color
+ .selectedBackgroundColor($r('app.color.selected_Background_Color')) // Check background color
+ .popupBackground($r('app.color.popup_Background_Color')) // popover background color
+ .usingPopup(true) // whether to show a popup
+ .selectedFont({ size: Constants.ALPHABETINDEXER_SELECTEDFONT_SIZE, weight: FontWeight.Bolder }) // selected style
+ .popupFont({ size: Constants.ALPHABETINDEXER_POPUPFONT_SIZE, weight: FontWeight.Bolder }) // Demo of the popup
+ .itemSize(Constants.ALPHABETINDEXER_ITEMSIZE) // size square of each item
+ .alignStyle(IndexerAlign.Left) // Align left
+ .onSelected((index: number) => {
+ this.index = index;
+ if (this.value[index] === '#' || this.value[index] === '☆') {
+ this.applicationItem = this.oldApplicationItem;
+ } else {
+ this.applicationItem = this.oldApplicationItem.filter((item) => {
+ return item.alphabeticalIndex.toUpperCase() === this.value[index];
+ })
+ }
+ })
+ .height(Constants.ALPHABETINDEXER_HEIGHT)
+ .width(Constants.ALPHABETINDEXER_WIDTH)
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/components/backBar.ets b/permissionmanager/src/main/ets/common/components/backBar.ets
new file mode 100644
index 0000000..8145d91
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/components/backBar.ets
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import router from '@system.router';
+import Resmgr from '@ohos.resourceManager'
+import Constants from '../utils/constant';
+
+@Component
+export struct backBar {
+ @Prop title: string; // return title name
+ @Prop recordable: boolean
+ @State record: string = ''
+
+ build() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Image($r('app.media.left'))
+ .objectFit(ImageFit.Contain)
+ .height(Constants.BACKBAR_IMAGE_HEIGHT)
+ .width(Constants.BACKBAR_IMAGE_WIDTH)
+ .margin({
+ top: Constants.BACKBAR_IMAGE_MARGIN_TOP,
+ left: Constants.BACKBAR_IMAGE_MARGIN_LEFT,
+ right: Constants.BACKBAR_IMAGE_MARGIN_RIGHT
+ })
+ .onClick(() => {
+ var length = router.getLength()
+ Number(length) == 1 ? globalThis.context.terminateSelf() : router.back()
+ })
+ Text(JSON.parse(this.title))
+ .fontColor($r('app.color.text_color'))
+ .fontSize(Constants.BACKBAR_TEXT_FONT_SIZE)
+ .flexGrow(Constants.BACKBAR_TEXT_FLEX_GROW)
+ .fontWeight(FontWeight.Bold)
+ .margin({ top: Constants.BACKBAR_TEXT_MARGIN_TOP })
+ if(this.recordable) {
+ Image($r("app.media.gongneng_dian"))
+ .objectFit(ImageFit.Contain)
+ .height(Constants.BACKBAR_IMAGE_HEIGHT)
+ .width(Constants.BACKBAR_IMAGE_WIDTH)
+ .margin({ top: Constants.BACKBAR_TEXT_MARGIN_TOP, right: Constants.BACKBAR_IMAGE_MARGIN_RIGHT })
+ .bindMenu([
+ {
+ value: this.record,
+ action: () => {
+ router.push({ uri: 'pages/permission-access-record' })
+ }
+ }
+ ])
+ }
+ }
+ }
+ .height(Constants.BACKBAR_HEIGHT)
+ .constraintSize({ minHeight: Constants.BACKBAR_MINHEIGHT })
+ .alignItems(HorizontalAlign.Start)
+ .backgroundColor($r('app.color.background_color'))
+ }
+
+ aboutToAppear() {
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ item.getString($r("app.string.permission_access_record").id, (err, val) => {
+ this.record = val
+ })
+ })
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/components/dialog.ets b/permissionmanager/src/main/ets/common/components/dialog.ets
new file mode 100644
index 0000000..8e86dd6
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/components/dialog.ets
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Constants from '../utils/constant';
+
+@CustomDialog
+export struct authorizeDialog {
+ controller: CustomDialogController;
+ cancel: () => void;
+ confirm: () => void;
+
+ build() {
+ Column() {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Center }) {
+ Text($r("app.string.Authorization_failed")).fontSize(Constants.DIALOG_TEXT_FONT_SIZE)
+ .margin({
+ top: Constants.DIALOG_TEXT_MARGIN_TOP
+ })
+ }
+ }
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.DIALOG_BORDER_RADIUS)
+ .height(Constants.DIALOG_HEIGHT)
+ .width(Constants.DIALOG_WIDTH)
+ }
+}
diff --git a/permissionmanager/src/main/ets/common/components/search.ets b/permissionmanager/src/main/ets/common/components/search.ets
new file mode 100644
index 0000000..72fa15f
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/components/search.ets
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Constants from '../utils/constant';
+
+@Component
+export struct textInput {
+ @Prop placeholder: string; // Prompt text when no input
+ @Link applicationItem: any; // application info array
+ @Link oldApplicationItem: any; // Original application information array
+ @Link searchResult: boolean; // search results
+
+ build() {
+ Column() {
+ Flex({ alignContent: FlexAlign.Start }) {
+ TextInput({ placeholder: this.placeholder })
+ .backgroundColor($r('app.color.default_background_color'))
+ .padding({ left: Constants.TEXTINPUT_PADDING_LEFT })
+ .type(InputType.Normal)
+ .border({ width: Constants.TEXTINPUT_BORDER_WIDTH, color: $r("app.color.label_color_20"), radius: Constants.TEXTINPUT_BORDER_RADIUS })
+ .placeholderColor(Color.Grey)
+ .placeholderFont({ size: Constants.TEXTINPUT_PLACEHOLDER_Font_SIZE, weight: FontWeight.Normal, family: "sans-serif", style: FontStyle.Normal })
+ .caretColor($r('app.color.secondary_font_color'))
+ .height(Constants.TEXTINPUT_HEIGHT)
+ .onChange((value: string) => {
+ if (value === '' || value === null) {
+ this.applicationItem = this.oldApplicationItem;
+ } else {
+ this.applicationItem = this.oldApplicationItem.filter((item) => {
+ return item.labelId.indexOf(value) > -1;
+ })
+ }
+ if (this.applicationItem.length) {
+ this.searchResult = true;
+ } else {
+ this.searchResult = false;
+ }
+ })
+ .onSubmit((enterKey) => {
+ })
+ .onEditChanged((isEditing) => {
+ })
+ Image($r('app.media.search'))
+ .objectFit(ImageFit.Contain)
+ .width(Constants.TEXTINPUT_IMAGE_WIDTH)
+ .height(Constants.TEXTINPUT_IMAGE_HEIGHT)
+ .position({ x: Constants.TEXTINPUT_IMAGE_MARGIN_LEFT, y: Constants.TEXTINPUT_IMAGE_MARGIN_TOP })
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/model/bundle.ets b/permissionmanager/src/main/ets/common/model/bundle.ets
new file mode 100644
index 0000000..d5f38e3
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/model/bundle.ets
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const BundleFlag = {
+ GET_BUNDLE_DEFAULT : 0x00000000,
+ GET_BUNDLE_WITH_ABILITIES : 0x00000001,
+ GET_ABILITY_INFO_WITH_PERMISSION : 0x00000002,
+ GET_ABILITY_INFO_WITH_APPLICATION : 0x00000004,
+ GET_APPLICATION_INFO_WITH_PERMISSION : 0x00000008,
+ GET_BUNDLE_WITH_REQUESTED_PERMISSION : 0x00000010,
+ GET_ALL_APPLICATION_INFO : 0xFFFF0000,
+ /**
+ * @since 8
+ */
+ GET_ABILITY_INFO_WITH_METADATA : 0x00000020,
+ /**
+ * @since 8
+ */
+ GET_APPLICATION_INFO_WITH_METADATA : 0x00000040,
+ /**
+ * @since 8
+ */
+ GET_ABILITY_INFO_SYSTEMAPP_ONLY : 0x00000080
+}
+
+export const USER_ID: number = 100
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/model/permissionGroup.ets b/permissionmanager/src/main/ets/common/model/permissionGroup.ets
new file mode 100644
index 0000000..d389c6b
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/model/permissionGroup.ets
@@ -0,0 +1,512 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const permissionGroups: any[] = [
+ {
+ "permissionName": "ohos.permission.LOCATION_IN_BACKGROUND",
+ "groupName": "LOCATION",
+ "label": "后台定位权限",
+ "description": "允许应用在后台运行时获取位置信息。",
+ "groupId": 0
+ },
+ {
+ "permissionName": "ohos.permission.LOCATION",
+ "groupName": "LOCATION",
+ "label": "前台定位权限",
+ "description": "允许应用在前台运行时获取位置信息。",
+ "groupId": 0
+ },
+ {
+ "permissionName": "ohos.permission.CAMERA",
+ "groupName": "CAMERA",
+ "label": "拍摄照片和录制视频",
+ "description": "允许应用拍摄照片和视频。",
+ "groupId": 1
+ },
+ {
+ "permissionName": "ohos.permission.MICROPHONE",
+ "groupName": "MICROPHONE",
+ "label": "录制音频",
+ "description": "允许应用打开或关闭录音通路。",
+ "groupId": 2
+ },
+ {
+ "permissionName": "ohos.permission.ANSWER_CALL",
+ "groupName": "PHONE",
+ "label": "接听电话",
+ "description": "允许应用接听电话。",
+ "groupId": 3
+ },
+ {
+ "permissionName": "ohos.permission.MANAGE_VOICEMAIL",
+ "groupName": "PHONE",
+ "label": "语音信箱",
+ "description": "允许应用管理语音信箱。",
+ "groupId": 3
+ },
+ {
+ "permissionName": "ohos.permission.READ_CELL_MESSAGES",
+ "groupName": "SMS",
+ "label": "读取小区广播",
+ "description": "允许应用读取设备接收的小区广播信息。",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.READ_MESSAGES",
+ "groupName": "SMS",
+ "label": "读取短彩信",
+ "description": "允许应用读取设备接收的短彩信信息。",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.RECEIVE_MMS",
+ "groupName": "SMS",
+ "label": "接收彩信",
+ "description": "允许应用接收彩信。",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.RECEIVE_SMS",
+ "groupName": "SMS",
+ "label": "接收短信",
+ "description": "允许应用接收短信。",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.RECEIVE_WAP_MESSAGES",
+ "groupName": "SMS",
+ "label": "接收WAP消息",
+ "description": "允许应用接收和处理WAP消息。",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.SEND_MESSAGES",
+ "groupName": "SMS",
+ "label": "发送短彩信",
+ "description": "允许应用发送短彩信",
+ "groupId": 4
+ },
+ {
+ "permissionName": "ohos.permission.READ_CONTACTS",
+ "groupName": "CONTACTS",
+ "label": "读取通讯录",
+ "description": "允许应用读取设备上存储的联系人信息。",
+ "groupId": 5
+ },
+ {
+ "permissionName": "ohos.permission.WRITE_CONTACTS",
+ "groupName": "CONTACTS",
+ "label": "新建/修改/删除通讯录",
+ "description": "允许应用新建/修改/删除设备上存储的联系人信息。",
+ "groupId": 5
+ },
+ {
+ "permissionName": "ohos.permission.READ_CALL_LOG",
+ "groupName": "CALL_LOG",
+ "label": "读取通话记录",
+ "description": "允许应用读取设备上的通话记录信息。",
+ "groupId": 6
+ },
+ {
+ "permissionName": "ohos.permission.WRITE_CALL_LOG",
+ "groupName": "CALL_LOG",
+ "label": "新建/修改/删除通话记录",
+ "description": "允许新建/修改/删除设备上的通话记录信息。",
+ "groupId": 6
+ },
+ {
+ "permissionName": "ohos.permission.MEDIA_LOCATION",
+ "groupName": "MEDIA",
+ "label": "允许应用访问拍摄位置",
+ "description": "应用访问用户媒体文件中的拍摄位置信息如经纬度信息。",
+ "groupId": 7
+ },
+ {
+ "permissionName": "ohos.permission.READ_MEDIA",
+ "groupName": "MEDIA",
+ "label": "允许应用读取媒体文件",
+ "description": "允许应用访问户媒体文件,如视频、音频、图片等。",
+ "groupId": 7
+ },
+ {
+ "permissionName": "ohos.permission.WRITE_MEDIA",
+ "groupName": "MEDIA",
+ "label": "允许应用读写媒体文件",
+ "description": "允许应用读写户媒体文件,如视频、音频、图片等。",
+ "groupId": 7
+ },
+ {
+ "permissionName": "ohos.permission.READ_CALENDAR",
+ "groupName": "CALENDAR",
+ "label": "读取日历",
+ "description": "允许应用读取日历。",
+ "groupId": 8
+ },
+ {
+ "permissionName": "ohos.permission.WRITE_CALENDAR",
+ "groupName": "CALENDAR",
+ "label": "新建/修改/删除日历",
+ "description": "允许应用新建/修改/删除日历。",
+ "groupId": 8
+ },
+ {
+ "permissionName": "ohos.permission.ACTIVITY_MOTION",
+ "groupName": "SPORT",
+ "label": "读取用户的运动状态",
+ "description": "允许应用程序读取用户的运动状态。",
+ "groupId": 9
+ },
+ {
+ "permissionName": "ohos.permission.READ_HEALTH_DATA",
+ "groupName": "HEALTH",
+ "label": "读取用户的健康数据",
+ "description": "允许应用程序读取用户的健康数据。",
+ "groupId": 10
+ },
+ {
+ "permissionName": "ohos.permission.DISTRIBUTED_DATASYNC",
+ "groupName": "OTHER",
+ "icon": $r("app.media.ic_multi_device_vector"),
+ "text": "使用多设备协同?",
+ "label": "多设备协同",
+ "description": "发现并访问其他设备。",
+ "groupId": 11
+ }
+]
+
+export const groups: any[] = [
+ {
+ "name": "LOCATION",
+ "groupName": "位置信息",
+ "icon": $r('app.media.ic_public_gps'),
+ "description": "",
+ "label": "访问位置信息?",
+ "permissions": [
+ "ohos.permission.LOCATION_IN_BACKGROUND",
+ "ohos.permission.LOCATION"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "CAMERA",
+ "groupName": "相机",
+ "icon": $r('app.media.ic_public_camera'),
+ "label": "使用相机?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.CAMERA"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "MICROPHONE",
+ "groupName": "麦克风",
+ "icon": $r('app.media.ic_public_voice'),
+ "label": "使用麦克风?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.MICROPHONE"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "PHONE",
+ "groupName": "电话",
+ "icon": $r('app.media.ic_public_phone'),
+ "label": "使用拨打电话?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.ANSWER_CALL",
+ "ohos.permission.MANAGE_VOICEMAIL"
+ ],
+ "isShow":false
+ },
+ {
+ "name": "SMS",
+ "groupName": "信息",
+ "icon": $r('app.media.ic_public_message'),
+ "label": "访问信息?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.READ_CELL_MESSAGES",
+ "ohos.permission.READ_MESSAGES",
+ "ohos.permission.RECEIVE_MMS",
+ "ohos.permission.RECEIVE_SMS",
+ "ohos.permission.RECEIVE_WAP_MESSAGES",
+ "ohos.permission.SEND_MESSAGES"
+ ],
+ "isShow":false
+ },
+ {
+ "name": "CONTACTS",
+ "groupName": "通讯录",
+ "icon": $r('app.media.ic_public_contacts_group'),
+ "label": "访问通讯录?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.READ_CONTACTS",
+ "ohos.permission.WRITE_CONTACTS"
+ ],
+ "isShow":false
+ },
+ {
+ "name": "CALL_LOG",
+ "groupName": "通话记录",
+ "icon": $r('app.media.ic_call_logs'),
+ "label": "访问通话记录?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.READ_CALL_LOG",
+ "ohos.permission.WRITE_CALL_LOG"
+ ],
+ "isShow":false
+ },
+ {
+ "name": "MEDIA",
+ "groupName": "媒体和文件",
+ "icon": $r('app.media.ic_public_folder'),
+ "description": "",
+ "label": "访问媒体和文件?",
+ "permissions": [
+ "ohos.permission.MEDIA_LOCATION",
+ "ohos.permission.READ_MEDIA",
+ "ohos.permission.WRITE_MEDIA"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "CALENDAR",
+ "groupName": "日历",
+ "icon": $r('app.media.ic_public_calendar'),
+ "label": "访问日历?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.READ_CALENDAR",
+ "ohos.permission.WRITE_CALENDAR"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "SPORT",
+ "groupName": "健身运动",
+ "icon": $r('app.media.ic_sport'),
+ "label": "访问健身运动?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.ACTIVITY_MOTION"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "HEALTH",
+ "groupName": "身体传感器",
+ "icon": $r('app.media.ic_ssensor'),
+ "label": "使用身体传感器?",
+ "description": "",
+ "permissions": [
+ "ohos.permission.READ_HEALTH_DATA"
+ ],
+ "isShow":true
+ },
+ {
+ "name": "OTHER",
+ "groupName": "其他权限",
+ "icon": $r('app.media.ic_more'),
+ "description": "",
+ "permissions": [
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+ ],
+ "isShow":false
+ }
+];
+
+export const permissionGroupPermissions: object = {
+ "LOCATION": [
+ "ohos.permission.LOCATION_IN_BACKGROUND",
+ "ohos.permission.LOCATION"
+ ],
+ "CAMERA": [
+ "ohos.permission.CAMERA"
+ ],
+ "MICROPHONE": [
+ "ohos.permission.MICROPHONE"
+ ],
+ "PHONE": [
+ "ohos.permission.ANSWER_CALL",
+ "ohos.permission.MANAGE_VOICEMAIL"
+ ],
+ "SMS": [
+ "ohos.permission.READ_CELL_MESSAGES",
+ "ohos.permission.READ_MESSAGES",
+ "ohos.permission.RECEIVE_MMS",
+ "ohos.permission.RECEIVE_SMS",
+ "ohos.permission.RECEIVE_WAP_MESSAGES",
+ "ohos.permission.SEND_MESSAGES"
+ ],
+ "CONTACTS": [
+ "ohos.permission.READ_CONTACTS",
+ "ohos.permission.WRITE_CONTACTS"
+ ],
+ "CALL_LOG": [
+ "ohos.permission.READ_CALL_LOG",
+ "ohos.permission.WRITE_CALL_LOG"
+ ],
+ "MEDIA": [
+ "ohos.permission.MEDIA_LOCATION",
+ "ohos.permission.READ_MEDIA",
+ "ohos.permission.WRITE_MEDIA"
+ ],
+ "CALENDAR": [
+ "ohos.permission.READ_CALENDAR",
+ "ohos.permission.WRITE_CALENDAR"
+ ],
+ "SPORT": [
+ "ohos.permission.ACTIVITY_MOTION"
+ ],
+ "HEALTH": [
+ "ohos.permission.READ_HEALTH_DATA"
+ ],
+ "OTHER": [
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+ ]
+};
+
+
+export const userGrantPermissions: string[] = [
+ "ohos.permission.LOCATION_IN_BACKGROUND",
+ "ohos.permission.LOCATION",
+ "ohos.permission.CAMERA",
+ "ohos.permission.MICROPHONE",
+ "ohos.permission.ANSWER_CALL",
+ "ohos.permission.MANAGE_VOICEMAIL",
+ "ohos.permission.READ_CELL_MESSAGES",
+ "ohos.permission.READ_MESSAGES",
+ "ohos.permission.RECEIVE_MMS",
+ "ohos.permission.RECEIVE_SMS",
+ "ohos.permission.RECEIVE_WAP_MESSAGES",
+ "ohos.permission.SEND_MESSAGES",
+ "ohos.permission.READ_CONTACTS",
+ "ohos.permission.WRITE_CONTACTS",
+ "ohos.permission.READ_CALL_LOG",
+ "ohos.permission.WRITE_CALL_LOG",
+ "ohos.permission.MEDIA_LOCATION",
+ "ohos.permission.READ_MEDIA",
+ "ohos.permission.WRITE_MEDIA",
+ "ohos.permission.READ_CALENDAR",
+ "ohos.permission.WRITE_CALENDAR",
+ "ohos.permission.ACTIVITY_MOTION",
+ "ohos.permission.READ_HEALTH_DATA",
+ "ohos.permission.DISTRIBUTED_DATASYNC"
+];
+
+export const permissionDescriptions: object = {
+ "位置信息": "允许应用在后台运行时获取位置信息。" ,
+ "相机": "允许应用拍摄照片和视频。" ,
+ "麦克风": "允许应用打开或关闭录音通路。" ,
+ "电话": "允许应用接听电话。" ,
+ "信息": "允许应用发送短彩信。" ,
+ "通讯录": "允许应用新建/修改/删除设备上存储的联系人信息。" ,
+ "通话记录": "允许新建/修改/删除设备上的通话记录信息。" ,
+ "媒体和文件": "允许应用访问户媒体文件,如视频、音频、图片等。" ,
+ "日历": "允许应用新建/修改/删除日历。" ,
+ "健身运动": "允许应用程序读取用户的运动状态。" ,
+ "身体传感器": "允许应用程序读取用户的健康数据。" ,
+ "其他权限": "允许应用与远程设备交换用户数据(如图片、音乐、视频、及应用数据等)。"
+};
+
+export const permissionPermissionGroup: object = {
+ "ohos.permission.LOCATION_IN_BACKGROUND": "LOCATION",
+ "ohos.permission.LOCATION": "LOCATION",
+ "ohos.permission.CAMERA": "CAMERA",
+ "ohos.permission.MICROPHONE": "MICROPHONE",
+ "ohos.permission.ANSWER_CALL": "PHONE",
+ "ohos.permission.MANAGE_VOICEMAIL": "PHONE",
+ "ohos.permission.READ_CELL_MESSAGES": "SMS",
+ "ohos.permission.READ_MESSAGES": "SMS",
+ "ohos.permission.RECEIVE_MMS": "SMS",
+ "ohos.permission.RECEIVE_SMS": "SMS",
+ "ohos.permission.RECEIVE_WAP_MESSAGES": "SMS",
+ "ohos.permission.SEND_MESSAGES": "SMS",
+ "ohos.permission.READ_CONTACTS": "CONTACTS",
+ "ohos.permission.WRITE_CONTACTS": "CONTACTS",
+ "ohos.permission.READ_CALL_LOG": "CALL_LOG",
+ "ohos.permission.WRITE_CALL_LOG": "CALL_LOG",
+ "ohos.permission.MEDIA_LOCATION": "MEDIA",
+ "ohos.permission.READ_MEDIA": "MEDIA",
+ "ohos.permission.WRITE_MEDIA": "MEDIA",
+ "ohos.permission.READ_CALENDAR": "CALENDAR",
+ "ohos.permission.WRITE_CALENDAR": "CALENDAR",
+ "ohos.permission.ACTIVITY_MOTION": "SPORT",
+ "ohos.permission.READ_HEALTH_DATA": "HEALTH",
+ "ohos.permission.DISTRIBUTED_DATASYNC": "OTHER"
+};
+
+export const permissionGroupIds: object = {
+ "ohos.permission.LOCATION_IN_BACKGROUND": "0",
+ "ohos.permission.LOCATION": "0",
+ "ohos.permission.CAMERA": "1",
+ "ohos.permission.MICROPHONE": "2",
+ "ohos.permission.ANSWER_CALL": "3",
+ "ohos.permission.MANAGE_VOICEMAIL": "3",
+ "ohos.permission.READ_CELL_MESSAGES": "4",
+ "ohos.permission.READ_MESSAGES": "4",
+ "ohos.permission.RECEIVE_MMS": "4",
+ "ohos.permission.RECEIVE_SMS": "4",
+ "ohos.permission.RECEIVE_WAP_MESSAGES": "4",
+ "ohos.permission.SEND_MESSAGES": "4",
+ "ohos.permission.READ_CONTACTS": "5",
+ "ohos.permission.WRITE_CONTACTS": "5",
+ "ohos.permission.READ_CALL_LOG": "6",
+ "ohos.permission.WRITE_CALL_LOG": "6",
+ "ohos.permission.MEDIA_LOCATION": "7",
+ "ohos.permission.READ_MEDIA": "7",
+ "ohos.permission.WRITE_MEDIA": "7",
+ "ohos.permission.READ_CALENDAR": "8",
+ "ohos.permission.WRITE_CALENDAR": "8",
+ "ohos.permission.ACTIVITY_MOTION": "9",
+ "ohos.permission.READ_HEALTH_DATA": "10",
+ "ohos.permission.DISTRIBUTED_DATASYNC": "11"
+};
+
+export const orderGroup: string[] = [
+ "位置信息",
+ "相机",
+ "麦克风",
+ "电话",
+ "信息",
+ "通讯录",
+ "通话记录",
+ "媒体和文件",
+ "日历",
+ "健身运动",
+ "身体传感器",
+ "其他权限"
+];
+
+export const otherPermissionsLabel: object = {
+ "ohos.permission.DISTRIBUTED_DATASYNC": "多设备协同"
+};
+
+export const noNeedDisplayApp: string[] = [
+ "com.ohos.launcher"
+]
+
+export const showSubpermissionsGrop: string[] = [
+ "电话",
+ "日历",
+ "信息",
+ "通讯录",
+ "通话记录"
+];
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/utils/constant.ets b/permissionmanager/src/main/ets/common/utils/constant.ets
new file mode 100644
index 0000000..1bfa231
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/utils/constant.ets
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Constants {
+ // alphabetIndexer
+ static ALPHABETINDEXER_SELECTEDFONT_SIZE = 12;
+ static ALPHABETINDEXER_POPUPFONT_SIZE = 30;
+ static ALPHABETINDEXER_ITEMSIZE = 16;
+ static ALPHABETINDEXER_HEIGHT = 448;
+ static ALPHABETINDEXER_WIDTH = 36;
+
+ // backBar
+ static BACKBAR_HEIGHT = 56;
+ static BACKBAR_MINHEIGHT = 56;
+
+ // image of backBar
+ static BACKBAR_IMAGE_HEIGHT = 24;
+ static BACKBAR_IMAGE_WIDTH = 24;
+ static BACKBAR_IMAGE_MARGIN_TOP = 17;
+ static BACKBAR_IMAGE_MARGIN_LEFT = 12;
+ static BACKBAR_IMAGE_MARGIN_RIGHT = 15;
+
+ // text of backBar
+ static BACKBAR_TEXT_FONT_SIZE = 20;
+ static BACKBAR_TEXT_FLEX_GROW = 1;
+ static BACKBAR_TEXT_MARGIN_TOP = 17;
+
+ // dialog
+ static DIALOG_BORDER_RADIUS = 24;
+ static DIALOG_HEIGHT = 70;
+ static DIALOG_WIDTH = 336;
+
+ // text of dialog
+ static DIALOG_TEXT_FONT_SIZE = 20;
+ static DIALOG_TEXT_MARGIN_TOP = 25;
+
+ // search textInput
+ static TEXTINPUT_PADDING_LEFT = 36;
+ static TEXTINPUT_BORDER_RADIUS = 20;
+ static TEXTINPUT_BORDER_WIDTH = 1.5;
+ static TEXTINPUT_PLACEHOLDER_Font_SIZE = 16;
+ static TEXTINPUT_HEIGHT = 40;
+ static TEXTINPUT_IMAGE_WIDTH = 16;
+ static TEXTINPUT_IMAGE_HEIGHT = 16;
+ static TEXTINPUT_IMAGE_MARGIN_LEFT = 12;
+ static TEXTINPUT_IMAGE_MARGIN_TOP = 12;
+
+ // grid useSizeType
+ static GRID_MARGIN = '0vp';
+ static GUTTER = 0;
+ static LEFT_XS_SPAN = 0;
+ static LEFT_XS_OFFSET = 0;
+ static LEFT_SM_SPAN = 0;
+ static LEFT_SM_OFFSET = 0;
+ static LEFT_MD_SPAN = 0;
+ static LEFT_MD_OFFSET = 0;
+ static LEFT_LG_SPAN = 2;
+ static LEFT_LG_OFFSET = 0;
+ static MIDDLE_XS_SPAN = 2;
+ static MIDDLE_XS_OFFSET = 0;
+ static MIDDLE_SM_SPAN = 4;
+ static MIDDLE_SM_OFFSET = 0;
+ static MIDDLE_MD_SPAN = 8;
+ static MIDDLE_MD_OFFSET = 0;
+ static MIDDLE_LG_SPAN = 8;
+ static MIDDLE_LG_OFFSET = 2;
+ static RIGHT_XS_SPAN = 0;
+ static RIGHT_XS_OFFSET = 2;
+ static RIGHT_SM_SPAN = 0;
+ static RIGHT_SM_OFFSET = 4;
+ static RIGHT_MD_SPAN = 0;
+ static RIGHT_MD_OFFSET = 8;
+ static RIGHT_LG_SPAN = 2;
+ static RIGHT_LG_OFFSET = 10;
+
+ // 100% width,height
+ static FULL_WIDTH = '100%';
+ static FULL_HEIGHT = '100%';
+
+ // public property style
+ static PERMISSION = 1;
+ static APPLICATION = 0;
+ static LAYOUT_WEIGHT = 1;
+ static FLEX_GROW = 1;
+ static TEXT_DECORATION_HEIGHT = 1;
+ static TEXT_MIDDLE_FONT_SIZE = 16;
+ static TEXT_SMAL_FONT_SIZE = 14;
+ static TEXT_SMALLER_FONT_SIZE = 12;
+ static TEXT_LINE_HEIGHT = 22;
+ static TEXT_SMALL_LINE_HEIGHT = 19;
+ static CONSTRAINTSIZE_MINHEIGHT = 48;
+ static LISTITEM_ROW_HEIGHT = 48;
+ static LISTITEM_PADDING_LEFT = 24;
+ static LIST_PADDING_LEFT = 12
+ static LISTITEM_PADDING_RIGHT = 24;
+ static LISTITEM_PADDING_LEFT_RECORD = 32;
+ static LISTITEM_MARGIN_BOTTOM = 12;
+ static LISTITEM_MARGIN_BOTTOM_PERMISSION = 14;
+ static LISTITEM_MARGIN_BOTTOM_APPLICATION = 10;
+ static LISTITEM_HEIGHT_PERMISSION = 64;
+ static LISTITEM_HEIGHT_APPLICATION = 72;
+ static IMAGE_HEIGHT = 24;
+ static IMAGE_WIDTH = 12;
+ static IMAGE_HEIGHT_RECORD = 12;
+ static IMAGE_WIDTH_RECORD = 24;
+ static IMAGE_HEIGHT_RECORD_APPLICATION = 16;
+ static IMAGE_WIDTH_RECORD_APPLICATION = 16;
+ static BORDER_RADIUS = 24;
+ static TITLE_MARGIN_BOTTOM = 16;
+ static SUBTITLE_MIN_HEIGHT = 48;
+ static SUBTITLE_LINE_HEIGHT = 24;
+ static SUBTITLE_PADDING_TOP = 16;
+ static SUBTITLE_PADDING_BOTTOM = 8;
+ static TAB_HEIGHT = 56;
+ static TAB_DECORATION_HEIGHT = 2;
+ static TAB_DECORATION_POSITION_Y = 46;
+ static DEFAULT_PADDING_START = 12;
+ static DEFAULT_PADDING_END = 12;
+
+ // application-secondary, authority-secondary
+ static FLEX_MARGIN_TOP = 8;
+ static FLEX_MARGIN_BOTTOM = 8;
+ static LIST_PADDING_TOP = 4;
+ static LIST_PADDING_BOTTOM = 4;
+ static LIST_MARGIN_BOTTOM = 12;
+ static ROW_MARGIN_TOP = 9;
+ static SECONDARY_TEXT_MARGIN_TOP = 19.5;
+ static SECONDARY_TEXT_MARGIN_LEFT = 24;
+ static SECONDARY_LIST_PADDING_LEFT = 12;
+ static SECONDARY_LIST_PADDING_RIGHT = 12;
+
+ // application-tertiary
+ static TERTIARY_IMAGE_WIDTH = 64;
+ static TERTIARY_IMAGE_HEIGHT = 64;
+ static TERTIARY_IMAGE_MARGIN_LEFT = 12;
+ static TERTIARY_IMAGE_MARGIN_RIGHT = 12;
+ static TERTIARY_LABEL_MARGIN_BOTTOM = 2;
+ static TERTIARY_MARGIN_LEFT = 12;
+ static TERTIARY_TEXT_MARGIN_LEFT = 24;
+ static TERTIARY_HALF_WIDTH = '50%';
+ static TERTIARY_ROW_MARGIN_TOP = 24;
+ static TERTIARY_PERMISSION_ROW_MARGIN_TOP = 12;
+ static TERTIARY_RADIO_IMAGE_WIDTH = 24;
+ static TERTIARY_RADIO_IMAGE_HEIGHT = 24;
+ static TERTIARY_RADIO_IMAGE_MARGIN_TOP = 4;
+ static TERTIARY_LISTITEM_PADDING_LEFT = 24;
+ static TERTIARY_LISTITEM_PADDING_RIGHT = 24;
+ static TERTIARY_LISTITEM_MARGIN_TOP = 1;
+ static TERTIARY_LIST_PADDING_LEFT = 12;
+ static TERTIARY_LIST_PADDING_RIGHT = 12;
+ static TERTIARY_LIST_PADDING_TOP = 4;
+ static TERTIARY_LIST_PADDING_BOTTOM = 4;
+
+ // authority-tertiary
+ static AUTHORITY_IMAGE_WIDTH = 40;
+ static AUTHORITY_IMAGE_HEIGHT = 40;
+ static AUTHORITY_IMAGE_MARGIN_RIGHT = 16;
+ static AUTHORITY_TOGGLE_WIDTH = 36;
+ static AUTHORITY_TOGGLE_HEIGHT = 20;
+ static AUTHORITY_ROW_HEIGHT = 72;
+ static AUTHORITY_CONSTRAINTSIZE_MINHEIGHT = 72;
+ static AUTHORITY_LISTITEM_PADDING_LEFT = 12;
+ static AUTHORITY_LISTITEM_PADDING_RIGHT = 12;
+ static AUTHORITY_TEXTINPUT_PADDING_LEFT = 12;
+ static AUTHORITY_TEXTINPUT_PADDING_RIGHT = 24;
+ static AUTHORITY_TEXT_MARGIN_TOP = 24;
+ static AUTHORITY_TEXT_MARGIN_LEFT = 0;
+ static AUTHORITY_ROW_MARGIN_TOP = 24;
+ static NORECORD_IMAGE_WIDTH = 120;
+ static NORECORD_IMAGE_HEIGHT = 120;
+ static NORECORD_IMAGE_MARGIN_LEFT = 40;
+ static SEARCHNORESULT_IMAGE_WIDTH = 200;
+ static SEARCHNORESULT_IMAGE_HEIGHT = 200;
+ static AUTHORITY_COLUMN_HEIGHT = '95%';
+ static AUTHORITY_ALPHABETINDEX_WIDTH = 24;
+ static AUTHORITY_ALPHABETINDEX_PADDING_TOP = 16;
+ static AUTHORITY_TEXT_DECORATION_WIDTH = '86%';
+ static AUTHORITY_TEXT_DECORATION_MARGIN_LEFT = 53;
+
+ // authority-management
+ static MANAGEMENT_IMAGE_WIDTH = 24;
+ static MANAGEMENT_IMAGE_HEIGHT = 24;
+ static MANAGEMENT_IMAGE_MARGIN_RIGHT = 16;
+ static MANAGEMENT_IMAGE_MARGIN_RIGHT_RECORD = 24;
+ static MANAGEMENT_IMAGE_MARGIN_LEFT = 8;
+ static MANAGEMENT_ROW_HEIGHT = 56;
+ static MANAGEMENT_TEXT_DECORATION_WIDTH = '95%';
+ static MANAGEMENT_TEXT_DECORATION_MARGIN_LEFT = 40;
+ static MANAGEMENT_LODING_IMAGE_WIDTH = 48;
+ static MANAGEMENT_LODING_IMAGE_HEIGHT = 48;
+ static MANAGEMENT_LODING_ROW_HEIGHT = '90%';
+ static MANAGEMENT_ROW_PADDING_LEFT = 12;
+ static MANAGEMENT_ROW_PADDING_RIGHT = 12;
+ static MANAGEMENT_ROW_PADDING_TOP = 8;
+ static MANAGEMENT_ROW_MARGIN_TOP = 12;
+ static MANAGEMENT_TRANSPARENCY = 0.8;
+ static APPLICATION_IMAGE_WIDTH = 40;
+ static APPLICATION_IMAGE_HEIGHT = 40;
+ static APPLICATION_IMAGE_MARGIN_RIGHT = 16;
+ static APPLICATION_TEXT_MARGIN_RIGHT = 4;
+ static APPLICATION_LIST_PADDING_LEFT = 12;
+ static APPLICATION_LIST_PADDING_RIGHT = 12;
+ static APPLICATION_LIST_MARGIN_BOTTOM = 50;
+ static APPLICATION_LISTITEM_PADDING_LEFT = 12;
+ static APPLICATION_LISTITEM_PADDING_RIGHT = 12;
+ static APPLICATION_TEXTINPUT_PADDING_LEFT = 12;
+ static APPLICATION_TEXTINPUT_PADDING_TOP = 8;
+ static APPLICATION_TEXTINPUT_PADDING_RIGHT = 24;
+ static APPLICATION_COLUMN_HEIGHT = '93%';
+ static APPLICATION_ALPHABETINDEX_MARGIN_TOP = 12;
+ static APPLICATION_ALPHABETINDEX_WIDTH = 24;
+ static APPLICATION_TEXT_DECORATION_WIDTH = '90%';
+ static APPLICATION_TEXT_DECORATION_MARGIN_LEFT = 56;
+ static LOADING_WIDTH = 100;
+
+ // slice
+ static SLICE_START = 0;
+ static SLICE_END = -1;
+ static SLICE_START_INDEX = 0;
+ static SLICE_END_INDEX = 1;
+
+ //group number
+ static FIXED_GROUP = 1;
+ static CHANGE_GROUP = 2;
+ static OTHER_GROUP = 3;
+
+ // tabBar
+ static BAR_WIDTH = 285;
+
+ // setTimeout
+ static DELAY_TIME = 1000;
+ static DELAY_TIME_MAX = 2000;
+
+ // radio
+ static RADIO_ALLOW_NAME = '允许';
+ static RADIO_ALLOW_INDEX = 0;
+ static RADIO_ALLOW_GROUP_NAME = 'radio';
+ static RADIO_BAN_NAME = '禁止';
+ static RADIO_BAN_INDEX = 1;
+ static RADIO_BAN_GROUP_NAME = 'radio';
+
+ //shape
+ static SHAPE_DIA = 24;
+ static SHAPE_BAN_DIA = 23;
+ static SHAPE_BIG_DIA = 48;
+ static SHAPE_OFFSET_X = -24;
+ static SHAPE_BAN_OFFSET = .5;
+ static SHAPE_ALLOW_DIA = 16;
+ static SHAPE_ALLOW_OFFSET = 4;
+ static SHAPE_ZINDEX = 10;
+
+ // utils
+ static CHAR_CODE = 0;
+ static UNI_MAX = 40869;
+ static UNI_MIN = 19968;
+
+ static PARMETER_BUNDLE_FLAG = 16;
+ static USERID = 100;
+
+ static PERMISSION_INDEX = 0;
+
+ static PERMISSION_NUM = 0;
+
+ static PERMISSION_FLAG = 2;
+ static API_VERSION_SUPPORT_STAGE = 9;
+
+ static PRE_AUTHORIZATION_NOT_MODIFIED = 4;
+
+ static BUNDLE_NAME = 'com.ohos.permissionmanager'
+
+ static START_SUBSCRIPT = 0
+ static END_SUBSCRIPT = 500
+
+ static RECORD_PADDING_BOTTOM = '20%'
+
+
+
+
+ ////////////////////////////////////////////
+ // icon of dialog
+ static DIALOG_ICON_WIDTH = 24;
+ static DIALOG_ICON_HEIGHT = 24;
+ static DIALOG_ICON_MARGIN_TOP = 23;
+
+ // label text of dialog
+ static DIALOG_LABEL_FONT_SIZE = 10;
+ static DIALOG_LABEL_MARGIN_TOP = 2;
+ static DIALOG_LABEL_LINE_HEIGHT = 14;
+
+ // request text of dialog
+ static DIALOG_REQ_FONT_SIZE = 16;
+ static DIALOG_REQ_MARGIN_TOP = 16;
+ static DIALOG_REQ_MARGIN_LEFT = 24;
+ static DIALOG_REQ_LINE_HEIGHT = 22;
+
+ // description text of dialog
+ static DIALOG_DESP_FONT_SIZE = 14;
+ static DIALOG_DESP_MARGIN_TOP = 2;
+ static DIALOG_DESP_MARGIN_LEFT = 24;
+ static DIALOG_DESP_MARGIN_RIGHT = 24;
+ static DIALOG_DESP_MARGIN_BOTTOM = 8;
+ static DIALOG_DESP_LINE_HEIGHT = 19;
+
+ static BUTTON_FONT_SIZE = 16;
+ static BUTTON_DIVIDER_FONT_SIZE = 24;
+ static BUTTON_MARGIN_TOP = 8;
+ static BUTTON_MARGIN_BOTTOM = 16;
+ static BUTTON_MARGIN_LEFT = 16;
+ static BUTTON_MARGIN_RIGHT = 16;
+ static BUTTON_HEIGHT = 40;
+ static BUTTON_WIDTH = 177;
+
+ static DIALOG_PRIVACY_BORDER_RADIUS = 32;
+ static DIALOG_PRIVACY_WIDTH = 395;
+ static DIALOG_PADDING_BOTTOM = 16;
+
+ // initial check status
+ static INIT_NEED_TO_WAIT = 0
+ static INIT_NEED_TO_VERIFY = 1
+ static INIT_NEED_TO_TERMINATED = 2
+ static INIT_NEED_TO_REFRESH = 3
+
+ static RESULT_SUCCESS = 1
+ static RESULT_FAILURE = 0
+ static RESULT_CODE = 0
+
+ //
+ static SETTING_OPER = -1
+ static PASS_OPER = 0
+ static DYNAMIC_OPER = 1
+ static INVALID_OPER = 2
+
+ //
+ static INITIAL_INDEX = 10
+ static ACCESS_TOKEN = 'ohos.security.accesstoken.tokencallback'
+
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/common/utils/utils.ets b/permissionmanager/src/main/ets/common/utils/utils.ets
new file mode 100644
index 0000000..8caae47
--- /dev/null
+++ b/permissionmanager/src/main/ets/common/utils/utils.ets
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Resmgr from '@ohos.resourceManager';
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+
+import { permissionGroups, groups } from "../model/permissionGroup";
+import Constants from '../utils/constant';
+
+/**
+ * Get app name resource
+ * @param {Number} labelId app name id
+ * @param {String} bundleName Package names
+ */
+export function getAppLabel(labelId, bundleName) {
+ return new Promise((resolve) => {
+ Resmgr.getResourceManager(globalThis.context, bundleName).then(item => {
+ item.getString(labelId, (error, value) => {
+ resolve(value);
+ })
+ }).catch(error => {
+ console.error('Resmgr.getResourceManager failed. Cause: ' + JSON.stringify(error));
+ })
+ })
+}
+
+/**
+ * Get app icon resources
+ * @param {Number} iconId app icon id
+ * @param {String} bundleName Package names
+ */
+export function getAppIcon(iconId, bundleName) {
+ return new Promise((resolve) => {
+ Resmgr.getResourceManager(globalThis.context, bundleName).then(item => {
+ item.getMediaBase64(iconId, (error, value) => {
+ resolve(value);
+ })
+ }).catch(error => {
+ console.error('Resmgr.getResourceManager failed. Cause: ' + JSON.stringify(error));
+ })
+ })
+}
+
+/**
+ * verify permission
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ */
+export function verifyAccessToken(accessTokenId, permission) {
+ return new Promise((resolve) => {
+ abilityAccessCtrl.createAtManager().verifyAccessToken(accessTokenId, permission).then((res) => {
+ return resolve(res);
+ })
+ .catch((error) => {
+ console.error('verifyAccessToken failed. Cause: ' + JSON.stringify(error));
+ })
+ })
+}
+
+/**
+* Let arkui detect changes in array index assignments。
+*/
+export function changeIndexValue(stateList, changeItem){
+ // copy array
+ let result = stateList.slice(0);
+ for (let i = 0 ; i < changeItem.length; i++) {
+ let item = changeItem[i];
+ if (!Array.isArray(item)) {
+ throw new Error("error");
+ }
+ let index = item[0];
+ let value = item[1];
+ if (index == undefined || value == undefined) {
+ throw new Error("error");
+ }
+ if (index < 0 || index > stateList.length - 1) {
+ continue;
+ }
+ let start = result.slice(0, index);
+ start = start.concat([value]);
+ result = start.concat(result.slice(index + 1));
+ }
+ return result;
+}
+
+// List of Chinese Pinyin Initials
+let strChineseFirstPY = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSC" +
+"YYYNJQYXXGJHHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPCBZ" +
+"JJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZZXNBGNNXBXLZSZS" +
+"BSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZXYALMELDCCXGZYRJXSDLTYZCQKCN" +
+"NJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXPJBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQT" +
+"GLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCSKDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMB" +
+"DTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCSHZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZA" +
+"SYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNCLLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXH" +
+"LGTGXBQJDZPYJSJYJCTMRNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJ" +
+"FFFFJCZFMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXKLQSCGJ" +
+"CLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZMLJLLJKYWXMKJLHSKJG" +
+"BMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJGBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLL" +
+"SDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJXXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYL" +
+"JSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXPXJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYL" +
+"YMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWGYJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPP" +
+"BFYHZHTJYFDZWKGKZBLDNTSXHQEEGZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBML" +
+"SFBHHGYGYYGGBHSCYAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZY" +
+"GPZSZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMCHKDSCRSWJP" +
+"WXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCKZXSHMLQXXTTHXWZFKHCCZDY" +
+"TCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHPYYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTX" +
+"JCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGGTGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZW" +
+"GPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWFZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDG" +
+"CYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGAFFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTL" +
+"FYQKASDNTCYHBLWDZHBBYDWJRYGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSL" +
+"CMBJCSZZKYDCZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZS" +
+"YMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZBYJTZBXHFDXKDA" +
+"SWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZEMMQBSQEHXFZMBMFLZZSRXYMJGS" +
+"XWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNYNPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMC" +
+"PJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYXYWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXY" +
+"YRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZYJZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMT" +
+"CJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYSXQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDH" +
+"ZGZDWYBSSCSKXSYHYTXXGCQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJY" +
+"ZWZXZDDXJSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWXLYDHL" +
+"YQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAWHZMLJTWYGXLYQZLJEE" +
+"YYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZSZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQ" +
+"YTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZQJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYW" +
+"YWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSBDSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZG" +
+"MDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQCFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMT" +
+"YBBCLBJASKYTSSQYYMSZXFJEWLXLLSZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBS" +
+"DZZTFDMXHCNJZYMQWSRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZ" +
+"XJTCZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHXNWXXKHKFH" +
+"TSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHHCJYXGLHZXCSNHEKDTGZXQY" +
+"PKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKTLXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWS" +
+"ZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSLFYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCP" +
+"MMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQQPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQ" +
+"JSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZKKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQ" +
+"HHHEYTMHLFSBDJSYYSHFYSTCZQLPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBB" +
+"ZPNPPTYZZYBQNYDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJ" +
+"LJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNNWZXQXCDSLQGDS" +
+"DPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAXYWQCJTLLCKJJTJHGDXDXYQYZZB" +
+"YWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZKSSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQ" +
+"GYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJXLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJY" +
+"EMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLLHYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGD" +
+"XJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXMSZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYS" +
+"PYMPQZMLPPLFFXJJNZZYLSJEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZ" +
+"SXYFYMNCWDABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYSPMJK" +
+"HWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCTZQXKYQFPYYRPFFLKQ" +
+"UNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJSWLJMYMMZYHFBJDGYXCCPSHXNZCSBSJ" +
+"YJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLHPFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZB" +
+"LCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZD" +
+"QQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYGBDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPH" +
+"ZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZSKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPB" +
+"YKXRYLYBHKJKSFXTZJMMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRT" +
+"QZSSTKXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZMMNYTPZS" +
+"XQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNYXHSZXCGJZYQPYLFHDJSBP" +
+"CCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZLYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZC" +
+"QQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXYGYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDE" +
+"SJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLBDJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMH" +
+"QNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJMQPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXS" +
+"RGJCWTJTZZQMGWJJTJHTQJBBHWZPXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMB" +
+"ZZLYGHGFMSHPZFZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQP" +
+"WQLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYHDHRJZSFGXTSY" +
+"CZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYKQSYSLZDQJMPXYYSSRHZJNYWTQ" +
+"DFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQQQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYS" +
+"YXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYFJHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYP" +
+"JYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZ" +
+"ZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJSXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWT" +
+"YYDCHQLXKPZWBGQYBKFCMZWPZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYL" +
+"MSTDJCYHBZLLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLTYXH" +
+"QLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJCFPQRYQXCYYYQYGRP" +
+"YWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXNSQYXMQYWRGYQLXBBZLJSYLPSYTJZY" +
+"HYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXLYYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCR" +
+"YLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDPBCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCD" +
+"JJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZGMYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYS" +
+"LBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYMCCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXX" +
+"TXXNBHRMLYJSLTXMRHNLXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYX" +
+"LSZQYXBEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXDRMJWRHX" +
+"CJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZDJGTKHSSTCYJLPSWZLXZX" +
+"RWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZBLZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNT" +
+"YJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSDCHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLY" +
+"CYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYMDJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGW" +
+"HKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLLMQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZM" +
+"DPJHGCLGMJJPGAEHHBWCQXAXHHHZCHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZ" +
+"QYXXDXXPFDMMSSYMPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPP" +
+"MHNLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPMLKJXMHLMLQMX" +
+"CTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNPPLPLPEPSZALLTYLKCKQZKGEN" +
+"QLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYDWQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDF" +
+"XQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXLDDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZ" +
+"LLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQHZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZ" +
+"ZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHTXSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTC" +
+"TSSYLLGZRZBBQZZKLPKLCZYSSUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYS" +
+"JYCZTLQZYBBYBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJQJ" +
+"PDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRFKZTJDHCZKLBSDZC" +
+"FJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXPZXHYZYCLWDXJJHXMFDZPFZHQHQMQ" +
+"GKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDLXBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZ" +
+"LSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHLXZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFL" +
+"CJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZKJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFS" +
+"ZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZXZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJ" +
+"HZYJFJXRZSDLLLTQSQQZQWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXY" +
+"WGSYJYZNBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJHZCXZBT" +
+"YNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJKRDHHGXJLJJTGXJXXST" +
+"JTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFXGFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRL" +
+"FSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLYZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFX" +
+"PYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXDYLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQ" +
+"YCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDUTJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJF" +
+"ZYNAKRGYWYQPQXXFKJTSZZXSWZDDFBBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJK" +
+"YHCPSTMCSQTZJYXTPCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJ" +
+"PXGLBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZZGJZZXTZJX" +
+"YCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCYSCCLDXYCDDQLYJJWMQLLCSG" +
+"LJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZMYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBG" +
+"MYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCYXZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJ" +
+"YHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBXGLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJ" +
+"DQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQDSPDJZZGKGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXX" +
+"NCWCXYPMAELYKKJMZZZBRXYYQJFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCX" +
+"TLWDQZPCYCYKPPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXMB" +
+"DZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLYXWJHSNLXYYXHBH" +
+"AWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXXLYLLJDZBTYMHPFSTTQQWLHOKYBL" +
+"ZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHLJKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZK" +
+"BXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHGZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFY" +
+"WLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZWFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGC" +
+"ULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJL" +
+"LQZYJSWXMZZMMYLMXCLMXCZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLL" +
+"LPYPSYJYSXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZYPFDW" +
+"FGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYDTZJYQGGKQTTFZXBDKT" +
+"YYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJDSZBLPRZTSWSBXBCLLXXLZDJZSJPYLY" +
+"XXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGYGMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZ" +
+"ZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCYZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZY" +
+"XXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZ" +
+"LJJXLSBHPYXXPSXSHHEZTXFPTLQYZZXHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWD" +
+"XZSXZDZXLEYJJZQBHZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJH" +
+"OJYNXELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYDMPXMDSXYB" +
+"SQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPGNYDMSXHMMMMAMYNBYJTMPX" +
+"YYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXMJSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZB" +
+"YZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQ" +
+"SQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQQJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZK" +
+"ZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMTJQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLC" +
+"TZSXKJZQZPZLBZRBTJDCXFCZDBCCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYC" +
+"ZGJWYXDXFRSKSTQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZF" +
+"YBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCPZBLLCYBBBBUBB" +
+"CBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSSTPHNDJXXBYXQTZQDDTJTDYYTGWS" +
+"CSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZAZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYY" +
+"LLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJXGNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYM" +
+"RBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMSLPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZX" +
+"JCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXTQCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLF" +
+"NDXQKCZFYWHGQMRDSXYCYTXNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZ" +
+"CZPTQFZMYFLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZTLML" +
+"WZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZJYJGMCTXLTGXSZLML" +
+"HBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQMSTPXLSKLZYNWRTSQLSZBPSPSGZWYHT" +
+"LKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCLXXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQ" +
+"JZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKNXJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGY" +
+"ZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQGBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZ" +
+"LPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZNCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPC" +
+"QDHLXZLYCBLCXZZJADJLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQK" +
+"TWPXXHCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBBFJLLCXDL" +
+"MJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPSSYYFNEJDXYZHLXLLLZQZS" +
+"JNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYA" +
+"DTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDDWRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZP" +
+"KJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSHCKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQH" +
+"YWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHHJTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQ" +
+"BSHYLLPJJJTHYJKYPPTHYYKTYEZYENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFS" +
+"YZYZBJTBCTSBSDHRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZN" +
+"SDJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQPQJPZYPZJZNJP" +
+"ZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQCZLPTXCDYYZXSQZSLXLZMYCPC" +
+"QBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJQQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZT" +
+"DKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBRFERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDD" +
+"NXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXCYZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSD" +
+"DTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZSQYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZ" +
+"HLYQQJBEYFXXXWHSRXWQHWPSLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELG" +
+"LXYDJYTLFBHBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYFLZB" +
+"YFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJTJTPWJYBJJBXJJTJ" +
+"TEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHYYXWSHCTXRLJHQXHCCYYYJLTKTTYTM" +
+"XGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYLBLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZG" +
+"LHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJLJXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQ" +
+"QMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQDCYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTT" +
+"SSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHWWKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWP" +
+"YMLGKDLDLGKQQBGYCHJXY";
+// 375 polyphonic words are included here
+let oMultiDiff = { "19969": "DZ", "19975": "WM", "19988": "QJ", "20048": "YL", "20056": "SC", "20060": "NM",
+ "20094": "QG", "20127": "QJ", "20167": "QC", "20193": "YG", "20250": "KH", "20256": "ZC", "20282": "SC",
+ "20285": "QJG", "20291": "TD", "20314": "YD", "20340": "NE", "20375": "TD", "20389": "YJ", "20391": "CZ",
+ "20415": "PB", "20446": "YS", "20447": "SQ", "20504": "TC", "20608": "KG", "20854": "QJ", "20857": "ZC",
+ "20911": "PF", "20985": "AW", "21032": "PB", "21048": "XQ", "21049": "SC", "21089": "YS", "21119": "JC",
+ "21242": "SB", "21273": "SC", "21305": "YP", "21306": "QO", "21330": "ZC", "21333": "SDC", "21345": "QK",
+ "21378": "CA", "21397": "SC", "21414": "XS", "21442": "SC", "21477": "JG", "21480": "TD", "21484": "ZS",
+ "21494": "YX", "21505": "YX", "21512": "HG", "21523": "XH", "21537": "PB", "21542": "PF", "21549": "KH",
+ "21571": "E", "21574": "DA", "21588": "TD", "21589": "O", "21618": "ZC", "21621": "KHA", "21632": "ZJ",
+ "21654": "KG", "21679": "LKG", "21683": "KH", "21710": "A", "21719": "YH", "21734": "WOE", "21769": "A",
+ "21780": "WN", "21804": "XH", "21834": "A", "21899": "ZD", "21903": "RN", "21908": "WO", "21939": "ZC",
+ "21956": "SA", "21964": "YA", "21970": "TD", "22003": "A", "22031": "JG", "22040": "XS", "22060": "ZC",
+ "22066": "ZC", "22079": "MH", "22129": "XJ", "22179": "XA", "22237": "NJ", "22244": "TD", "22280": "JQ",
+ "22300": "YH", "22313": "XW", "22331": "YQ", "22343": "YJ", "22351": "PH", "22395": "DC", "22412": "TD",
+ "22484": "PB", "22500": "PB", "22534": "ZD", "22549": "DH", "22561": "PB", "22612": "TD", "22771": "KQ",
+ "22831": "HB", "22841": "JG", "22855": "QJ", "22865": "XQ", "23013": "ML", "23081": "WM", "23487": "SX",
+ "23558": "QJ", "23561": "YW", "23586": "YW", "23614": "YW", "23615": "SN", "23631": "PB", "23646": "ZS",
+ "23663": "ZT", "23673": "YG", "23762": "TD", "23769": "ZS", "23780": "QJ", "23884": "QK", "24055": "XH",
+ "24113": "DC", "24162": "ZC", "24191": "GA", "24273": "QJ", "24324": "NL", "24377": "TD", "24378": "QJ",
+ "24439": "PF", "24554": "ZS", "24683": "TD", "24694": "WE", "24733": "LK", "24925": "TN", "25094": "ZG",
+ "25100": "XQ", "25103": "XH", "25153": "PB", "25170": "PB", "25179": "KG", "25203": "PB", "25240": "ZS",
+ "25282": "FB", "25303": "NA", "25324": "KG", "25341": "ZY", "25373": "WZ", "25375": "XJ", "25384": "A",
+ "25457": "A", "25528": "SD", "25530": "SC", "25552": "TD", "25774": "ZC", "25874": "ZC", "26044": "YW",
+ "26080": "WM", "26292": "PB", "26333": "PB", "26355": "ZY", "26366": "CZ", "26397": "ZC", "26399": "QJ",
+ "26415": "ZS", "26451": "SB", "26526": "ZC", "26552": "JG", "26561": "TD", "26588": "JG", "26597": "CZ",
+ "26629": "ZS", "26638": "YL", "26646": "XQ", "26653": "KG", "26657": "XJ", "26727": "HG", "26894": "ZC",
+ "26937": "ZS", "26946": "ZC", "26999": "KJ", "27099": "KJ", "27449": "YQ", "27481": "XS", "27542": "ZS",
+ "27663": "ZS", "27748": "TS", "27784": "SC", "27788": "ZD", "27795": "TD", "27812": "O", "27850": "PB",
+ "27852": "MB", "27895": "SL", "27898": "PL", "27973": "QJ", "27981": "KH", "27986": "HX", "27994": "XJ",
+ "28044": "YC", "28065": "WG", "28177": "SM", "28267": "QJ", "28291": "KH", "28337": "ZQ", "28463": "TL",
+ "28548": "DC", "28601": "TD", "28689": "PB", "28805": "JG", "28820": "QG", "28846": "PB", "28952": "TD",
+ "28975": "ZC", "29100": "A", "29325": "QJ", "29575": "SL", "29602": "FB", "30010": "TD", "30044": "CX",
+ "30058": "PF", "30091": "YSP", "30111": "YN", "30229": "XJ", "30427": "SC", "30465": "SX", "30631": "YQ",
+ "30655": "QJ", "30684": "QJG", "30707": "SD", "30729": "XH", "30796": "LG", "30917": "PB", "31074": "NM",
+ "31085": "JZ", "31109": "SC", "31181": "ZC", "31192": "MLB", "31293": "JQ", "31400": "YX", "31584": "YJ",
+ "31896": "ZN", "31909": "ZY", "31995": "XJ", "32321": "PF", "32327": "ZY", "32418": "HG", "32420": "XQ",
+ "32421": "HG", "32438": "LG", "32473": "GJ", "32488": "TD", "32521": "QJ", "32527": "PB", "32562": "ZSQ",
+ "32564": "JZ", "32735": "ZD", "32793": "PB", "33071": "PF", "33098": "XL", "33100": "YA", "33152": "PB",
+ "33261": "CX", "33324": "BP", "33333": "TD", "33406": "YA", "33426": "WM", "33432": "PB", "33445": "JG",
+ "33486": "ZN", "33493": "TS", "33507": "QJ", "33540": "QJ", "33544": "ZC", "33564": "XQ", "33617": "YT",
+ "33632": "QJ", "33636": "XH", "33637": "YX", "33694": "WG", "33705": "PF", "33728": "YW", "33882": "SR",
+ "34067": "WM", "34074": "YW", "34121": "QJ", "34255": "ZC", "34259": "XL", "34425": "JH", "34430": "XH",
+ "34485": "KH", "34503": "YS", "34532": "HG", "34552": "XS", "34558": "YE", "34593": "ZL", "34660": "YQ",
+ "34892": "XH", "34928": "SC", "34999": "QJ", "35048": "PB", "35059": "SC", "35098": "ZC", "35203": "TQ",
+ "35265": "JX", "35299": "JX", "35782": "SZ", "35828": "YS", "35830": "E", "35843": "TD", "35895": "YG",
+ "35977": "MH", "36158": "JG", "36228": "QJ", "36426": "XQ", "36466": "DC", "36710": "JC", "36711": "ZYG",
+ "36767": "PB", "36866": "SK", "36951": "YW", "37034": "YX", "37063": "XH", "37218": "ZC", "37325": "ZC",
+ "38063": "PB", "38079": "TD", "38085": "QY", "38107": "DC", "38116": "TD", "38123": "YD", "38224": "HG",
+ "38241": "XTC", "38271": "ZC", "38415": "YE", "38426": "KH", "38461": "YD", "38463": "AE", "38466": "PB",
+ "38477": "XJ", "38518": "YT", "38551": "WK", "38585": "ZC", "38704": "XS", "38739": "LJ", "38761": "GJ",
+ "38808": "SQ", "39048": "JG", "39049": "XJ", "39052": "HG", "39076": "CZ", "39271": "XT", "39534": "TD",
+ "39552": "TD", "39584": "PB", "39647": "SB", "39730": "LG", "39748": "TPB", "40109": "ZQ", "40479": "ND",
+ "40516": "HG", "40536": "HG", "40583": "QJ", "40765": "YQ", "40784": "QJ", "40840": "YK", "40863": "QJG" };
+
+// Program that returns the first letter array of Chinese characters
+export function makePy(str) {
+ if (typeof(str) != "string")
+ throw new Error("函数makePy需要字符串类型参数!");
+ var arrResult = [];
+ // Convert string to array
+ for (var i = 0, len = str.length; i < len; i++) {
+ var ch = str.charAt(i);
+ arrResult.push(checkCh(ch));
+ }
+ return mkRslt(arrResult);
+}
+
+// Check processing Chinese characters
+function checkCh(ch) {
+ var uni = ch.charCodeAt(Constants.CHAR_CODE);
+ // If it is not within the scope of Chinese character processing, return the original character, and you can also call your own processing function
+ if (uni > Constants.UNI_MAX || uni < Constants.UNI_MIN)
+ return ch; //dealWithOthers(ch);
+ // Check whether it is a polyphonic word, it is processed as a polyphonic word, if not, just find the corresponding first letter in the strChineseFirstPY string.
+ return (oMultiDiff[uni] ? oMultiDiff[uni] : (strChineseFirstPY.charAt(uni - Constants.UNI_MIN)));
+}
+
+// Process the characters and return an array of letters
+function mkRslt(arr) {
+ var arrRslt = [""];
+ for (var i = 0, len = arr.length; i < len; i++) {
+ var str = arr[i];
+ var strlen = str.length;
+ if (strlen == 1) {
+ for (var k = 0; k < arrRslt.length; k++) {
+ arrRslt[k] += str;
+ }
+ } else {
+ var tmpArr = arrRslt.slice(0);
+ arrRslt = [];
+ for (k = 0; k < strlen; k++) {
+ // Copy an identical arrRslt
+ var tmp = tmpArr.slice(0);
+ // Add the current character str[k] to the end of each element
+ for (var j = 0; j < tmp.length; j++) {
+ tmp[j] += str.charAt(k);
+ }
+ // Concatenate the copied and modified array to arrRslt
+ arrRslt = arrRslt.concat(tmp);
+ }
+ }
+ }
+ return arrRslt;
+}
+
+/**
+ * Get the corresponding permission group id according to the permission
+ * @param {String} permission app name id
+ * @return {Number} groupId
+ */
+export function getPermissionGroup(permission: string) {
+ for (var i = 0; i < permissionGroups.length; i++) {
+ if (permissionGroups[i].permissionName == permission) {
+ if(permissionGroups[i].groupName == 'OTHER') {
+ return {
+ "name": permissionGroups[i].groupName,
+ "groupName": permissionGroups[i].label,
+ "label": permissionGroups[i].text,
+ "icon": permissionGroups[i].icon,
+ "description": '',
+ "permissions": [
+ permissionGroups[i].permissionName
+ ]
+ }
+ }else {
+ return groups[permissionGroups[i].groupId]
+ }
+ }
+ }
+}
+
+const TAG = 'PermissionManager_Log';
+
+export class Log {
+ static info(log) {
+ console.info(`Info: ${TAG} ${log}`)
+ }
+
+ static error(log) {
+ console.error(`Error: ${TAG} ${log}`)
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/ets/pages/application-secondary.ets b/permissionmanager/src/main/ets/pages/application-secondary.ets
new file mode 100644
index 0000000..6ff3deb
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/application-secondary.ets
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import router from '@system.router';
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import { groups } from "../common/model/permissionGroup";
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+const allowedStatus = 0; // Status: Allowed
+const bannedStatus = 1; // Status: Banned
+
+class AllowedObj {
+ groupName: string;
+ permission: string[];
+ constructor(groupName: string, permission: string[]) {
+ this.groupName = groupName;
+ this.permission = permission;
+ }
+} // Class Allowed
+class BannedObj {
+ groupName: string;
+ permission: string[];
+ constructor(groupName: string, permission: string[]) {
+ this.groupName = groupName;
+ this.permission = permission;
+ }
+} // Class Banned
+
+@Entry
+@Component
+struct appNamePlusPage {
+ @State allowedListItem: AllowedObj[] = []; // Array of allowed permissions
+ @State bannedListItem: BannedObj[] = []; // array of forbidden permissions
+ private routerData = router.getParams().routerData; // Routing jump data
+
+ @Builder ListItemLayout(item, index, status) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Text(item.groupName)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.text_color'))
+ .fontWeight(FontWeight.Medium)
+ .flexGrow(Constants.FLEX_GROW)
+ Image($r('app.media.rightarrow'))
+ .objectFit(ImageFit.Contain)
+ .height(Constants.IMAGE_HEIGHT)
+ .width(Constants.IMAGE_WIDTH)
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.LISTITEM_ROW_HEIGHT)
+ }
+ if (!index) {
+ Row() {
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ }
+ }
+ }.onClick(() => {
+ if (status === 'allow') {
+ if (item.groupName == "其他权限") {
+ router.push({
+ uri: 'pages/other-permissions',
+ params: {
+ routerData: this.routerData.bundleName,
+ backTitle: item.groupName,
+ permission: item.permission,
+ status: allowedStatus,
+ tokenId: this.routerData.tokenId
+ }
+ });
+ } else {
+ router.push({
+ uri: 'pages/application-tertiary',
+ params: {
+ routerData: this.routerData.bundleName,
+ backTitle: item.groupName,
+ permission: item.permission,
+ status: allowedStatus
+ }
+ });
+ }
+ }
+ else if (status === 'banned') {
+ if (item.groupName == "其他权限") {
+ router.push({
+ uri: 'pages/other-permissions',
+ params: {
+ routerData: this.routerData.bundleName,
+ backTitle: item.groupName,
+ permission: item.permission,
+ status: bannedStatus,
+ tokenId: this.routerData.tokenId
+ }
+ });
+ } else {
+ router.push({
+ uri: 'pages/application-tertiary',
+ params: {
+ routerData: this.routerData.bundleName,
+ backTitle: item.groupName,
+ permission: item.permission,
+ status: bannedStatus
+ }
+ });
+ }
+ }
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ /**
+ * Initialize permission status information and group permission information
+ */
+ async initialPermissions() {
+ var reqPermissions = this.routerData.permissions;
+ var reqGroupIds = this.routerData.groupId;
+
+ if (!reqGroupIds.length) {
+ this.allowedListItem = [];
+ this.bannedListItem = [];
+ return;
+ }
+
+ for (let i = 0; i < reqGroupIds.length; i++) {
+ let id = reqGroupIds[i];
+ let groupName = groups[id].groupName;
+ let groupReqPermissons = [];
+ for (let j = 0; j < reqPermissions.length; j++) {
+ let permission = reqPermissions[j];
+ if (groups[id].permissions.indexOf(permission) != -1) {
+ groupReqPermissons.push(permission)
+ }
+ }
+ let isGranted = true;
+ for (let i = 0; i < groupReqPermissons.length; i++) {
+ let permission = groupReqPermissons[i]
+ let res = await abilityAccessCtrl.createAtManager().verifyAccessToken(
+ this.routerData.tokenId, permission);
+ if (res != 0) {
+ isGranted = false;
+ }
+ }
+
+ if (isGranted) {
+ this.allowedListItem.push(new AllowedObj(groupName, groupReqPermissons));
+ } else {
+ this.bannedListItem.push(new BannedObj(groupName, groupReqPermissons));
+ }
+ }
+ }
+
+ /**
+ * Lifecycle function, triggered once when this page is displayed
+ */
+ onPageShow() {
+ console.log(TAG + 'onPageShow application-secondary')
+ this.initialPermissions();
+ }
+
+ /**
+ * Lifecycle function, triggered once when this page disappears
+ */
+ onPageHide() {
+ console.log(TAG + 'onPageHide application-secondary')
+ setTimeout(()=> {
+ this.allowedListItem = [];
+ this.bannedListItem = [];
+ }, Constants.DELAY_TIME)
+ }
+
+ build() {
+ Column(){
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row({}) {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(this.routerData.labelId), recordable: false })
+ }
+ Row() {
+ Column() {
+ if (!this.allowedListItem.length && !this.bannedListItem.length) {
+ Row() {
+ List() {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Column() {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Text($r('app.string.no_permission'))
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.text_color'))
+ }.margin({ top: Constants.FLEX_MARGIN_TOP, bottom: Constants.FLEX_MARGIN_BOTTOM })
+ }.height(Constants.FULL_HEIGHT)
+ }.flexGrow(Constants.FLEX_GROW)
+ .constraintSize({minHeight: Constants.CONSTRAINTSIZE_MINHEIGHT })
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.LISTITEM_ROW_HEIGHT)
+ }
+ }
+ }
+ }.padding({ left: Constants.LISTITEM_PADDING_LEFT, right: Constants.LISTITEM_PADDING_RIGHT })
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.ROW_MARGIN_TOP })
+ .padding({ left: Constants.SECONDARY_LIST_PADDING_LEFT, right: Constants.SECONDARY_LIST_PADDING_RIGHT })
+ } else {
+ Scroll() {
+ List() {
+ if (this.allowedListItem.length) {
+ ListItem() {
+ Row() {
+ Text($r('app.string.allowed'))
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .fontWeight(FontWeight.Medium)
+ .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
+ }.constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
+ .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
+ left: Constants.SECONDARY_TEXT_MARGIN_LEFT})
+ }
+
+ ListItem() {
+ Row() {
+ List() {
+ ForEach(this.allowedListItem.slice(Constants.SLICE_START, this.allowedListItem.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX, 'allow')
+ }, item => item.toString())
+ ForEach(this.allowedListItem.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX, 'allow')
+ }, item => item.toString())
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.ROW_MARGIN_TOP })
+ .padding({
+ left: Constants.SECONDARY_LIST_PADDING_LEFT,
+ right: Constants.SECONDARY_LIST_PADDING_RIGHT
+ })
+ }
+ }
+ if (this.bannedListItem.length) {
+ ListItem() {
+ Row() {
+ Text($r('app.string.banned'))
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .fontWeight(FontWeight.Medium)
+ .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
+ }.constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
+ .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
+ left: Constants.SECONDARY_TEXT_MARGIN_LEFT})
+ }
+
+ ListItem() {
+ Row() {
+ List() {
+ ForEach(this.bannedListItem.slice(Constants.SLICE_START, this.bannedListItem.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX, 'banned')
+ }, item => item.toString())
+ ForEach(this.bannedListItem.slice(Constants.SLICE_END), (item) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX, 'banned')
+ }, item => item.toString())
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.ROW_MARGIN_TOP })
+ .padding({
+ left: Constants.SECONDARY_LIST_PADDING_LEFT,
+ right: Constants.SECONDARY_LIST_PADDING_RIGHT
+ })
+ }
+ }
+ }
+ }.scrollBar(BarState.Off)
+ }
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.FULL_HEIGHT)
+ }
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/application-tertiary.ets b/permissionmanager/src/main/ets/pages/application-tertiary.ets
new file mode 100644
index 0000000..e4d4e0c
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/application-tertiary.ets
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import router from '@system.router';
+import bundle from "@ohos.bundle";
+import { getAppLabel, getAppIcon, verifyAccessToken } from "../common/utils/utils";
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import Resmgr from '@ohos.resourceManager'
+import { authorizeDialog } from "../common/components/dialog";
+import { permissionDescriptions, permissionGroups, showSubpermissionsGrop } from "../common/model/permissionGroup";
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+let routerData = router.getParams().routerData; // Routing jump data
+let backTitle = router.getParams().backTitle; // return title name
+let status = router.getParams().status; // Status: Allowed, Forbidden
+let permissions = router.getParams().permission; // permissions name
+let nowGrantResult = Constants.PERMISSION_NUM; // Authorization results now
+let nowRevokeResult = Constants.PERMISSION_NUM; // Now deauthorize results
+let GrantResultFlag = []; // Authorization result Flag
+let RevokeResultFlag = []; // Cancel authorization result Flag
+let reason = null // Authorized reason
+class MeidaDocObj {
+ name: string
+ index: number
+ groupName: string
+ accessTokenId: string
+ permissions: []
+ constructor(
+ name: string,
+ index: number,
+ groupName: string,
+ accessTokenId: string,
+ permissions: []
+ ) {
+ this.name = name
+ this.index = index
+ this.groupName = groupName
+ this.accessTokenId = accessTokenId
+ this.permissions = permissions
+ }
+}; // permission information class
+class MediaListObj {
+ labelId: string
+ iconId: string
+ versionName: string
+ description: string
+ constructor(
+ labelId: string,
+ iconId: string,
+ versionName: string,
+ description: string
+ ) {
+ this.labelId = labelId
+ this.iconId = iconId
+ this.versionName = versionName
+ this.description = description
+ }
+}; // Permission application information class
+
+@Entry
+@Component
+struct mediaDocumentPage {
+ build() {
+ Column() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(backTitle), recordable: false })
+ }
+ Row() {
+ Column() {
+ mediaDocumentItem()
+ }.width(Constants.FULL_WIDTH)
+ }
+ .margin({ top: Constants.TITLE_MARGIN_BOTTOM })
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+ }
+}
+
+@Component
+struct mediaDocumentItem {
+ @State mediaDocListItem: MeidaDocObj[] = []; // Permission information array
+ @State mediaListItem: MediaListObj = {
+ labelId: '',
+ iconId: '',
+ versionName: '',
+ description: ''
+ }; // application info array
+ @State isCheckList: boolean[] = []; // Permission status array
+
+ authorizeDialogController: CustomDialogController = new CustomDialogController({
+ builder: authorizeDialog({ }),
+ autoCancel: true,
+ alignment: DialogAlignment.Center
+ });
+
+ /**
+ * Grant permissions to the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ */
+ grantUserGrantedPermission(accessTokenId, permission) {
+ abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then((result) => {
+ nowGrantResult = result;
+ })
+ .catch((error) => {
+ console.error(TAG + 'grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Deauthorize the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ */
+ revokeUserGrantedPermission(accessTokenId, permission) {
+ abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then((result) => {
+ nowRevokeResult = result;
+ })
+ .catch((error) => {
+ console.error(TAG + 'revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Lifecycle function, executed when the page is initialized
+ */
+ aboutToAppear() {
+ let permissionDescription = permissionDescriptions[backTitle];
+ if(showSubpermissionsGrop.indexOf(backTitle) != -1) {
+ reason = []
+ permissions.forEach(permission => {
+ permissionGroups.forEach(permissionGroup => {
+ if(permissionGroup.permissionName == permission) {
+ reason.push(permissionGroup.label)
+ }
+ })
+ })
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ Promise.all([item.getString($r("app.string.separator").id),
+ item.getString($r("app.string.reason_suffix").id)])
+ .then(values => {
+ reason = reason.join(values[0])
+ reason += values[1]
+ })
+ })
+ }else {
+ reason = ''
+ }
+ let hasReason = false
+ bundle.getBundleInfo(routerData, Constants.PARMETER_BUNDLE_FLAG).then(res => {
+ permissions.forEach(permission => {
+ res.reqPermissionDetails.forEach(reqPermissionDetail => {
+ if(reqPermissionDetail.name == permission) {
+ Resmgr.getResourceManager(globalThis.context, routerData).then(item => {
+ item.getString(reqPermissionDetail.reasonId, (err, value) => {
+ if (value !== undefined && !hasReason) {
+ reason += value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT)
+ hasReason = true
+ }
+ })
+ })
+ }
+ })
+ })
+ Promise.all([getAppLabel(res.appInfo.labelId, res.name),
+ getAppIcon(res.appInfo.iconId, res.name)])
+ .then((values) => {
+ this.mediaListItem = new MediaListObj(
+ String(values[0]), String(values[1]), res.versionName, permissionDescription);
+ })
+ this.mediaDocListItem.push(
+ new MeidaDocObj(
+ Constants.RADIO_ALLOW_NAME,
+ Constants.RADIO_ALLOW_INDEX,
+ Constants.RADIO_ALLOW_GROUP_NAME,
+ res.appInfo.accessTokenId,
+ permissions
+ )
+ );
+ this.mediaDocListItem.push(
+ new MeidaDocObj(
+ Constants.RADIO_BAN_NAME,
+ Constants.RADIO_BAN_INDEX,
+ Constants.RADIO_BAN_GROUP_NAME,
+ res.appInfo.accessTokenId,
+ permissions
+ )
+ );
+ }).catch((error) => {
+ console.error(TAG + 'bundle.getBundleInfo failed. Cause: ' + JSON.stringify(error));
+ this.mediaListItem = new MediaListObj('', '', '', permissionDescription);
+ this.mediaDocListItem.push(
+ new MeidaDocObj(Constants.RADIO_ALLOW_NAME, Constants.RADIO_ALLOW_INDEX,
+ Constants.RADIO_ALLOW_GROUP_NAME, '', permissions)
+ );
+ this.mediaDocListItem.push(
+ new MeidaDocObj(Constants.RADIO_BAN_NAME, Constants.RADIO_BAN_INDEX,
+ Constants.RADIO_BAN_GROUP_NAME, '', permissions)
+ );
+ })
+ // Get permission status
+ if (!status) {
+ this.isCheckList = [true, false];
+ } else {
+ this.isCheckList = [false, true];
+ }
+ }
+
+ build(){
+ Column() {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Image(this.mediaListItem.iconId)
+ .width(Constants.TERTIARY_IMAGE_WIDTH)
+ .height(Constants.TERTIARY_IMAGE_HEIGHT)
+ .margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
+ Column() {
+ Row() {
+ Text(this.mediaListItem.labelId)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.label_color'))
+ .fontWeight(FontWeight.Bold)
+ .textAlign(TextAlign.Start)
+ }
+ .width(Constants.TERTIARY_HALF_WIDTH)
+ .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
+ Row() {
+ Text(this.mediaListItem.versionName)
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .textAlign(TextAlign.Start)
+ }
+ .width(Constants.TERTIARY_HALF_WIDTH)
+ }
+ }.margin({ left: Constants.TERTIARY_MARGIN_LEFT })
+ }
+ if(reason) {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Text(reason)
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .textAlign(TextAlign.Start)
+ }.margin({ left: Constants.TERTIARY_IMAGE_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT })
+ }
+ }
+ .margin({ top: Constants.TERTIARY_ROW_MARGIN_TOP, left: Constants.TERTIARY_MARGIN_LEFT })
+ }
+ Row() {
+ Text(backTitle)
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .fontWeight(FontWeight.Medium)
+ .textAlign(TextAlign.Start)
+ .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
+ Text($r('app.string.access_permission'))
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .fontWeight(FontWeight.Medium)
+ .textAlign(TextAlign.Start)
+ .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
+ }.width(Constants.FULL_WIDTH)
+ .constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
+ .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM,
+ left: Constants.TERTIARY_TEXT_MARGIN_LEFT, right: Constants.TERTIARY_IMAGE_MARGIN_RIGHT})
+ .margin({ top: Constants.TERTIARY_PERMISSION_ROW_MARGIN_TOP })
+ Column() {
+ List() {
+ ForEach(this.mediaDocListItem, (item) => {
+ ListItem() {
+ Column() {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Text(item.name)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.label_color'))
+ .fontWeight(FontWeight.Medium)
+ .flexGrow(Constants.FLEX_GROW)
+ if (this.isCheckList[item.index] === true) {
+ Shape() {
+ Circle().width(Constants.SHAPE_DIA).height(Constants.SHAPE_DIA)
+ .fill($r("app.color.shape_allow_color")).offset({ x: 0, y: 0 })
+ Circle().width(Constants.SHAPE_ALLOW_DIA).height(Constants.SHAPE_ALLOW_DIA)
+ .fill($r("app.color.default_background_color"))
+ .offset({ x: Constants.SHAPE_ALLOW_OFFSET, y: Constants.SHAPE_ALLOW_OFFSET })
+ }
+ } else if (this.isCheckList[item.index] === false) {
+ Shape() {
+ Circle().width(Constants.SHAPE_DIA).height(Constants.SHAPE_DIA)
+ .fill($r("app.color.shape_ban_color")).offset({ x: 0, y: 0 })
+ Circle().width(Constants.SHAPE_BAN_DIA).height(Constants.SHAPE_BAN_DIA)
+ .fill($r("app.color.default_background_color"))
+ .offset({ x: Constants.SHAPE_BAN_OFFSET, y: Constants.SHAPE_BAN_OFFSET })
+ }
+ }
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.LISTITEM_ROW_HEIGHT)
+ .onClick(() => {
+ item.permissions.forEach((permission) => {
+ if (!item.index) {
+ this.grantUserGrantedPermission(item.accessTokenId, permission)
+ if (nowGrantResult != Constants.PERMISSION_INDEX) {
+ GrantResultFlag.push(-1)
+ }else{
+ GrantResultFlag.push(0)
+ }
+ } else {
+ this.revokeUserGrantedPermission(item.accessTokenId, permission)
+ if (nowRevokeResult != Constants.PERMISSION_INDEX) {
+ RevokeResultFlag.push(-1)
+ this.authorizeDialogController.open();
+ setTimeout(()=> {
+ this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ }else{
+ RevokeResultFlag.push(0)
+ }
+ }
+ })
+ if (!item.index) {
+ if(GrantResultFlag.indexOf(-1) > -1){
+ this.authorizeDialogController.open();
+ setTimeout(()=> {
+ this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ }else{
+ this.isCheckList = [true, false];
+ }
+ }else{
+ if (RevokeResultFlag.indexOf(-1) > -1){
+ this.authorizeDialogController.open();
+ setTimeout(()=> {
+ this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ }else{
+ this.isCheckList = [false, true];
+ }
+ }
+ })
+ }
+ }
+ if (!item.index) {
+ Row() {
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ }
+ }
+ }
+ .onClick(() => {
+ })
+ }
+ .padding({
+ left: Constants.DEFAULT_PADDING_START,
+ right: Constants.DEFAULT_PADDING_END
+ })
+ .margin({ top: Constants.TERTIARY_LISTITEM_MARGIN_TOP })
+ }, item => item.toString())
+ }
+ .borderRadius(Constants.BORDER_RADIUS)
+ .backgroundColor($r('app.color.default_background_color'))
+ .padding({
+ top: Constants.TERTIARY_LIST_PADDING_TOP, bottom: Constants.TERTIARY_LIST_PADDING_BOTTOM
+ })
+ }
+ .padding({
+ left: Constants.LIST_PADDING_LEFT,
+ right: Constants.LIST_PADDING_LEFT
+ })
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.FULL_HEIGHT)
+ }
+ .width(Constants.FULL_WIDTH)
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/authority-management.ets b/permissionmanager/src/main/ets/pages/authority-management.ets
new file mode 100644
index 0000000..a1e2535
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/authority-management.ets
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import { alphabetIndexerComponent } from "../common/components/alphabeticalIndex";
+import { textInput } from "../common/components/search";
+import router from '@system.router';
+import bundle from "@ohos.bundle";
+import Resmgr from '@ohos.resourceManager';
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import { groups, userGrantPermissions, permissionGroupPermissions, noNeedDisplayApp } from "../common/model/permissionGroup";
+import { permissionGroups, permissionPermissionGroup, permissionGroupIds } from "../common/model/permissionGroup";
+import { makePy } from "../common/utils/utils";
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+@Extend(Image) function customizeImage(width: number, height: number) {
+ .objectFit(ImageFit.Contain)
+ .width(width)
+ .height(height)
+};
+
+interface applicationPermissions {
+ 'bundleName': string,
+ 'iconId': string,
+ 'permissions': string[],
+ 'labelId': string,
+ 'tokenId': number,
+ 'groupId': number[]
+};
+
+interface permissionApplications {
+ 'permission': string,
+ 'groupName': string,
+ 'bundleNames': string[],
+ 'icon': string
+};
+
+interface groupPermission {
+ 'group': string,
+ 'permissions': string[],
+ 'groupName': string,
+ 'icon': string,
+ 'isShow':boolean
+};
+
+let bundleInfosList: any[] = []; // Permission information array
+let textInput_placeholder: any = ''
+
+@Entry
+@Component
+struct authorityManagementPage {
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Image(item.icon)
+ .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
+ .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
+ Text(item.groupName)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .flexGrow(Constants.FLEX_GROW)
+ Image($r('app.media.rightarrow'))
+ .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT)
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.MANAGEMENT_ROW_HEIGHT)
+ }
+ if (!index) {
+ Row() {
+ Flex() {
+ Column().width(Constants.MANAGEMENT_TEXT_DECORATION_MARGIN_LEFT)
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ .flexGrow(Constants.FLEX_GROW)
+ }
+ }
+ }
+ }.onClick(() => {
+ if (item.groupName === '其他权限' || item.groupName === '电话' || item.groupName === '通讯录' || item.groupName === '信息'
+ || item.groupName === '通话记录' || item.groupName === '日历') {
+ router.push({
+ uri: 'pages/authority-secondary',
+ params: { routerData: this.allPermissionApplications, backTitle: item.groupName }
+ })
+ } else {
+ var dataList = this.allPermissionApplications.filter((ele) => {
+ return ele.groupName === item.group
+ })
+
+ router.push({
+ uri: 'pages/authority-tertiary-groups',
+ params: { routerData: dataList, backTitle: item.groupName }
+ })
+ }
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ @State allApplicationPermissions: applicationPermissions[] = []; // All permissions apply
+ @State allPermissions: string[] = []; // All permissions
+ @State allSystemPermissions: string[] = []; // All system permissions
+ @State allUserPermissions: string[] = []; // All user rights
+ @State allPermissionApplications: permissionApplications [] = [] // All app permissions
+ @State allGroups: string[] = [] // All groups
+ @State allGroupPermission: groupPermission[] = [] // All group permissions
+ @State currentIndex: number = 0
+ @Builder TabBuilder(index: number) {
+ Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
+ Text(index ? $r('app.string.application') : $r('app.string.authority'))
+ .fontColor(this.currentIndex == index ? $r('app.color.button_color') : $r('app.color.label_color'))
+ .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular)
+ .lineHeight(Constants.TEXT_LINE_HEIGHT)
+ if(this.currentIndex == index) {
+ Row().width(Constants.FULL_WIDTH).height(Constants.TAB_DECORATION_HEIGHT)
+ .backgroundColor($r('app.color.button_color'))
+ .position({ y: Constants.TAB_DECORATION_POSITION_Y })
+ }
+ }.height(Constants.TAB_HEIGHT)
+ }
+
+ /**
+ * Convert the permission array into key, value key-value objects for easy sorting
+ * @param {Array} order User rights
+ * @return {Object} return the processed object
+ */
+ orderDict(order) {
+ let result = {};
+ for (let i = 0; i < order.length; i++) {
+ let key = order[i];
+ result[key] = i;
+ }
+ return result;
+ }
+
+ /**
+ * Compare and sort the permission array according to the permission key value
+ * @param {String} prop Sort by permission
+ * @param {Object} orderSort objects to be sorted
+ * @return {Array} Returns a sorted array of permissions
+ */
+ compare(prop, orderSort) {
+ return function(a, b) {
+ let aSortValue = orderSort[a[prop]];
+ let bSortValue = orderSort[b[prop]];
+ if (aSortValue == undefined) {
+ throw new Error('当前的字段不在排序列表里:' + a[prop]);
+ }
+ if (bSortValue == undefined) {
+ throw new Error('当前的字段不在排序列表里:' + b[prop]);
+ }
+ return aSortValue - bSortValue;
+ }
+ }
+
+ /**
+ * Get all app permission information
+ * @param {Array} allPermissions All permissions
+ * @param {Object} allApplicationPermissions All app permissions
+ */
+ getAllBundlePermissions(allPermissions: string[], allApplicationPermissions: applicationPermissions[]) {
+ bundle.getAllBundleInfo(Constants.PARMETER_BUNDLE_FLAG).then(async(res) => {
+ const bundleInfos = res;
+ var count = bundleInfos.length;
+ if (count <= 0) {
+ console.info(TAG + 'bundle.getAllBundleInfo result.length less than or equal to zero');
+ return;
+ }
+ var infoIndex = 0;
+ for (let i = 0; i < count; i++) {
+ var info = bundleInfos[i];
+ // Filter blank icon icon and text label resources
+ try {
+ const ret = await bundle.queryAbilityByWant({
+ bundleName: info.name,
+ action: "action.system.home",
+ entities: ["entity.system.home"]
+ }, bundle.BundleFlag.GET_ABILITY_INFO_WITH_APPLICATION, Constants.USERID);
+ } catch(e) {
+ console.log(TAG + 'queryAbilityByWant catch error: ' + JSON.stringify(e))
+ continue;
+ }
+
+ if (noNeedDisplayApp.indexOf(info.name) != -1) {
+ continue;
+ }
+ await this.deduplicationPermissions(info, allPermissions, allApplicationPermissions);
+ this.updateAppLabel(infoIndex, info.name, info.appInfo.label);
+ this.updateAppIcon(infoIndex, info.name);
+ infoIndex = infoIndex + 1;
+ }
+ this.getAllPermissionApplications();
+ let orderSort = this.orderDict(userGrantPermissions);
+ this.allPermissionApplications.sort(this.compare('permission', orderSort));
+ this.getAllGroupPermission();
+ bundleInfosList = this.allApplicationPermissions;
+ bundleInfosList.forEach((item) => {
+ if (!isNaN(item.labelId)) {
+ item.alphabeticalIndex = '';
+ } else {
+ item.alphabeticalIndex = makePy(item.labelId)[0].slice(0, 1); // Get the first letter in the returned initials array
+ }
+ })
+ })
+ .catch((error) => {
+ console.error(TAG + 'bundle.getAllBundleInfo failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Get the corresponding permission group id according to the permission
+ * @param {String} permission app name id
+ * @return {Number} groupId
+ */
+ getPermissionGroupByPermission(permission: string) {
+ for (let i = 0; i < permissionGroups.length; i++) {
+ if (permissionGroups[i].permissionName == permission) {
+ return groups[permissionGroups[i].groupId];
+ }
+ }
+ }
+
+ /**
+ * Get all app permission information
+ */
+ getAllPermissionApplications() {
+ const this_ = this;
+ var leng = this_.allPermissions.length;
+ if (leng > 0) {
+ for (let i = 0; i < leng; i++) {
+ if (userGrantPermissions.indexOf(this_.allPermissions[i]) == -1) {
+ this_.allSystemPermissions.push(this_.allPermissions[i]);
+ } else {
+ this_.allUserPermissions.push(this_.allPermissions[i]);
+ }
+ }
+ }
+ for (let i = 0; i < this_.allUserPermissions.length; i++) {
+ var permissionGroup = this_.getPermissionGroupByPermission(this_.allUserPermissions[i]);
+ var icon: string = permissionGroup.icon;
+ var bundleNames: string[] = [];
+ for (let j = 0; j < this_.allApplicationPermissions.length; j++) {
+ if (this_.allApplicationPermissions[j].permissions.indexOf(this_.allUserPermissions[i]) != -1) {
+ bundleNames.push(this_.allApplicationPermissions[j].bundleName);
+ }
+ }
+ var pa: permissionApplications = {
+ 'permission': this_.allUserPermissions[i],
+ 'groupName': permissionGroup.name,
+ 'bundleNames': bundleNames,
+ 'icon': icon
+ };
+ this_.allPermissionApplications.push(pa);
+ }
+ }
+
+ /**
+ * Get permission group information
+ */
+ getAllGroupPermission() {
+ const this_ = this;
+ var temp1 = [];
+ temp1 = ["LOCATION","CAMERA","MICROPHONE","MEDIA","CALENDAR","SPORT","HEALTH"];
+ groups.forEach((item) => {
+ if (temp1.indexOf(item.name) > -1) {
+ var gp: groupPermission = {
+ "group": item.name,
+ "permissions": item.permissions,
+ 'groupName': item.groupName,
+ 'icon': item.icon,
+ 'isShow': item.isShow
+ };
+ this_.allGroupPermission.push(gp);
+ }
+ })
+ let temp2 = [];
+ groups.forEach((item) => {
+ if (item.isShow && temp1.indexOf(item.name) === -1) {
+ var gp: groupPermission = {
+ "group": item.name,
+ "permissions": item.permissions,
+ 'groupName': item.groupName,
+ 'icon': item.icon,
+ 'isShow': item.isShow
+ };
+ temp2.push(item.name);
+ this_.allGroupPermission.push(gp);
+ }
+ })
+ for (let i = 0; i < this_.allPermissionApplications.length; i++) {
+ if (this_.allGroups.indexOf(this_.allPermissionApplications[i].groupName) == -1
+ && temp1.indexOf(this_.allPermissionApplications[i].groupName) == -1) {
+ this_.allGroups.push(this_.allPermissionApplications[i].groupName);
+ }
+ }
+ // Permission layout
+ var temp = this_.allGroups;
+ temp = temp.filter(function(item) {
+ return temp1.indexOf(item) == -1 && temp2.indexOf(item) == -1;
+ });
+ if (temp.indexOf("OTHER") > -1) {
+ temp.splice(temp.indexOf("OTHER"),1);
+ temp.push("OTHER");
+ }else {
+ temp.push("OTHER");
+ }
+ this_.allGroups = temp;
+ for (let i = 0; i < this_.allGroups.length; i++) {
+ var permissions: string[] = permissionGroupPermissions[this_.allGroups[i]];
+ var gp: groupPermission = {
+ "group": this_.allGroups[i],
+ "permissions": permissions,
+ 'groupName': '',
+ 'icon': '',
+ 'isShow': false
+ };
+ this_.allGroupPermission.push(gp);
+ }
+ this.allGroupPermission.forEach((ele) => {
+ groups.forEach((item) => {
+ if (ele.group === item.name) {
+ ele.groupName = item.groupName;
+ ele.icon = item.icon;
+ ele.isShow = item.isShow;
+ }
+ });
+ })
+ }
+
+ /**
+ * Deduplicate permission information and permission group information
+ * @param {Object} info bundleInfos Application Information
+ * @param {Array} allPermissions All permissions
+ * @param {Array} allApplicationPermissions All permissions apply
+ */
+ async deduplicationPermissions(info, allPermissions, allApplicationPermissions) {
+ var reqPermissionsLen = info.reqPermissions.length;
+ var reqUserPermissions: string[] = [];
+ var acManager = abilityAccessCtrl.createAtManager()
+ if (reqPermissionsLen > 0) {
+ for (let j = 0; j < info.reqPermissions.length; j++) {
+ var permission = info.reqPermissions[j];
+ var flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission)
+ if(flag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) {
+ continue
+ }
+ if (allPermissions.indexOf(permission) == -1) {
+ allPermissions.push(permission);
+ }
+ if (userGrantPermissions.indexOf(permission) != -1) {
+ reqUserPermissions.push(permission);
+ }
+ }
+ }
+ let dePermissions = [];
+ let groupIds = [];
+ for (let i = 0; i < reqUserPermissions.length; i++) {
+ if(dePermissions.indexOf(permissionPermissionGroup[reqUserPermissions[i]]) == -1){
+ dePermissions.push(permissionPermissionGroup[reqUserPermissions[i]]);
+ }
+ if(groupIds.indexOf(permissionGroupIds[reqUserPermissions[i]]) == -1){
+ groupIds.push(permissionGroupIds[reqUserPermissions[i]]);
+ }
+ }
+
+ // adapt different api
+ if (info.compatibleVersion >= Constants.API_VERSION_SUPPORT_STAGE) {
+ info.appInfo.iconId = info.hapModuleInfos[0].abilityInfo[0].iconId;
+ }
+
+ var ap: applicationPermissions = {
+ 'bundleName': info.name,
+ 'tokenId': info.appInfo.accessTokenId,
+ 'iconId': info.appInfo.iconId,
+ 'labelId': info.appInfo.labelId,
+ 'permissions': reqUserPermissions,
+ 'groupId': groupIds
+ };
+ allApplicationPermissions.push(ap);
+ }
+
+ /**
+ * Get app name resource
+ * @param {Number} index index of all app permissions array
+ * @param {String} bundleName Package names
+ * @param {String} labelName Application Name
+ */
+ updateAppLabel(index, bundleName, labelName) {
+ Resmgr.getResourceManager(globalThis.context, bundleName).then(item => {
+ if (index >= this.allApplicationPermissions.length) {
+ return;
+ }
+ var info = this.allApplicationPermissions[index];
+ item.getString(info['labelId'], (error, value) => {
+ if (value == undefined) {
+ info['labelId'] = labelName;
+ } else {
+ info['labelId'] = value;
+ }
+ })
+ }).catch(error => {
+ console.error(TAG + 'Resmgr.getResourceManager failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Get app icon resources
+ * @param {Number} index index of all app permissions array
+ * @param {String} bundleName Package names
+ */
+ updateAppIcon(index, bundleName) {
+ Resmgr.getResourceManager(globalThis.context, bundleName).then(item => {
+ if (index >= this.allApplicationPermissions.length) {
+ return;
+ }
+ var info = this.allApplicationPermissions[index];
+ item.getMediaBase64(info['iconId'], (error, value) => {
+ info['iconId'] = value;
+ })
+ }).catch(error => {
+ console.error(TAG + 'Resmgr.getResourceManager failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Lifecycle function, executed when the page is initialized
+ */
+ aboutToAppear() {
+ console.log(TAG + 'on aboutToAppear, version 1.01');
+ this.getAllBundlePermissions(this.allPermissions, this.allApplicationPermissions);
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ item.getString($r("app.string.textInput_placeholder").id, (err, val) => {
+ textInput_placeholder = val
+ })
+ })
+ }
+
+ getPermissionGroup(allGroup, order) {
+ var fixedName: string[] = ['LOCATION', 'CAMERA', 'MICROPHONE']
+ var fixedGroup: any[] = []
+ var changeGroup: any[] = []
+ var otherGroup: any[] = []
+
+ allGroup.forEach(group => {
+ if(fixedName.indexOf(group.group) !== -1) {
+ fixedGroup.push(group)
+ }else if(group.group == 'OTHER') {
+ otherGroup.push(group)
+ }else {
+ changeGroup.push(group)
+ }
+ })
+
+ if(order == Constants.FIXED_GROUP){
+ return fixedGroup
+ }else if(order == Constants.CHANGE_GROUP) {
+ return changeGroup
+ }else if(order == Constants.OTHER_GROUP) {
+ return otherGroup
+ }
+ }
+
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar( { title: JSON.stringify($r('app.string.authority_management')), recordable: true })
+ }
+ Row() {
+ Column() {
+ Column() {
+ Stack() {
+ if(this.allGroupPermission.length) {
+ Tabs() {
+ TabContent() {
+ Row() {
+ Column() {
+ Scroll() {
+ Column() {
+ List() {
+ ListItem() {
+ List() {
+ ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP).slice(Constants.SLICE_START,
+ this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP).length - 1), (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP).slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ .margin({ bottom: Constants.LIST_MARGIN_BOTTOM })
+ }
+
+ ListItem() {
+ List() {
+ ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP).slice(Constants.SLICE_START,
+ this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP).length - 1), (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP).slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ .margin({ bottom: Constants.LIST_MARGIN_BOTTOM })
+ }
+
+ ListItem() {
+ List() {
+ ForEach(this.getPermissionGroup(this.allGroupPermission, Constants.OTHER_GROUP), (item) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }
+ }.height(Constants.FULL_HEIGHT)
+ .borderRadius(Constants.BORDER_RADIUS)
+ .clip(true)
+ }.padding({
+ left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
+ right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
+ })
+ }.scrollBar(BarState.Off)
+ .margin({ top: Constants.MANAGEMENT_ROW_PADDING_TOP })
+ }.width(Constants.FULL_WIDTH)
+ }
+ }.tabBar(this.TabBuilder(0))
+ TabContent() {
+ applicationItem()
+ }.tabBar(this.TabBuilder(1))
+ }
+ .barWidth(Constants.BAR_WIDTH)
+ .barMode(BarMode.Fixed)
+ .onChange((index) => {
+ this.currentIndex = index
+ })
+ }else {
+ LoadingProgress().width(Constants.LOADING_WIDTH)
+ }
+ }.height(Constants.FULL_HEIGHT)
+ }
+ }
+ }
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+}
+
+@Component
+struct applicationItem {
+ @State applicationItem: any[] = bundleInfosList // application info array
+ @State oldApplicationItem: any[] = bundleInfosList // Original application information array
+ @State searchResult: boolean = true // search results
+
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Image(item.iconId)
+ .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
+ .margin({ right: Constants.APPLICATION_IMAGE_MARGIN_RIGHT })
+ Text(item.labelId)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .flexGrow(Constants.FLEX_GROW)
+ Text(item.groupId.length + '项权限')
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_lighter'))
+ .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT })
+ Image($r('app.media.rightarrow'))
+ .customizeImage(Constants.IMAGE_WIDTH, Constants.IMAGE_HEIGHT)
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.AUTHORITY_ROW_HEIGHT)
+ .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
+ }
+ if (!index) {
+ Row() {
+ Flex() {
+ Column().width(Constants.APPLICATION_TEXT_DECORATION_MARGIN_LEFT)
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ .flexGrow(Constants.FLEX_GROW)
+ }
+ }
+ }
+ }.onClick(() => {
+ router.push({
+ uri: 'pages/application-secondary',
+ params: { routerData: item }
+ });
+ })
+ }
+ }.padding({
+ left: Constants.DEFAULT_PADDING_START,
+ right: Constants.DEFAULT_PADDING_END
+ })
+ }
+
+ build() {
+ Column() {
+ Row() {
+ textInput({
+ placeholder: textInput_placeholder,
+ applicationItem: $applicationItem,
+ oldApplicationItem: $oldApplicationItem,
+ searchResult: $searchResult
+ })
+ }.padding({
+ left: Constants.APPLICATION_TEXTINPUT_PADDING_LEFT,
+ top: Constants.APPLICATION_TEXTINPUT_PADDING_TOP,
+ right: Constants.APPLICATION_TEXTINPUT_PADDING_RIGHT
+ })
+ Row() {
+ Flex({ alignItems: ItemAlign.Start }) {
+ Column() {
+ Column() {
+ if (!this.applicationItem.length) {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
+ Image($r('app.media.searchnoresult'))
+ .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
+ }
+ }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP })
+ .padding({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT })
+ } else {
+ Row() {
+ Scroll() {
+ List() {
+ ForEach(this.applicationItem.slice(Constants.SLICE_START, this.applicationItem.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.applicationItem.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.scrollBar(BarState.Off)
+ }.margin({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT })
+ .borderRadius(Constants.BORDER_RADIUS)
+ .clip(true)
+ }
+ }.backgroundColor($r('app.color.background_color'))
+ .height(Constants.FULL_HEIGHT)
+ }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP, bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM })
+ Column() {
+ alphabetIndexerComponent({ applicationItem: $applicationItem, oldApplicationItem: $oldApplicationItem })
+ }.margin({ top: Constants.APPLICATION_ALPHABETINDEX_MARGIN_TOP })
+ .width(Constants.APPLICATION_ALPHABETINDEX_WIDTH)
+ }
+ }
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/authority-secondary.ets b/permissionmanager/src/main/ets/pages/authority-secondary.ets
new file mode 100644
index 0000000..21480ad
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/authority-secondary.ets
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import { permissionGroups, groups } from "../common/model/permissionGroup";
+import router from '@system.router';
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+class CalendarObj {
+ permissionName: string
+ groupName: string
+ description: string
+ label: string
+ index: number
+ constructor(permissionName: string, groupName: string, description: string, label: string, index: number) {
+ this.permissionName = permissionName
+ this.groupName = groupName
+ this.description = description
+ this.label = label
+ this.index = index
+ }
+} // Permission management secondary interface data class
+
+@Entry
+@Component
+struct appNamePage {
+ private backTitle = router.getParams().backTitle; // return title name
+
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(this.backTitle), recordable: false })
+ }
+ Row() {
+ Column() {
+ Scroll() {
+ appNameItem()
+ }
+ }
+ }.layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+}
+
+@Component
+struct appNameItem {
+ @State calendarListItem: CalendarObj[] = []; // Permission management secondary interface data array
+ private routerData = router.getParams().routerData; // Routing jump data
+ private backTitle = router.getParams().backTitle; // return title name
+ private allPermissionApplications = router.getParams().allPermissionApplications; // Array of all app permission names
+
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Text(item.label)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.label_color'))
+ .fontWeight(FontWeight.Medium)
+ .flexGrow(Constants.FLEX_GROW)
+ Image($r('app.media.rightarrow'))
+ .objectFit(ImageFit.Contain)
+ .height(Constants.IMAGE_HEIGHT)
+ .width(Constants.IMAGE_WIDTH)
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.LISTITEM_ROW_HEIGHT)
+ }
+ if (!index) {
+ Row() {
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ }
+ }
+ }.onClick(() => {
+ var dataList = this.routerData.filter((ele) => {
+ return ele.groupName === item.groupName;
+ })
+ router.push({
+ uri: 'pages/authority-tertiary',
+ params: { routerData: [dataList[item.index]], backTitle: item.label }
+ });
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ /**
+ * Lifecycle function, executed when the page is initialized
+ */
+ aboutToAppear() {
+ var permissionsList = groups.filter((item) => {
+ return item.groupName === this.backTitle
+ })
+ for (let i = 0; i < permissionsList[0].permissions.length; i++) {
+ permissionGroups.forEach((item) => {
+ if (item.permissionName === permissionsList[0].permissions[i]) {
+ this.calendarListItem.push(
+ new CalendarObj(item.permissionName, item.groupName, item.description, item.label, i)
+ )
+ }
+ })
+ }
+ }
+
+ build() {
+ Row() {
+ Column() {
+ Row() {
+ List() {
+ ForEach(this.calendarListItem.slice(Constants.SLICE_START, this.calendarListItem.length - 1), (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.calendarListItem.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color')).borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.ROW_MARGIN_TOP })
+ .padding({ left: Constants.LIST_PADDING_LEFT, right: Constants.LISTITEM_PADDING_RIGHT })
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.FULL_HEIGHT)
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/authority-tertiary-groups.ets b/permissionmanager/src/main/ets/pages/authority-tertiary-groups.ets
new file mode 100644
index 0000000..44cd922
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/authority-tertiary-groups.ets
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import { alphabetIndexerComponent } from "../common/components/alphabeticalIndex";
+import { textInput } from "../common/components/search";
+import router from '@system.router';
+import bundle from "@ohos.bundle";
+import Resmgr from '@ohos.resourceManager';
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import { getAppLabel, getAppIcon, verifyAccessToken} from "../common/utils/utils";
+import { makePy } from "../common/utils/utils";
+import { authorizeDialog } from "../common/components/dialog";
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+@Extend(Image) function customizeImage(width: number, height: number) {
+ .objectFit(ImageFit.Contain)
+ .width(width)
+ .height(height)
+}
+
+let routerData = router.getParams().routerData; // Routing jump data
+let backTitle = router.getParams().backTitle; // return title name
+let nowGrantResult = Constants.PERMISSION_NUM; // Authorization results now
+let nowRevokeResult = Constants.PERMISSION_NUM; // Now deauthorize results
+let GrantResultFlag = []; // Authorization result Flag
+let RevokeResultFlag = []; // Cancel authorization result Flag
+
+class ApplicationObj {
+ labelId: string
+ iconId: string
+ index: number
+ accessTokenId: number
+ permission: string
+ alphabeticalIndex: string
+ constructor(
+ labelId: string,
+ iconId: string,
+ index: number,
+ accessTokenId: number,
+ permission: string,
+ alphabeticalIndex: string) {
+ this.labelId = labelId
+ this.iconId = iconId
+ this.index = index
+ this.accessTokenId = accessTokenId
+ this.permission = permission
+ this.alphabeticalIndex = alphabeticalIndex
+ }
+} // application information
+
+@Entry
+@Component
+struct locationInfoPage {
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(backTitle), recordable: false })
+ }
+ Row() {
+ Column() {
+ applicationItem()
+
+ }.width(Constants.FULL_WIDTH)
+ }
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+}
+
+@Component
+struct applicationItem {
+ @State permissionNum: number = Constants.PERMISSION_NUM; // permission num
+ @State toggleIsOn: object = {}; // toggle switch state array
+ @State applicationList: ApplicationObj[] = []; // application info array
+ @State oldApplicationItem: ApplicationObj[] = []; // Original application information array
+ @State searchResult: boolean = true; // search results
+ @State placeholder: string = ''
+
+ authorizeDialogController: CustomDialogController = new CustomDialogController({
+ builder: authorizeDialog({ }),
+ autoCancel: true,
+ alignment: DialogAlignment.Center
+ });
+
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Image(item.iconId)
+ .customizeImage(Constants.AUTHORITY_IMAGE_WIDTH, Constants.AUTHORITY_IMAGE_HEIGHT)
+ .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT })
+ Text(item.labelId)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.text_color'))
+ .flexGrow(Constants.FLEX_GROW)
+ Toggle({ type: ToggleType.Switch, isOn: this.toggleIsOn[item.index] })
+ .selectedColor($r('app.color.toggle_color'))
+ .width(Constants.AUTHORITY_TOGGLE_WIDTH)
+ .height(Constants.AUTHORITY_TOGGLE_HEIGHT)
+ .onChange((isOn: boolean) => {
+ if (item.accessTokenId === '' || item.permission === '') {
+ return;
+ }
+ let _this = this;
+ if (isOn) {
+ let promises = routerData.map(it => new Promise((resolve, reject) => {
+ _this.grantUserGrantedPermission(item.accessTokenId, it.permission, item.index, resolve);
+ }));
+ Promise.all(promises).then(function(results) {
+ if(results.indexOf(-1) != -1) {
+ _this.authorizeDialogController.open();
+ _this.toggleIsOn[item.index] = false;
+ setTimeout(()=> {
+ _this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ } else {
+ _this.toggleIsOn[item.index] = true;
+ }
+ let num = Constants.PERMISSION_NUM;
+ for(let key in _this.toggleIsOn){
+ if(_this.toggleIsOn[key]){
+ num++;
+ }
+ }
+ _this.permissionNum = num;
+ });
+ } else {
+ let promises = routerData.map(it => new Promise((resolve, reject) => {
+ _this.revokeUserGrantedPermission(item.accessTokenId, it.permission, item.index, resolve);
+ }));
+ Promise.all(promises).then(function(results) {
+ if(results.indexOf(-1) != -1) {
+ _this.authorizeDialogController.open();
+ _this.toggleIsOn[item.index] = true;
+ setTimeout(()=> {
+ _this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ } else {
+ _this.toggleIsOn[item.index] = false;
+ }
+ let num = Constants.PERMISSION_NUM;
+ for(let key in _this.toggleIsOn){
+ if(_this.toggleIsOn[key]){
+ num++;
+ }
+ }
+ _this.permissionNum = num;
+ });
+ }
+ })
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.AUTHORITY_ROW_HEIGHT)
+ .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
+ }
+ if (!index) {
+ Row() {
+ Flex() {
+ Column().width(Constants.APPLICATION_TEXT_DECORATION_MARGIN_LEFT)
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ .flexGrow(Constants.FLEX_GROW)
+ }
+ }
+ }
+ }.onClick(() => {
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ /**
+ * Grant permissions to the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ * @param {Number} index Array index to modify permission status
+ */
+ grantUserGrantedPermission(accessTokenId, permission, index, resolve) {
+ abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then(result => {
+ // result: 0 Authorization succeeded; result: -1 Authorization failed
+ resolve(result);
+ }).catch(error => {
+ resolve(-1);
+ console.error(TAG + 'abilityAccessCtrl.createAtManager.grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Deauthorize the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ * @param {Number} index Array index to modify permission status
+ */
+ revokeUserGrantedPermission(accessTokenId, permission, index, resolve) {
+ abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then(result => {
+ // result: 0 successfully cancel the authorization; result: -1 cancel the authorization failed
+ resolve(result);
+ }).catch(error => {
+ resolve(-1);
+ console.error(TAG + 'abilityAccessCtrl.createAtManager.revokeUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Lifecycle function, executed when the page is initialized
+ */
+ aboutToAppear() {
+ var bundleNames = []
+ routerData.forEach(permissionmanager => {
+ permissionmanager.bundleNames.forEach( bundleName => {
+ if (bundleNames.indexOf(bundleName) == -1) {
+ bundleNames.push(bundleName)
+ }
+ })
+ })
+
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ item.getString($r("app.string.textInput_placeholder").id, (err, val) => {
+ this.placeholder = val
+ })
+ })
+
+ // initial then fill values when sync return which may cause sync panic
+ for (let i = 0; i < bundleNames.length; i++) {
+ this.applicationList.push(
+ new ApplicationObj('', '', i, 0, '', ''));
+ this.oldApplicationItem.push(
+ new ApplicationObj('', '', i, 0, '', ''));
+ }
+
+ for (let i = 0; i < bundleNames.length; i++) {
+ // Get BundleInfo based on bundle name
+ bundle.getBundleInfo(bundleNames[i], Constants.PARMETER_BUNDLE_FLAG).then(res => {
+ Promise.all([getAppLabel(res.appInfo.labelId, res.name),
+ getAppIcon(res.appInfo.iconId, res.name)
+ ])
+ .then((values) => {
+ this.applicationList[i] = (
+ new ApplicationObj(
+ String(values[0]),
+ String(values[1]),
+ i,
+ res.appInfo.accessTokenId,
+ routerData[0].permission,
+ makePy(values[0])[0].slice(0, 1)) // Get the first letter in the returned initials array
+ );
+ this.oldApplicationItem[i] = (
+ new ApplicationObj(
+ String(values[0]),
+ String(values[1]),
+ i,
+ res.appInfo.accessTokenId,
+ routerData[0].permission,
+ makePy(values[0])[0].slice(0, 1)) // Get the first letter in the returned initials array
+ );
+ });
+ // 0: have permission; -1: no permission
+ var boole = true;
+ this.permissionNum++;
+ for (let j = 0; j < routerData.length; j++) {
+ if (res.reqPermissions.indexOf(routerData[j].permission) == -1) {
+ continue
+ }
+ verifyAccessToken(res.appInfo.accessTokenId, routerData[j].permission).then((access) => {
+ if (Number(access) === Constants.PERMISSION_INDEX) {
+ if(boole){
+ this.toggleIsOn[i] = true;
+ }
+ } else {
+ if(boole){
+ this.permissionNum--
+ }
+ boole = false;
+ this.toggleIsOn[i] = false;
+ }
+ });
+ }
+ }).catch(error => {
+ console.log(TAG + bundleNames[i] + "getBundleInfo failed, cause: " + JSON.stringify(error));
+ })
+ }
+ }
+
+ build() {
+ Column() {
+ Row() {
+ textInput({
+ placeholder: this.placeholder,
+ applicationItem: $applicationList,
+ oldApplicationItem: $oldApplicationItem,
+ searchResult: $searchResult
+ })
+ }.padding({
+ left: Constants.AUTHORITY_TEXTINPUT_PADDING_LEFT,
+ right: Constants.AUTHORITY_TEXTINPUT_PADDING_RIGHT
+ })
+ Row() {
+ Flex({ alignItems:ItemAlign.Start, justifyContent: FlexAlign.Start }) {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start }) {
+ Text(this.permissionNum + '个应用获取此权限')
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.secondary_font_color'))
+ .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP, left: Constants.AUTHORITY_TEXT_MARGIN_LEFT })
+ }
+ Scroll() {
+ Row() {
+ Column() {
+ if (!this.applicationList.length) {
+ if (this.searchResult) {
+ Row() {
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ } else {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
+ Image($r('app.media.searchnoresult'))
+ .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
+ }
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ }
+ } else {
+ Row() {
+ List() {
+ ForEach(this.applicationList.slice(Constants.SLICE_START, this.applicationList.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.applicationList.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ }
+ }.width(Constants.FULL_WIDTH)
+ .height(Constants.AUTHORITY_COLUMN_HEIGHT)
+ }
+ }
+ }.padding({ left: Constants.AUTHORITY_LISTITEM_PADDING_LEFT })
+ Column() {
+ alphabetIndexerComponent({ applicationItem: $applicationList, oldApplicationItem: $oldApplicationItem })
+ }.width(Constants.AUTHORITY_ALPHABETINDEX_WIDTH)
+ .padding({ top: Constants.AUTHORITY_ALPHABETINDEX_PADDING_TOP })
+ }
+ }
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/authority-tertiary.ets b/permissionmanager/src/main/ets/pages/authority-tertiary.ets
new file mode 100644
index 0000000..040934f
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/authority-tertiary.ets
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import { alphabetIndexerComponent } from "../common/components/alphabeticalIndex";
+import { textInput } from "../common/components/search";
+import router from '@system.router';
+import bundle from "@ohos.bundle";
+import Resmgr from '@ohos.resourceManager';
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import { getAppLabel, getAppIcon, verifyAccessToken } from "../common/utils/utils";
+import { makePy } from "../common/utils/utils";
+import { authorizeDialog } from "../common/components/dialog";
+import Constants from '../common/utils/constant';
+
+var TAG = 'PermissionManager_MainAbility:'
+
+@Extend(Image) function customizeImage(width: number, height: number) {
+ .objectFit(ImageFit.Contain)
+ .width(width)
+ .height(height)
+}
+
+let routerData = router.getParams().routerData; // Routing jump data
+let backTitle = router.getParams().backTitle; // return title name
+class ApplicationObj {
+ labelId: string
+ iconId: string
+ index: number
+ accessTokenId: number
+ permission: string
+ alphabeticalIndex: string
+ constructor(
+ labelId: string,
+ iconId: string,
+ index: number,
+ accessTokenId: number,
+ permission: string,
+ alphabeticalIndex: string) {
+ this.labelId = labelId
+ this.iconId = iconId
+ this.index = index
+ this.accessTokenId = accessTokenId
+ this.permission = permission
+ this.alphabeticalIndex = alphabeticalIndex
+ }
+} // application information
+
+@Entry
+@Component
+struct locationInfoPage {
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(backTitle), recordable: false })
+ }
+ Row() {
+ Column() {
+ applicationItem()
+
+ }.width(Constants.FULL_WIDTH)
+ }
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+}
+
+@Component
+struct applicationItem {
+ @State permissionNum: number = Constants.PERMISSION_NUM; // permission num
+ @State toggleIsOn: object = {}; // toggle switch state array
+ @State applicationList: ApplicationObj[] = []; // application info array
+ @State oldApplicationItem: ApplicationObj[] = []; // Original application information array
+ @State searchResult: boolean = true; // search results
+ @State placeholder: string = ''
+
+ authorizeDialogController: CustomDialogController = new CustomDialogController({
+ builder: authorizeDialog({ }),
+ autoCancel: true,
+ alignment: DialogAlignment.Center
+ });
+
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Image(item.iconId)
+ .customizeImage(Constants.AUTHORITY_IMAGE_WIDTH, Constants.AUTHORITY_IMAGE_HEIGHT)
+ .margin({ right: Constants.AUTHORITY_IMAGE_MARGIN_RIGHT })
+ Text(item.labelId)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .flexGrow(Constants.FLEX_GROW)
+ Toggle({ type: ToggleType.Switch, isOn: this.toggleIsOn[item.index] })
+ .selectedColor($r('app.color.toggle_color'))
+ .width(Constants.AUTHORITY_TOGGLE_WIDTH)
+ .height(Constants.AUTHORITY_TOGGLE_HEIGHT)
+ .onChange((isOn: boolean) => {
+ if (item.accessTokenId === '' || item.permission === '') {
+ return;
+ }
+ if (isOn) {
+ this.grantUserGrantedPermission(item.accessTokenId, item.permission, item.index);
+ } else {
+ this.revokeUserGrantedPermission(item.accessTokenId, item.permission, item.index);
+ }
+ })
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.AUTHORITY_ROW_HEIGHT)
+ .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
+ }
+ if (!index) {
+ Row() {
+ Flex() {
+ Column().width(Constants.APPLICATION_TEXT_DECORATION_MARGIN_LEFT)
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ .flexGrow(Constants.FLEX_GROW)
+ }
+ }
+ }
+ }.onClick(() => {
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ /**
+ * Grant permissions to the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ * @param {Number} index Array index to modify permission status
+ */
+ grantUserGrantedPermission(accessTokenId, permission, index) {
+ abilityAccessCtrl.createAtManager().grantUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then(result => {
+ // result: 0 Authorization succeeded; result: -1 Authorization failed
+ if (result !== Constants.PERMISSION_INDEX) {
+ this.authorizeDialogController.open();
+ this.toggleIsOn[index] = false;
+ setTimeout(()=> {
+ this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ } else {
+ this.toggleIsOn[index] = true;
+ }
+ let num = Constants.PERMISSION_NUM;
+ for(let key in this.toggleIsOn){
+ if(this.toggleIsOn[key]){
+ num++;
+ }
+ }
+ this.permissionNum = num;
+ }).catch(error => {
+ console.error(TAG + 'abilityAccessCtrl.createAtManager.grantUserGrantedPermission failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ /**
+ * Deauthorize the app
+ * @param {Number} accessTokenId
+ * @param {String} permission permission name
+ * @param {Number} index Array index to modify permission status
+ */
+ revokeUserGrantedPermission(accessTokenId, permission, index) {
+ abilityAccessCtrl.createAtManager().revokeUserGrantedPermission(
+ accessTokenId, permission, Constants.PERMISSION_FLAG).then(result => {
+ // result: 0 successfully cancel the authorization; result: -1 cancel the authorization failed
+ if (result !== Constants.PERMISSION_INDEX) {
+ this.authorizeDialogController.open();
+ this.toggleIsOn[index] = true;
+ setTimeout(()=> {
+ this.authorizeDialogController.close();
+ }, Constants.DELAY_TIME)
+ } else {
+ this.toggleIsOn[index] = false;
+ }
+ let num = Constants.PERMISSION_NUM;
+ for(let key in this.toggleIsOn){
+ if(this.toggleIsOn[key]){
+ num++;
+ }
+ }
+ this.permissionNum = num;
+ })
+ }
+
+ /**
+ * Lifecycle function, executed when the page is initialized
+ */
+ aboutToAppear() {
+ let bundleNames = routerData[0].bundleNames;
+
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ item.getString($r("app.string.textInput_placeholder").id, (err, val) => {
+ this.placeholder = val
+ })
+ })
+
+ // initial then fill values when sync return which may cause sync panic
+ for (let i = 0; i < bundleNames.length; i++) {
+ this.applicationList.push(
+ new ApplicationObj('', '', i, 0, '', ''));
+ this.oldApplicationItem.push(
+ new ApplicationObj('', '', i, 0, '', ''));
+ }
+
+ for (let i = 0; i < bundleNames.length; i++) {
+ // Get BundleInfo based on bundle name
+ bundle.getBundleInfo(bundleNames[i], Constants.PARMETER_BUNDLE_FLAG).then(res => {
+ Promise.all([getAppLabel(res.appInfo.labelId, res.name),
+ getAppIcon(res.appInfo.iconId, res.name),
+ verifyAccessToken(res.appInfo.accessTokenId, routerData[0].permission)])
+ .then((values) => {
+ this.applicationList[i] = (
+ new ApplicationObj(
+ String(values[0]),
+ String(values[1]),
+ i,
+ res.appInfo.accessTokenId,
+ routerData[0].permission,
+ makePy(values[0])[0].slice(0, 1)) // Get the first letter in the returned initials array
+ );
+ this.oldApplicationItem[i] = (
+ new ApplicationObj(
+ String(values[0]),
+ String(values[1]),
+ i,
+ res.appInfo.accessTokenId,
+ routerData[0].permission,
+ makePy(values[0])[0].slice(0, 1)) // Get the first letter in the returned initials array
+ );
+ // 0: have permission; -1: no permission
+ if (values[2] === Constants.PERMISSION_INDEX) {
+ this.toggleIsOn[i] = true;
+ this.permissionNum++;
+ } else {
+ this.toggleIsOn[i] = false;
+ }
+ });
+ }).catch(error => {
+ console.log(TAG + bundleNames[i] + "getBundleInfo failed, cause: " + JSON.stringify(error));
+ })
+ }
+ }
+
+ build() {
+ Column() {
+ Row() {
+ textInput({
+ placeholder: this.placeholder,
+ applicationItem: $applicationList,
+ oldApplicationItem: $oldApplicationItem,
+ searchResult: $searchResult
+ })
+ }.padding({
+ left: Constants.AUTHORITY_TEXTINPUT_PADDING_LEFT,
+ right: Constants.AUTHORITY_TEXTINPUT_PADDING_RIGHT
+ })
+ Row() {
+ Flex({ alignItems:ItemAlign.Start, justifyContent: FlexAlign.Start }) {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start }) {
+ Text(this.permissionNum + '个应用获取此权限')
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.secondary_font_color'))
+ .margin({ top: Constants.AUTHORITY_TEXT_MARGIN_TOP, left: Constants.AUTHORITY_TEXT_MARGIN_LEFT })
+ }
+ Scroll() {
+ Row() {
+ Column() {
+ if (!this.applicationList.length) {
+ if (this.searchResult) {
+ Row() {
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ } else {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
+ Image($r('app.media.searchnoresult'))
+ .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
+ }
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ }
+ } else {
+ Row() {
+ List() {
+ ForEach(this.applicationList.slice(Constants.SLICE_START, this.applicationList.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.applicationList.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.AUTHORITY_ROW_MARGIN_TOP })
+ }
+ }.width(Constants.FULL_WIDTH)
+ .height(Constants.AUTHORITY_COLUMN_HEIGHT)
+ }
+ }
+ }.padding({ left: Constants.AUTHORITY_LISTITEM_PADDING_LEFT })
+ Column() {
+ alphabetIndexerComponent({ applicationItem: $applicationList, oldApplicationItem: $oldApplicationItem })
+ }.width(Constants.AUTHORITY_ALPHABETINDEX_WIDTH)
+ .padding({ top: Constants.AUTHORITY_ALPHABETINDEX_PADDING_TOP })
+ }
+ }
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/dialogPlus.ets b/permissionmanager/src/main/ets/pages/dialogPlus.ets
new file mode 100644
index 0000000..a56068a
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/dialogPlus.ets
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import bundle from '@ohos.bundle';
+import Resmgr from '@ohos.resourceManager'
+import rpc from '@ohos.rpc';
+import { Log, getPermissionGroup } from '../common/utils/utils'
+import Constants from '../common/utils/constant'
+import { BundleFlag } from '../common/model/bundle'
+import { permissionGroups, showSubpermissionsGrop } from '../common/model/permissionGroup'
+
+@Extend(Button) function customizeButton() {
+ .backgroundColor($r('app.color.default_background_color'))
+ .fontColor($r('app.color.button_color'))
+ .fontWeight(FontWeight.Medium)
+ .height(Constants.BUTTON_HEIGHT)
+ .width(Constants.BUTTON_WIDTH)
+}
+
+@Entry
+@Component
+struct dialogPlusPage {
+ @State count: number = 0
+ @State result: Array = []
+ @State accessTokenId: number = 0
+ @State initStatus: number = Constants.INIT_NEED_TO_WAIT
+ @State reqPerms: Array = []
+ @State grantGroups: Array = []
+ @State userFixedFlag: number = 2 // means user fixed
+ @State appName: string = ""
+ @State win: any = ""
+ @State proxy: any = ''
+
+ build() {
+ Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
+ Column() {
+ if ((this.initStatus != Constants.INIT_NEED_TO_WAIT) && this.verify()) {
+ Image(this.grantGroups[this.count].icon)
+ .width(Constants.DIALOG_ICON_WIDTH)
+ .height(Constants.DIALOG_ICON_HEIGHT)
+ .fillColor($r("app.color.first_font_color"))
+ .margin({
+ top: Constants.DIALOG_ICON_MARGIN_TOP
+ })
+ Text(`${this.count + 1} / ${this.grantGroups.length}`)
+ .fontSize(Constants.DIALOG_LABEL_FONT_SIZE)
+ .fontColor($r('app.color.text_secondary_color'))
+ .lineHeight(Constants.DIALOG_LABEL_LINE_HEIGHT)
+ .margin({
+ top: Constants.DIALOG_LABEL_MARGIN_TOP
+ })
+ Column() {
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start }) {
+ Text("是否允许" + this.appName +
+ this.grantGroups[this.count].label)
+ .fontSize(Constants.DIALOG_REQ_FONT_SIZE)
+ .fontColor($r('app.color.first_font_color'))
+ .fontWeight(FontWeight.Medium)
+ .fontSize(Constants.DIALOG_REQ_FONT_SIZE)
+ .lineHeight(Constants.DIALOG_REQ_LINE_HEIGHT)
+ .margin({
+ top: Constants.DIALOG_REQ_MARGIN_TOP,
+ left: Constants.DIALOG_REQ_MARGIN_LEFT
+ })
+ }
+ }
+
+ Row() {
+ Flex({ justifyContent: FlexAlign.Start }) {
+ Text(this.grantGroups[this.count].description)
+ .fontSize(Constants.DIALOG_DESP_FONT_SIZE)
+ .fontColor($r('app.color.text_secondary_color'))
+ .fontSize(Constants.DIALOG_DESP_FONT_SIZE)
+ .lineHeight(Constants.DIALOG_DESP_LINE_HEIGHT)
+ .margin({
+ top: Constants.DIALOG_DESP_MARGIN_TOP,
+ left: Constants.DIALOG_DESP_MARGIN_LEFT,
+ right: Constants.DIALOG_DESP_MARGIN_RIGHT,
+ bottom: Constants.DIALOG_DESP_MARGIN_BOTTOM
+ })
+ }
+ }
+ }
+ }
+ Row() {
+ Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
+ Button('禁止')
+ .fontSize(Constants.BUTTON_FONT_SIZE)
+ .onClick(() => {
+ this.privacyCancel(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag)
+ }).customizeButton().margin({ left: Constants.BUTTON_MARGIN_LEFT })
+ Text('|').fontSize(Constants.BUTTON_DIVIDER_FONT_SIZE).fontColor($r('app.color.divider_color'))
+ Button('允许')
+ .fontSize(Constants.BUTTON_FONT_SIZE)
+ .onClick(() => {
+ this.privacyAccept(this.grantGroups[this.count], this.accessTokenId, this.reqPerms, this.userFixedFlag)
+ }).customizeButton().margin({ right: Constants.BUTTON_MARGIN_RIGHT })
+ }
+ }
+ }
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.DIALOG_PRIVACY_BORDER_RADIUS)
+ .width(Constants.DIALOG_PRIVACY_WIDTH)
+ .padding({ bottom: Constants.DIALOG_PADDING_BOTTOM })
+ }.width(Constants.FULL_WIDTH)
+ .height(Constants.FULL_HEIGHT)
+ }
+
+ verify() {
+ if((this.initStatus == Constants.INIT_NEED_TO_TERMINATED) || (this.count >= this.grantGroups.length)) {
+ this.answerRequest()
+ this.initStatus = Constants.INIT_NEED_TO_WAIT
+ return false
+ }
+ return true
+ }
+
+ answerRequest() {
+ var ret: number = Constants.RESULT_SUCCESS
+ if (this.initStatus == Constants.INIT_NEED_TO_TERMINATED) {
+ ret = Constants.RESULT_FAILURE
+ }
+ this.answer(ret, this.reqPerms)
+ }
+
+ answer(ret, reqPerms) {
+ Log.info("code:" + ret + ", perms="+ JSON.stringify(reqPerms) +", result=" + JSON.stringify(this.result))
+ var perms = []
+ var results = []
+ reqPerms.forEach(perm => {
+ perms.push(perm)
+ })
+ this.result.forEach(result => {
+ results.push(result)
+ })
+ let option = new rpc.MessageOption()
+ let data = new rpc.MessageParcel()
+ let reply = new rpc.MessageParcel()
+ Promise.all([data.writeInterfaceToken(Constants.ACCESS_TOKEN),
+ data.writeStringArray(perms),
+ data.writeIntArray(results)
+ ]).then(() => {
+ this.proxy.sendRequest(Constants.RESULT_CODE, data, reply, option)
+ this.destruction()
+ }).catch(() => {
+ Log.error('write result failed!')
+ this.destruction()
+ })
+ }
+
+ destruction() {
+ this.win.destroy()
+ globalThis.windowNum --
+ Log.info("windowNum:" + globalThis.windowNum)
+ if(globalThis.windowNum == 0) {
+ globalThis.extensionContext.terminateSelf()
+ }
+ }
+
+ async privacyAccept(group, accessTokenId, permissionList, userFixedFlag) {
+ var acManager = abilityAccessCtrl.createAtManager()
+ var num = 0
+ group.permissions.forEach(async permission => {
+ let result
+ if(showSubpermissionsGrop.indexOf(group.groupName) == -1) {
+ result = await acManager.grantUserGrantedPermission(accessTokenId, permission, userFixedFlag)
+ }else {
+ if(permissionList.includes(permission)) {
+ result = await acManager.grantUserGrantedPermission(accessTokenId, permission, userFixedFlag)
+ }
+ }
+ num ++
+ Log.info("grant permission result:" + result + "permission" + permission)
+ if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
+ permissionList.forEach((req, idx) => {
+ if(req == permission) {
+ this.result[idx] = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
+ }
+ })
+ Log.info("grant permission success:" + permission)
+ } else {
+ Log.error("failed to grant permission:" + permission + " ret:" + result)
+ }
+ if(num == group.permissions.length) {
+ this.count ++
+ }
+ })
+ }
+
+ async privacyCancel(group, accessTokenId, permissionList, userFixedFlag) {
+ var acManager = abilityAccessCtrl.createAtManager()
+ group.permissions.forEach(async permission => {
+ let result
+ if(showSubpermissionsGrop.indexOf(group.groupName) == -1) {
+ result = await acManager.revokeUserGrantedPermission(accessTokenId, permission, userFixedFlag)
+ }else {
+ if(permissionList.includes(permission)) {
+ result = await acManager.revokeUserGrantedPermission(accessTokenId, permission, userFixedFlag)
+ }
+ }
+ Log.info("revoke permission result:" + result + "permission" + permission);
+ })
+ this.count ++
+ }
+
+ getgrantGroups(stateGroup) {
+ this.reqPerms.forEach((permission, idx) => {
+ //已授权
+ if(stateGroup[idx] == Constants.PASS_OPER) {
+ Log.info("permission has been fixed:" + permission)
+ this.result[idx] = abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
+ //待授权
+ }else if(stateGroup[idx] == Constants.DYNAMIC_OPER) {
+ var group = getPermissionGroup(permission)
+ if(!group) {
+ Log.info("permission not find:" + permission)
+ }else {
+ var exist = this.grantGroups.find(grantGroup => grantGroup.name == group.name)
+ //判断是否为需要展示子权限的权限组
+ if(showSubpermissionsGrop.indexOf(group.groupName) != -1) {
+ var permissionDetail
+ permissionGroups.forEach(permissionGroup => {
+ if(permissionGroup.permissionName == permission) {
+ //获取授权的权限信息
+ permissionDetail = permissionGroup
+ }
+ })
+ //权限组已存在的情况
+ if(!exist) {
+ group.description = [permissionDetail.label]
+ this.grantGroups.push(group)
+ }else {
+ if(exist.description.indexOf(permissionDetail.label) == -1) {
+ exist.description.push(permissionDetail.label)
+ }
+ }
+ }else {
+ if(!exist) {
+ this.grantGroups.push(group)
+ }
+ }
+ }
+ }
+ })
+ this.initStatus = Constants.INIT_NEED_TO_VERIFY
+ }
+
+ getApplicationName(uid) {
+ bundle.getNameForUid(uid).then((data) => {
+ Log.info("getApplicationName bundleName:" + data)
+ Log.info("getApplicationName userId:" + Math.floor(uid/200000))
+ bundle.getApplicationInfo(data, BundleFlag.GET_BUNDLE_DEFAULT, Math.floor(uid/200000)).then(applicationInfo => {
+ Resmgr.getResourceManager(globalThis.extensionContext, data).then(item => {
+ item.getString(applicationInfo.labelId, (err, value) => {
+ if (value == undefined) {
+ this.appName = applicationInfo.label
+ } else {
+ this.appName = value
+ }
+ Log.info("hap label:" + applicationInfo.label + ", value:"+this.appName)
+ })
+ })
+ }).catch(err => {
+ Log.error("applicationInfo error :" + err)
+ this.initStatus = Constants.INIT_NEED_TO_TERMINATED
+ })
+ bundle.getBundleInfo(data, Constants.PARMETER_BUNDLE_FLAG).then(bundleInfo => {
+ this.grantGroups.forEach((group, idx) => {
+ if(group.description) {
+ Resmgr.getResourceManager(globalThis.extensionContext, Constants.BUNDLE_NAME).then(item => {
+ Promise.all([item.getString($r("app.string.separator").id),
+ item.getString($r("app.string.reason_suffix").id)])
+ .then(values => {
+ group.description = group.description.join(values[0])
+ group.description += values[1]
+ this.getReason(group, bundleInfo, data)
+ })
+ })
+ }else {
+ this.getReason(group, bundleInfo, data)
+ }
+ })
+ })
+ }).catch(err => {
+ Log.error("getNameForUid error :" + JSON.stringify(err))
+ this.initStatus = Constants.INIT_NEED_TO_TERMINATED
+ })
+ }
+
+ getReason(group, bundleInfo, bundleName) {
+ group.permissions.forEach(permission => {
+ if(this.reqPerms.indexOf(permission) != -1) {
+ bundleInfo.reqPermissionDetails.forEach(reqPermissionDetail => {
+ if(reqPermissionDetail.name == permission) {
+ Resmgr.getResourceManager(globalThis.extensionContext, bundleName).then(item => {
+ item.getString(reqPermissionDetail.reasonId, (err, value) => {
+ this.initStatus = Constants.INIT_NEED_TO_REFRESH
+ if (value !== undefined && !group.hasReason) {
+ group.description += value.slice(Constants.START_SUBSCRIPT, Constants.END_SUBSCRIPT)
+ group.hasReason = true
+ }
+ })
+ })
+ }
+ })
+ }
+ })
+ }
+
+ aboutToAppear() {
+ this.count = 0;
+ this.initStatus = Constants.INIT_NEED_TO_WAIT
+ this.result = []
+ this.reqPerms = globalThis.abilityWant.parameters['ohos.user.grant.permission']
+ this.accessTokenId = globalThis.abilityWant.parameters['ohos.aafwk.param.callerToken']
+ this.proxy = globalThis.abilityWant.parameters['ohos.ability.params.callback'].value
+ this.win = globalThis.extensionWin
+ if (this.reqPerms == undefined || this.accessTokenId == undefined || this.reqPerms.length == 0) {
+ Log.info("invalid parameters")
+ this.initStatus = Constants.INIT_NEED_TO_TERMINATED
+ return
+ }
+ Log.info("request permission=" + JSON.stringify(this.reqPerms) + ", tokenId = " + this.accessTokenId)
+ Log.info("permission state=" + JSON.stringify(globalThis.abilityWant.parameters['ohos.user.grant.permission.state']));
+ this.result = new Array(this.reqPerms.length).fill(-1);
+ this.getgrantGroups(globalThis.abilityWant.parameters['ohos.user.grant.permission.state']);
+ this.getApplicationName(globalThis.abilityWant.parameters['ohos.aafwk.param.callerUid'])
+ }
+}
+
diff --git a/permissionmanager/src/main/ets/pages/other-permissions.ets b/permissionmanager/src/main/ets/pages/other-permissions.ets
new file mode 100644
index 0000000..1de45de
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/other-permissions.ets
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { backBar } from "../common/components/backBar";
+import router from '@system.router';
+import Constants from '../common/utils/constant';
+import { otherPermissionsLabel } from '../common/model/permissionGroup'
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
+
+var TAG = 'PermissionManager_MainAbility:'
+
+let routerData = router.getParams().routerData; // Routing jump data
+let tokenId: any = router.getParams().tokenId; // tokenId for verify permission
+let backTitle = router.getParams().backTitle; // return title name
+let status = router.getParams().status; // Status: Allowed, Forbidden
+let permissions: any = router.getParams().permission; // permissions name
+let otherPermissionList = []; // otherPermission List
+for (let i = 0; i < permissions.length; i++) {
+ otherPermissionList.push({
+ permissionLabel: otherPermissionsLabel[permissions[i]],
+ permission: permissions[i]
+ })
+}
+
+@Entry
+@Component
+struct appNamePage {
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar({ title: JSON.stringify(backTitle), recordable: false })
+ }
+ Row() {
+ Column() {
+ Scroll() {
+ appNameItem()
+ }
+ }
+ }.layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+
+/**
+ * Lifecycle function, triggered once when this page is displayed
+ */
+ onPageShow() {
+ console.log(TAG + 'onPageShow other-permissions')
+ let isGranted = true;
+ permissions.forEach(permission => {
+ abilityAccessCtrl.createAtManager().verifyAccessToken(tokenId, permission).then(res => {
+ status = res;
+ })
+ .catch(err => {
+ console.error(TAG + 'verifyAccessToken occure error: ' + JSON.stringify(err))
+ })
+ })
+ }
+}
+
+@Component
+struct appNameItem {
+ @State otherPermissionListItem: string[] = otherPermissionList; // Other permission interface data array
+ @Builder ListItemLayout(item, index) {
+ ListItem() {
+ Row() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ Text(item.permissionLabel)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontColor($r('app.color.text_color'))
+ .flexGrow(Constants.FLEX_GROW)
+ Image($r('app.media.rightarrow'))
+ .objectFit(ImageFit.Contain)
+ .height(Constants.IMAGE_HEIGHT)
+ .width(Constants.IMAGE_WIDTH)
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.LISTITEM_ROW_HEIGHT)
+ }
+ if (!index) {
+ Row() {
+ Column()
+ .backgroundColor($r('app.color.text_decoration_color'))
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.TEXT_DECORATION_HEIGHT)
+ }
+ }
+ }.onClick(() => {
+ router.push({
+ uri: 'pages/application-tertiary',
+ params: {
+ routerData: routerData,
+ backTitle: item.permissionLabel,
+ permission: [item.permission],
+ status: status
+ }
+ });
+ })
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END })
+ }
+
+ build() {
+ Row() {
+ Column() {
+ Row() {
+ List() {
+ ForEach(this.otherPermissionListItem.slice(Constants.SLICE_START, this.otherPermissionListItem.length - 1),
+ (item) => {
+ this.ListItemLayout(item, Constants.SLICE_START_INDEX)
+ }, item => item.toString())
+ ForEach(this.otherPermissionListItem.slice(Constants.SLICE_END), (item, index) => {
+ this.ListItemLayout(item, Constants.SLICE_END_INDEX)
+ }, item => item.toString())
+ }.backgroundColor($r('app.color.default_background_color')).borderRadius(Constants.BORDER_RADIUS)
+ .padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.margin({ top: Constants.ROW_MARGIN_TOP })
+ .padding({ left: Constants.LIST_PADDING_LEFT, right: Constants.LISTITEM_PADDING_RIGHT })
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(Constants.FULL_HEIGHT)
+ }
+ }
+}
diff --git a/permissionmanager/src/main/ets/pages/permission-access-record.ets b/permissionmanager/src/main/ets/pages/permission-access-record.ets
new file mode 100644
index 0000000..529f738
--- /dev/null
+++ b/permissionmanager/src/main/ets/pages/permission-access-record.ets
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import bundle from '@ohos.bundle';
+import router from '@system.router';
+import Resmgr from '@ohos.resourceManager'
+import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
+import privacyManager from '@ohos.privacyManager'
+import { backBar } from "../common/components/backBar";
+import Constants from '../common/utils/constant';
+import { noNeedDisplayApp, userGrantPermissions, permissionGroupIds } from "../common/model/permissionGroup";
+import { getPermissionGroup } from '../common/utils/utils'
+
+var TAG = 'PermissionManager_MainAbility:'
+
+@Extend(Image) function customizeImage(width: number, height: number) {
+ .objectFit(ImageFit.Contain)
+ .width(width)
+ .height(height)
+};
+
+@Entry
+@Component
+struct permissionRecordPage {
+ @State groups: any[] = []
+ @State applicationInfos: any[] = []
+ @State permissionApplications: any[] = []
+ @State permissionIndex: number = -1
+ @State applicationIndex: number = -1
+ @State strings: any = {}
+ @State currentIndex: number = 0
+ @Builder TabBuilder(index: number) {
+ Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
+ Text(index ? $r('app.string.application') : $r('app.string.authority'))
+ .fontColor(this.currentIndex == index ? $r('app.color.button_color') : $r('app.color.label_color'))
+ .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular)
+ .lineHeight(Constants.TEXT_LINE_HEIGHT)
+ if(this.currentIndex == index) {
+ Row().width(Constants.FULL_WIDTH).height(Constants.TAB_DECORATION_HEIGHT)
+ .backgroundColor($r('app.color.button_color'))
+ .position({ y: Constants.TAB_DECORATION_POSITION_Y })
+ }
+ }.height(Constants.TAB_HEIGHT)
+ }
+
+ @Builder ListItemLayout(item, index, dimension) {
+ ListItem() {
+ Column() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
+ Row() {
+ if(dimension) {
+ Image(item.icon)
+ .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
+ .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT_RECORD, left: Constants.MANAGEMENT_IMAGE_MARGIN_LEFT })
+ }else {
+ Image(item.icon)
+ .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
+ .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
+ }
+ Column() {
+ Text(item.groupName)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .lineHeight(Constants.TEXT_LINE_HEIGHT)
+ .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
+ if(dimension) {
+ Text(this.strings.visits + item.sum)
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
+ }else {
+ Row() {
+ if (item.permissions) {
+ ForEach(item.permissions, permission => {
+ Image(permission.icon)
+ .customizeImage(Constants.IMAGE_WIDTH_RECORD_APPLICATION, Constants.IMAGE_HEIGHT_RECORD_APPLICATION)
+ .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT })
+ })
+ }
+ }
+ }
+ }.flexGrow(Constants.FLEX_GROW)
+ .alignItems(HorizontalAlign.Start)
+ if(dimension) {
+ if(index == this.permissionIndex) {
+ Image($r('app.media.xiangshangjiantou'))
+ .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
+ }else {
+ Image($r('app.media.xiangxiajiantou'))
+ .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
+ }
+ }else {
+ if(index == this.applicationIndex) {
+ Image($r('app.media.xiangshangjiantou'))
+ .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
+ }else {
+ Image($r('app.media.xiangxiajiantou'))
+ .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
+ }
+ }
+ }
+ .width(Constants.FULL_WIDTH)
+ .height(dimension ? Constants.LISTITEM_HEIGHT_PERMISSION : Constants.LISTITEM_HEIGHT_APPLICATION)
+ }
+ }.onClick(() => {
+ dimension ?
+ (this.permissionIndex = this.permissionIndex == index ? -1 : index) :
+ (this.applicationIndex = this.applicationIndex == index ? -1 : index)
+ if(dimension) {
+ this.permissionApplications = this.applicationInfos.filter(appInfo => {
+ return appInfo.groupNames.includes(item.groupName)
+ })
+ }
+ })
+ if(dimension && (index == this.permissionIndex)) {
+ List() {
+ ForEach(this.permissionApplications, (permissionApplication) => {
+ ListItem() {
+ Row() {
+ Image(permissionApplication.icon)
+ .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
+ .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
+ Column() {
+ Row().width(Constants.FULL_WIDTH).height(Constants.TEXT_DECORATION_HEIGHT)
+ .backgroundColor($r("app.color.label_color_lightest"))
+ .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM_PERMISSION })
+ Text(permissionApplication.groupName)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .lineHeight(Constants.TEXT_LINE_HEIGHT)
+ .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
+ Text(this.strings.visits + this.getAppRecords(permissionApplication, item.groupName, true) +
+ this.strings.recent_visit + this.getTime(this.getAppRecords(permissionApplication, item.groupName, false)))
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
+ }.alignItems(HorizontalAlign.Start)
+ .height(Constants.FULL_HEIGHT)
+ }
+ }.height(Constants.LISTITEM_HEIGHT_APPLICATION)
+ .onClick(() => {
+ router.push({
+ uri: 'pages/application-secondary',
+ params: { routerData: {
+ 'bundleName': permissionApplication.name,
+ 'tokenId': permissionApplication.accessTokenId,
+ 'iconId': permissionApplication.icon,
+ 'labelId': permissionApplication.groupName,
+ 'permissions': permissionApplication.reqUserPermissions,
+ 'groupId': permissionApplication.groupIds
+ } }
+ });
+ })
+ })
+ }
+ }
+ if(!dimension && (index == this.applicationIndex)) {
+ List() {
+ ForEach(item.permissions, (permission) => {
+ ListItem() {
+ Row() {
+ Image(permission.icon)
+ .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
+ .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT_RECORD, left: Constants.MANAGEMENT_IMAGE_MARGIN_LEFT })
+ Column() {
+ Row().width(Constants.FULL_WIDTH).height(Constants.TEXT_DECORATION_HEIGHT)
+ .backgroundColor($r("app.color.label_color_lightest"))
+ .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM_APPLICATION })
+ Text(permission.groupName)
+ .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
+ .fontWeight(FontWeight.Medium)
+ .fontColor($r('app.color.label_color'))
+ .lineHeight(Constants.TEXT_LINE_HEIGHT)
+ .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
+ Text(this.strings.visits + permission['count' + item.accessTokenId]
+ + this.strings.recent_visit + this.getTime(permission['lastTime' + item.accessTokenId]))
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
+ }.alignItems(HorizontalAlign.Start)
+ .height(Constants.FULL_HEIGHT)
+ }
+ }.height(Constants.LISTITEM_HEIGHT_PERMISSION)
+ .onClick(() => {
+ router.push({
+ uri: 'pages/application-secondary',
+ params: { routerData: {
+ 'bundleName': item.name,
+ 'tokenId': item.accessTokenId,
+ 'iconId': item.icon,
+ 'labelId': item.groupName,
+ 'permissions': item.reqUserPermissions,
+ 'groupId': item.groupIds
+ } }
+ });
+ })
+ })
+ }
+ }
+ }
+ }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END,
+ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM })
+ .backgroundColor($r('app.color.default_background_color'))
+ .borderRadius(Constants.BORDER_RADIUS)
+ }
+
+ build() {
+ GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
+ Row() {
+ Row()
+ .useSizeType({
+ xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
+ sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
+ md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
+ lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row() {
+ Column() {
+ Row() {
+ backBar( { title: JSON.stringify($r('app.string.permission_access_record')), recordable: false })
+ }
+ Row() {
+ Column() {
+ Column() {
+ Flex({ justifyContent: FlexAlign.Start }) {
+ Text($r('app.string.record_time_limit'))
+ .margin({ left: Constants.BACKBAR_IMAGE_MARGIN_LEFT })
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
+ }.constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
+ .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM })
+ if(this.groups.length) {
+ Stack() {
+ Tabs() {
+ TabContent() {
+ Row() {
+ Column() {
+ Scroll() {
+ Row() {
+ List() {
+ ForEach(this.groups, (item, index) => {
+ this.ListItemLayout(item, index, Constants.PERMISSION)
+ }, item => item.toString())
+ }.padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.padding({
+ left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
+ right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
+ top: Constants.MANAGEMENT_ROW_PADDING_TOP
+ })
+ }.scrollBar(BarState.Off)
+ }.width(Constants.FULL_WIDTH)
+ }
+ }.tabBar(this.TabBuilder(0))
+ TabContent() {
+ Row() {
+ Column() {
+ Scroll() {
+ Row() {
+ List() {
+ ForEach(this.applicationInfos, (item, index) => {
+ this.ListItemLayout(item, index, Constants.APPLICATION)
+ }, item => item.toString())
+ }.padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
+ }.padding({
+ left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
+ right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
+ top: Constants.MANAGEMENT_ROW_PADDING_TOP
+ })
+ }.scrollBar(BarState.Off)
+ }.width(Constants.FULL_WIDTH)
+ }
+ }.tabBar(this.TabBuilder(1))
+ }
+ .barWidth(Constants.BAR_WIDTH)
+ .barMode(BarMode.Fixed)
+ .onChange((index) => {
+ this.currentIndex = index
+ })
+ }.height(Constants.FULL_HEIGHT)
+ }else {
+ Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
+ Image($r('app.media.noRecord'))
+ .customizeImage(Constants.NORECORD_IMAGE_WIDTH, Constants.NORECORD_IMAGE_HEIGHT)
+ .margin({ left: Constants.NORECORD_IMAGE_MARGIN_LEFT })
+ Text($r('app.string.no_record')).margin({ top: Constants.DIALOG_REQ_MARGIN_TOP })
+ .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
+ .fontColor($r('app.color.label_color_light'))
+ }.width(Constants.FULL_WIDTH).height(Constants.FULL_HEIGHT)
+ .padding({ bottom: Constants.RECORD_PADDING_BOTTOM })
+ }
+ }
+ }
+ }
+ .layoutWeight(Constants.LAYOUT_WEIGHT)
+ }
+ }
+ .useSizeType({
+ xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
+ sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
+ md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
+ lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ Row()
+ .useSizeType({
+ xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
+ sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
+ md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
+ lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
+ })
+ .height(Constants.FULL_HEIGHT)
+ }
+ .height(Constants.FULL_HEIGHT)
+ .width(Constants.FULL_WIDTH)
+ .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
+ .opacity(Constants.MANAGEMENT_TRANSPARENCY)
+ }
+ }
+
+ /**
+ * Get time
+ * @param {Number} The time stamp
+ */
+ getTime(time, format='MM月DD日 NNHH:mm') {
+ if(this.strings.morning == 'am') { format = 'MM/DD HH:mm NN' }
+ let date = new Date(time * 1000)
+ let config = {
+ MM: date.getMonth() + 1,
+ DD: date.getDate(),
+ NN: date.getHours() >= 12 ? this.strings.afternoon : this.strings.morning,
+ HH: date.getHours() >= 12 ? date.getHours() - 12 : date.getHours(),
+ mm: date.getMinutes() > 10 ? date.getMinutes() : '0' + date.getMinutes(),
+ }
+
+ for(const key in config){
+ format = format.replace(key,config[key])
+ }
+ return format
+ }
+
+ /**
+ * Get application record info
+ * @param {Object} application info
+ * @param {String} groupName
+ * @param {Boolean} true: count, false: lastTime
+ */
+ getAppRecords(appInfo, groupName, option) {
+ var record = appInfo.permissions.filter(permission => {
+ return permission.groupName == groupName
+ })
+ return option ? record[0]['count' + appInfo.accessTokenId] : record[0]['lastTime' + appInfo.accessTokenId]
+ }
+
+ getStrings() {
+ Resmgr.getResourceManager(globalThis.context, Constants.BUNDLE_NAME).then(item => {
+ item.getString($r("app.string.visits").id, (err, val) => {
+ this.strings.visits = val
+ })
+ item.getString($r("app.string.recent_visit").id, (err, val) => {
+ this.strings.recent_visit = val
+ })
+ item.getString($r("app.string.morning").id, (err, val) => {
+ this.strings.morning = val
+ })
+ item.getString($r("app.string.afternoon").id, (err, val) => {
+ this.strings.afternoon = val
+ })
+ }).catch(error => {
+ console.error(TAG + 'Resmgr.getResourceManager failed. Cause: ' + JSON.stringify(error));
+ })
+ }
+
+ getInfo(record, sortFlag) {
+ bundle.getBundleInfo(record.bundleName, Constants.PARMETER_BUNDLE_FLAG).then(async info => {
+ var reqUserPermissions: string[] = [];
+ var reqUserRecords: any[] = [];
+ var permissionGroups: any[] = [];
+ var acManager = abilityAccessCtrl.createAtManager()
+ var appInfo: any = {}
+ for (let j = 0; j < record.permissionRecords.length; j++) {
+ var permission = record.permissionRecords[j].permissionName;
+ var flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission)
+ if(flag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) {
+ continue
+ }
+ if (userGrantPermissions.indexOf(permission) != -1) {
+ reqUserRecords.push(record.permissionRecords[j])
+ }
+ }
+ for (let k = 0; k < info.reqPermissions.length; k++) {
+ var reqPermission = info.reqPermissions[k];
+ var reqFlag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, reqPermission)
+ if(reqFlag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) {
+ continue
+ }
+ if (userGrantPermissions.indexOf(reqPermission) != -1) {
+ reqUserPermissions.push(reqPermission);
+ }
+ }
+
+ let groupNames = [];
+ let appLastTime = 0;
+ reqUserRecords.forEach(reqUserRecord => {
+ var group = getPermissionGroup(reqUserRecord.permissionName)
+ if(!group) {
+ console.info(TAG + "permission not find:" + reqUserRecord.permissionName)
+ }else {
+ var existing = permissionGroups.find(permissionGroup => permissionGroup.name == group.name)
+ var lastTime = reqUserRecord.lastAccessTime
+ lastTime > appLastTime ? appLastTime = lastTime : ''
+ if(!existing) {
+ group['count' + record.tokenId] = reqUserRecord.accessCount
+ group['lastTime' + record.tokenId] = lastTime
+ permissionGroups.push(group)
+ groupNames.push(group.groupName)
+ }else {
+ existing['count' + record.tokenId] += reqUserRecord.accessCount
+ lastTime > existing['lastTime' + record.tokenId] ? existing['lastTime' + record.tokenId] = lastTime : ''
+ }
+ }
+ })
+
+ let groupIds = [];
+ for (let i = 0; i < reqUserPermissions.length; i++) {
+ if(groupIds.indexOf(permissionGroupIds[reqUserPermissions[i]]) == -1){
+ groupIds.push(permissionGroupIds[reqUserPermissions[i]]);
+ }
+ }
+
+ await Resmgr.getResourceManager(globalThis.context, info.name).then(item => {
+ item.getString(info.appInfo['labelId'], (error, value) => {
+ if (value == undefined) {
+ appInfo['groupName'] = info.appInfo.label;
+ } else {
+ appInfo['groupName'] = value;
+ }
+ })
+
+ item.getMediaBase64(info.appInfo['iconId'], (error, value) => {
+ appInfo['icon'] = value;
+ })
+ })
+
+ appInfo.name = info.appInfo.name
+ appInfo.accessTokenId = info.appInfo.accessTokenId
+ appInfo.reqUserPermissions = reqUserPermissions
+ appInfo.permissions = permissionGroups
+ appInfo.groupNames = groupNames
+ appInfo.groupIds = groupIds
+ appInfo.appLastTime = appLastTime
+ this.applicationInfos.push(appInfo)
+ if(sortFlag) {
+ var appInfos: any[] = []
+ this.applicationInfos.forEach(item => { appInfos.push(item) })
+ appInfos.sort((a, b) => { return b.appLastTime - a.appLastTime })
+ this.applicationInfos = appInfos
+ }
+ })
+ }
+
+ getAllRecords() {
+ let request = {
+ "tokenId": 0,
+ "isRemote": false,
+ "permissionNames": [],
+ "beginTime": 0,
+ "endTime": 0,
+ "flag": 1
+ }
+ privacyManager.getPermissionUsedRecords(request).then(async records => {
+ console.info(TAG + "records: " + JSON.stringify(records.bundleRecords))
+ var groupArray: any[] = []
+ for (let i = 0; i < records.bundleRecords.length; i++) {
+ var record = records.bundleRecords[i]
+ try {
+ const ret = await bundle.queryAbilityByWant({
+ bundleName: record.bundleName,
+ action: "action.system.home",
+ entities: ["entity.system.home"]
+ }, bundle.BundleFlag.GET_ABILITY_INFO_WITH_APPLICATION, Constants.USERID);
+ } catch(e) {
+ continue;
+ }
+ if (noNeedDisplayApp.indexOf(record.bundleName) != -1) {
+ continue;
+ }
+ console.info(TAG + "record: " + JSON.stringify(record))
+ this.getInfo(record, (i + 1) == records.bundleRecords.length)
+
+ record.permissionRecords.forEach(permissionRecord => {
+ var group = getPermissionGroup(permissionRecord.permissionName)
+ if(group) {
+ var exist = groupArray.find(permissionGroup => permissionGroup.name == group.name)
+ var lastTime = permissionRecord.lastAccessTime
+ if(!exist) {
+ group.sum = permissionRecord.accessCount
+ group.recentVisit = lastTime
+ groupArray.push(group)
+ }else {
+ exist.sum += permissionRecord.accessCount
+ lastTime > exist.recentVisit ? exist.recentVisit = lastTime : ''
+ }
+ }
+ })
+ }
+ groupArray.sort((a, b) => { return b.recentVisit - a.recentVisit })
+ this.groups = groupArray
+ })
+ }
+
+ aboutToAppear() {
+ this.getStrings()
+ this.getAllRecords()
+ }
+}
diff --git a/permissionmanager/src/main/module.json b/permissionmanager/src/main/module.json
new file mode 100644
index 0000000..234024c
--- /dev/null
+++ b/permissionmanager/src/main/module.json
@@ -0,0 +1,58 @@
+
+
+{
+ "module": {
+ "name": "permissionmanager",
+ "type": "feature",
+ "srcEntrance": "./ets/Application/AbilityStage.ts",
+ "description": "$string:permissionmanager_desc",
+ "mainElement": "MainAbility",
+ "deviceTypes": [
+ "phone"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "uiSyntax": "ets",
+ "abilities": [
+ {
+ "name": "com.ohos.permissionmanager.MainAbility",
+ "srcEntrance": "./ets/MainAbility/MainAbility.ts",
+ "description": "$string:MainAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:MainAbility_label",
+ "visible": true,
+ "launchType": "standard"
+ }
+ ],
+ "extensionAbilities": [
+ {
+ "icon": "$media:icon",
+ "name": "com.ohos.permissionmanager.GrantAbility",
+ "srcEntrance": "./ets/ServiceExtAbility/ServiceExtAbility.ts",
+ "type": "service",
+ "visible": true
+ }
+ ],
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.GET_SENSITIVE_PERMISSIONS"
+ },
+ {
+ "name": "ohos.permission.GRANT_SENSITIVE_PERMISSIONS"
+ },
+ {
+ "name": "ohos.permission.REVOKE_SENSITIVE_PERMISSIONS"
+ },
+ {
+ "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED"
+ },
+ {
+ "name": "ohos.permission.GET_BUNDLE_INFO"
+ },
+ {
+ "name": "ohos.permission.PERMISSION_USED_STATS"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/ar/profile/string.json b/permissionmanager/src/main/resources/ar/profile/string.json
new file mode 100644
index 0000000..c3a6df1
--- /dev/null
+++ b/permissionmanager/src/main/resources/ar/profile/string.json
@@ -0,0 +1,14 @@
+{
+ "strings": {
+ "app_name": "CategoryPage",
+ "describe": "describe",
+ "category": "Category",
+ "itemChild": "ItemChild",
+ "item": "Item",
+ "search": "search...",
+ "you_search": "You search ",
+ "you_clicked": "You clicked ",
+ "tab": "Tab",
+ "more": "< more"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/element/color.json b/permissionmanager/src/main/resources/base/element/color.json
new file mode 100644
index 0000000..d9c648a
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/element/color.json
@@ -0,0 +1,112 @@
+{
+ "color": [
+ {
+ "name": "text_color",
+ "value": "#E5000000"
+ },
+ {
+ "name": "label_color",
+ "value": "#182431"
+ },
+ {
+ "name": "label_color_light",
+ "value": "#99182431"
+ },
+ {
+ "name": "label_color_lighter",
+ "value": "#66182431"
+ },
+ {
+ "name": "label_color_20",
+ "value": "#33182431"
+ },
+ {
+ "name": "label_color_lightest",
+ "value": "#0D182431"
+ },
+ {
+ "name": "background_color",
+ "value": "#F4F5F7"
+ },
+ {
+ "name": "list_background_color",
+ "value": "#FDFDFD"
+ },
+ {
+ "name": "text_secondary_color",
+ "value": "#99000000"
+ },
+ {
+ "name": "active_background_color",
+ "value": "#e5f3ff"
+ },
+ {
+ "name": "divider_color",
+ "value": "#f3f4f6"
+ },
+ {
+ "name": "text_decoration_color",
+ "value": "#f3f4f6"
+ },
+ {
+ "name": "default_background_color",
+ "value": "#ffffff"
+ },
+ {
+ "name": "button_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "shape_allow_color",
+ "value": "#1856D4"
+ },
+ {
+ "name": "shape_ban_color",
+ "value": "#000000"
+ },
+ {
+ "name": "first_font_color",
+ "value": "#E6000000"
+ },
+ {
+ "name": "secondary_font_color",
+ "value": "#66000000"
+ },
+ {
+ "name": "toggle_color",
+ "value": "#409eff"
+ },
+ {
+ "name": "color_Primary",
+ "value": "#E5000000"
+ },
+ {
+ "name": "color_Secondary",
+ "value": "#99000000"
+ },
+ {
+ "name": "color_Tertiary",
+ "value": "#66000000"
+ },
+ {
+ "name": "color_Fourth",
+ "value": "#33000000"
+ },
+ {
+ "name": "selected_Color",
+ "value": "#ffffff"
+ },
+ {
+ "name": "popup_Color",
+ "value": "#FFFAF0"
+ },
+ {
+ "name": "selected_Background_Color",
+ "value": "#CCCCCC"
+ },
+ {
+ "name": "popup_Background_Color",
+ "value": "#D2B48C"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/element/string.json b/permissionmanager/src/main/resources/base/element/string.json
new file mode 100644
index 0000000..a1b07a9
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/element/string.json
@@ -0,0 +1,92 @@
+{
+ "string": [
+ {
+ "name": "permissionmanager_desc",
+ "value": "permissionmanager"
+ },
+ {
+ "name": "MainAbility_desc",
+ "value": "manage the permissions of all applications from the permission and application dimensions"
+ },
+ {
+ "name": "MainAbility_label",
+ "value": "permission manage"
+ },
+ {
+ "name": "no_permission",
+ "value": "no permission"
+ },
+ {
+ "name": "access_permission",
+ "value": "access permission"
+ },
+ {
+ "name": "permission_access_record",
+ "value": "permission access record"
+ },
+ {
+ "name": "authority_management",
+ "value": "authority management"
+ },
+ {
+ "name": "other_permissions",
+ "value": "other permissions"
+ },
+ {
+ "name": "application",
+ "value": "application"
+ },
+ {
+ "name": "authority",
+ "value": "authority"
+ },
+ {
+ "name": "textInput_placeholder",
+ "value": "search application"
+ },
+ {
+ "name": "allowed",
+ "value": "allowed"
+ },
+ {
+ "name": "banned",
+ "value": "banned"
+ },
+ {
+ "name": "Authorization_failed",
+ "value": "Authorization failure!"
+ },
+ {
+ "name": "reason_suffix",
+ "value": " and other permissions."
+ },
+ {
+ "name": "separator",
+ "value": ","
+ },
+ {
+ "name": "visits",
+ "value": "Number of visits:"
+ },
+ {
+ "name": "recent_visit",
+ "value": ";Recent visits:"
+ },
+ {
+ "name": "morning",
+ "value": "am"
+ },
+ {
+ "name": "afternoon",
+ "value": "pm"
+ },
+ {
+ "name": "no_record",
+ "value": "No permission access record"
+ },
+ {
+ "name": "record_time_limit",
+ "value": "Access records in the last 7 days"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/gongneng_dian.svg b/permissionmanager/src/main/resources/base/media/gongneng_dian.svg
new file mode 100644
index 0000000..50265c1
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/gongneng_dian.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_call_logs.svg b/permissionmanager/src/main/resources/base/media/ic_call_logs.svg
new file mode 100644
index 0000000..8826af6
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_call_logs.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/permissionmanager/src/main/resources/base/media/ic_dropzone.svg b/permissionmanager/src/main/resources/base/media/ic_dropzone.svg
new file mode 100644
index 0000000..960483f
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_dropzone.svg
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_exercise.svg b/permissionmanager/src/main/resources/base/media/ic_exercise.svg
new file mode 100644
index 0000000..e31feee
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_exercise.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/permissionmanager/src/main/resources/base/media/ic_forward.svg b/permissionmanager/src/main/resources/base/media/ic_forward.svg
new file mode 100644
index 0000000..ddf503e
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_forward.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/permissionmanager/src/main/resources/base/media/ic_more.svg b/permissionmanager/src/main/resources/base/media/ic_more.svg
new file mode 100644
index 0000000..73ab249
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_more.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_multi_device_vector.svg b/permissionmanager/src/main/resources/base/media/ic_multi_device_vector.svg
new file mode 100644
index 0000000..b85bdf1
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_multi_device_vector.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_nearby.svg b/permissionmanager/src/main/resources/base/media/ic_nearby.svg
new file mode 100644
index 0000000..4b201c8
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_nearby.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg b/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg
new file mode 100644
index 0000000..bfb1636
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_calendar.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_camera.svg b/permissionmanager/src/main/resources/base/media/ic_public_camera.svg
new file mode 100644
index 0000000..535b7a3
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_camera.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg b/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg
new file mode 100644
index 0000000..e019107
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_contacts_group.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_folder.svg b/permissionmanager/src/main/resources/base/media/ic_public_folder.svg
new file mode 100644
index 0000000..01a9fae
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_folder.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_gps.svg b/permissionmanager/src/main/resources/base/media/ic_public_gps.svg
new file mode 100644
index 0000000..738516f
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_gps.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_message.svg b/permissionmanager/src/main/resources/base/media/ic_public_message.svg
new file mode 100644
index 0000000..79f77f6
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_message.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_phone.svg b/permissionmanager/src/main/resources/base/media/ic_public_phone.svg
new file mode 100644
index 0000000..df52fe3
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_phone.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_public_voice.svg b/permissionmanager/src/main/resources/base/media/ic_public_voice.svg
new file mode 100644
index 0000000..257ae06
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_public_voice.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_sport.svg b/permissionmanager/src/main/resources/base/media/ic_sport.svg
new file mode 100644
index 0000000..e9ed571
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_sport.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/ic_ssensor.svg b/permissionmanager/src/main/resources/base/media/ic_ssensor.svg
new file mode 100644
index 0000000..51b9c50
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/ic_ssensor.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/icon.png b/permissionmanager/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000..ce307a8
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/icon.png differ
diff --git a/permissionmanager/src/main/resources/base/media/in_app_installations.svg b/permissionmanager/src/main/resources/base/media/in_app_installations.svg
new file mode 100644
index 0000000..c40993a
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/in_app_installations.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/left.png b/permissionmanager/src/main/resources/base/media/left.png
new file mode 100644
index 0000000..3d2329c
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/left.png differ
diff --git a/permissionmanager/src/main/resources/base/media/loading.gif b/permissionmanager/src/main/resources/base/media/loading.gif
new file mode 100644
index 0000000..915c198
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/loading.gif differ
diff --git a/permissionmanager/src/main/resources/base/media/noRecord.svg b/permissionmanager/src/main/resources/base/media/noRecord.svg
new file mode 100644
index 0000000..bc844b7
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/noRecord.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg b/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg
new file mode 100644
index 0000000..5b10a66
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/noinstallationpackage.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/nopermission.svg b/permissionmanager/src/main/resources/base/media/nopermission.svg
new file mode 100644
index 0000000..fe47a1d
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/nopermission.svg
@@ -0,0 +1,16 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/radioactive.jpg b/permissionmanager/src/main/resources/base/media/radioactive.jpg
new file mode 100644
index 0000000..55e2ade
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/radioactive.jpg differ
diff --git a/permissionmanager/src/main/resources/base/media/radiodefault.jpg b/permissionmanager/src/main/resources/base/media/radiodefault.jpg
new file mode 100644
index 0000000..189d3ae
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/radiodefault.jpg differ
diff --git a/permissionmanager/src/main/resources/base/media/rightarrow.png b/permissionmanager/src/main/resources/base/media/rightarrow.png
new file mode 100644
index 0000000..51aad9f
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/rightarrow.png differ
diff --git a/permissionmanager/src/main/resources/base/media/search.png b/permissionmanager/src/main/resources/base/media/search.png
new file mode 100644
index 0000000..7f3716e
Binary files /dev/null and b/permissionmanager/src/main/resources/base/media/search.png differ
diff --git a/permissionmanager/src/main/resources/base/media/searchnoresult.svg b/permissionmanager/src/main/resources/base/media/searchnoresult.svg
new file mode 100644
index 0000000..e948acc
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/searchnoresult.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/xiangshangjiantou.svg b/permissionmanager/src/main/resources/base/media/xiangshangjiantou.svg
new file mode 100644
index 0000000..24d372d
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/xiangshangjiantou.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/media/xiangxiajiantou.svg b/permissionmanager/src/main/resources/base/media/xiangxiajiantou.svg
new file mode 100644
index 0000000..42116e2
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/media/xiangxiajiantou.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/base/profile/main_pages.json b/permissionmanager/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000..c2e856f
--- /dev/null
+++ b/permissionmanager/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,13 @@
+{
+ "src": [
+ "pages/authority-management",
+ "pages/application-secondary",
+ "pages/authority-secondary",
+ "pages/authority-tertiary",
+ "pages/application-tertiary",
+ "pages/other-permissions",
+ "pages/authority-tertiary-groups",
+ "pages/permission-access-record",
+ "pages/dialogPlus"
+ ]
+}
diff --git a/permissionmanager/src/main/resources/dark/profile/string.json b/permissionmanager/src/main/resources/dark/profile/string.json
new file mode 100644
index 0000000..ddc52a1
--- /dev/null
+++ b/permissionmanager/src/main/resources/dark/profile/string.json
@@ -0,0 +1,7 @@
+{
+ "colors": {
+ "colorSubBackground": "#000000",
+ "appbar_subtitle_color": "#99ffffff",
+ "text_color": "#ffffff"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/en/profile/string.json b/permissionmanager/src/main/resources/en/profile/string.json
new file mode 100644
index 0000000..319b5d6
--- /dev/null
+++ b/permissionmanager/src/main/resources/en/profile/string.json
@@ -0,0 +1,14 @@
+{
+ "strings": {
+ "app_name": "CategoryPage",
+ "describe": "describe",
+ "category": "Category",
+ "itemChild": "ItemChild",
+ "item": "Item",
+ "search": "search...",
+ "you_search": "You search ",
+ "you_clicked": "You clicked ",
+ "tab": "Tab",
+ "more": "more >"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/light/profile/string.json b/permissionmanager/src/main/resources/light/profile/string.json
new file mode 100644
index 0000000..4b9482c
--- /dev/null
+++ b/permissionmanager/src/main/resources/light/profile/string.json
@@ -0,0 +1,7 @@
+{
+ "colors": {
+ "colorSubBackground": "#f1f3f5",
+ "appbar_subtitle_color": "#99000000",
+ "text_color": "#000000"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/zh/profile/string.json b/permissionmanager/src/main/resources/zh/profile/string.json
new file mode 100644
index 0000000..4ca364c
--- /dev/null
+++ b/permissionmanager/src/main/resources/zh/profile/string.json
@@ -0,0 +1,14 @@
+{
+ "strings": {
+ "app_name": "分类页",
+ "describe": "描述",
+ "category": "分类",
+ "itemChild": "子类",
+ "item": "类型",
+ "search": "搜索...",
+ "you_search": "你搜索了",
+ "you_clicked": "你点击了",
+ "tab": "分页",
+ "more": "更多 >"
+ }
+}
\ No newline at end of file
diff --git a/permissionmanager/src/main/resources/zh_CN/element/string.json b/permissionmanager/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000..e92d068
--- /dev/null
+++ b/permissionmanager/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,92 @@
+{
+ "string": [
+ {
+ "name": "permissionmanager_desc",
+ "value": "权限管理"
+ },
+ {
+ "name": "MainAbility_desc",
+ "value": "从权限和应用两个维度来管理所有应用申请的权限。"
+ },
+ {
+ "name": "MainAbility_label",
+ "value": "权限管理"
+ },
+ {
+ "name": "no_permission",
+ "value": "暂无权限"
+ },
+ {
+ "name": "access_permission",
+ "value": "访问权限"
+ },
+ {
+ "name": "permission_access_record",
+ "value": "权限访问记录"
+ },
+ {
+ "name": "authority_management",
+ "value": "权限管理"
+ },
+ {
+ "name": "other_permissions",
+ "value": "其它权限"
+ },
+ {
+ "name": "application",
+ "value": "应用"
+ },
+ {
+ "name": "authority",
+ "value": "权限"
+ },
+ {
+ "name": "textInput_placeholder",
+ "value": "搜索应用"
+ },
+ {
+ "name": "allowed",
+ "value": "已允许"
+ },
+ {
+ "name": "banned",
+ "value": "已禁止"
+ },
+ {
+ "name": "Authorization_failed",
+ "value": "授权失败!"
+ },
+ {
+ "name": "reason_suffix",
+ "value": "等权限。"
+ },
+ {
+ "name": "separator",
+ "value": "、"
+ },
+ {
+ "name": "visits",
+ "value": "访问次数:"
+ },
+ {
+ "name": "recent_visit",
+ "value": ";最近访问:"
+ },
+ {
+ "name": "morning",
+ "value": "上午"
+ },
+ {
+ "name": "afternoon",
+ "value": "下午"
+ },
+ {
+ "name": "no_record",
+ "value": "没有权限访问记录"
+ },
+ {
+ "name": "record_time_limit",
+ "value": "近7天访问记录"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/signature/pm_5.p7b b/signature/pm_5.p7b
new file mode 100644
index 0000000..e2aa614
Binary files /dev/null and b/signature/pm_5.p7b differ