diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..52c0fa2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +/entry/.preview +.cxx +/node_modules diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..d0381d6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,176 @@ +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 diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 0000000..da7d1b0 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,57 @@ +# AdminProvisioning + +- [简介](#section11660541593) + - [架构图](#section125101832114213) +- [目录](#section161941989596) +- [使用说明](#section123459000) +- [相关仓](#section1371113476307) + +## 简介 + +AdminProvisioning应用是OpenHarmony中预置的系统应用,用于企业环境下在设备上发放MDM业务,同时提供了业务发放接口给其它子系统或者三方MDM客户端应用调用,支持在产品上构建完整的MDM解决方案。 + +### 架构图 + +![](figures/adminProvisioning_architecture.png) + +## 目录 + +``` +/applications/standard/systemui +├── build.gradle # 全局编译配置文件 +├── settings.gradle # 编译模块配置文件 +├── LICENSE # 许可文件 +├── entry # entry模块目录 +│ └── src +│ ├── main +│ ├── ets # ets模块目录 +│ ├── MainAbility +│ ├── model # 数据管理存放目录 +│ │ ├── appMagagementImpl +│ │ ├── appDetailData # 数据管理目录 +│ │ ├── baseData # 常量存放目录 +│ ├── pages # 组件页面存放目录 +│ │ ├── component +│ │ ├── entryComponent # 待激活应用详情组件 +│ │ ├── headComponent # 本身应用名称组件 +│ │ ├── permissionListComponent # 待激活应用权限组件 +│ │ ├── applicationInfo +│ ├── app.ets # 全局ets逻辑和应用生命周期管理文件 +│ ├── resources # 资源配置文件存放目录 +│ ├── base # 默认语言场景,图片资源,字体大小,颜色资源内容存放目录 +│ ├── en_AS.element # 英文语言场景资源内容存放目录 +│ ├── rawfile # 本地配置文件存放目录 +│ ├── zh_CN.element # 中文语言场景资源内容存放目录 +│ └── config.json # 全局配置文件 +├── signature # 证书文件目录 +``` +## 使用说明 + + 参见使用说明([使用说明](./doc/Instructions.md)) + +## 相关仓 + +系统应用 + +**applications\_admin_provisioning** + diff --git a/build.gradle b/build.gradle new file mode 100755 index 0000000..a084c04 --- /dev/null +++ b/build.gradle @@ -0,0 +1,37 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 7 + defaultConfig { + compatibleSdkVersion 7 + } + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.5.2' + classpath 'com.huawei.ohos:decctest:1.2.7.2' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/doc/Instructions.md b/doc/Instructions.md new file mode 100755 index 0000000..0c02e75 --- /dev/null +++ b/doc/Instructions.md @@ -0,0 +1,258 @@ +# AdminProvisioning 使用说明 +## 代码使用 +### 代码下载 +#### 配置码云ssh +1. 打开本地git bash窗口 +2. 进入到.ssh 目录:cd ~/.ssh +3. 找到id_rsa.pub文件:ls +4. 查看公钥:cat id_rsa.pub +5. 在码云个人设置-安全设置-ssh公钥中配置公钥 + +#### 下载代码 + 1. 打开码云AdminProvisioning地址([下载地址](https://gitee.com/openharmony/applications_admin_provisioning))。 + 2. 选择克隆/下载 - ssh方式 -复制下载地址 + 3. 本机git bash 中执行: + ``` + git clone '复制的下载地址' + ``` + +### 环境搭建 +打开DevEco Studio链接下载安装,安装步骤及安装说明详见开发者网站 + +## 基础开发说明 +### 系统接口调用 +#### NAPI接口集成 +- 导入指定模块 +``` JavaScript +import bundle from '@ohos.bundle'; +``` +- 调用模块中的相应函数 +``` JavaScript +bundle.getApplicationInfos().then(data => { + +}); +``` +### 异步回调的使用 +- 在需要回调操作的ets文件中创建回调函数 +```JavaScript +subscribeCallback(err, data){ + // do something +}, +``` +- 调用应用内部封装的接口,并传入回调函数 +```JavaScript +Notification.subscribe(mSubscriber, this.subscribeCallback.bind(this)); +``` +- 在AsyncCallback返回数据时可以获取到错误信息或目标数据 +```JavaScript +subscribeCallback(err, data) { + Log.showInfo(TAG, 'subscribeCallback finished ====================' + JSON.stringify(data)); +} +``` +### 如何引用资源文件 +- 在.ets文件中,可直接通过$r()引用资源 +```` JavaScript +this.title = this.$r('app.string.hello_world'); +```` + +## 典型接口的使用 + 1. 获取电池状态接口 + ``` JavaScript + import BatteryInfo from '@ohos.batteryInfo' + // 根据TS的文件描述,获取对应的电池属性 + + batterySOC = BatteryInfo.batterySOC; // 电池剩余电量 0~100; + batteryCharging = BatteryInfo.chargingStatus; // 电池充电状态 + ``` + 2. 返回按键 + ``` JavaScript + import input from '@ohos.injectEventHandler' + // 在触摸开始及结束时分别调用 + onTouchStart(){ + let res = input.injectEventSync({ + isPressed: true, // 是否为按下 + keyCode: 2, // 对应code + keyDownDuration: 1 // keydown 时长 + }); + }, + onTouchStop(){ + let res = input.injectEventSync({ + isPressed: false, // 是否为按下 + keyCode: 2, // 对应code + keyDownDuration: 1 // keydown 时长 + }); + } + ``` +## 签名打包 +### 签名 +#### 签名文件的获取 +1. 拷贝OpenHarmony标准版 工程的 prebuilts\signcenter 目录到操作目录 +2. 拷贝AdminProvisioning工程的 signature\adminprovisioning.p7b 到该目录下 +#### 签名文件的配置 +打开项目工程,选择 File → Project Structure + +![](image/signature_1.png) + +选择 Project → Signing Configs,将对应的签名文件配置如下,完成后点击Apply,再点击OK。 + +![](image/signature_2.png) + +配置完成后,对应的build.gradle文件中会出现如下内容 + +![](image/signature_3.png) +### 打包 +DevEco Studio 支持 debug 与 release 两种打包类型。可以在 OhosBuild Variants 窗口中进行切换。 + + ![](image/ds_ohosbuild_variants.png) + +#### debug打包 +1. 代码准备完成后,在 OhosBuild Variants 窗口的 Selected Variant 中选择 debug。 + + ![](image/ds_ohosbuild_variants_debug.png) + +2. 选择Build → Build Haps(s)/APP(s) → Build Hap(s) + + ![](image/ds_build_haps.png) + +3. 编译完成后,hap包会生成在工程目录下的 `\build\outputs\hap\debug\phone\`路径下(如果没有配置签名,则只会生成未签名的hap包) + + ![](image/ds_ohosbuild_variants_release.png) +#### release打包 +1. 代码准备完成后,在 OhosBuild Variants 窗口的 Selected Variant 中选择 release + + ![](image/ds_ohosbuild_variants_release.png) + +2. 选择Build → Build Haps(s)/APP(s) → Build Hap(s) + + ![](image/ds_build_haps.png) + +3. 编译完成后,hap包会生成在工程目录下的 `\build\outputs\hap\release\phone\`路径下(配置好签名后,生成的hap包会显示signed) + + ![](image/ds_ohosbuild_output_dir_release.png) +## 安装、运行、调试 +## 应用安装 +配置 hdc: +进入SDK目录中的toolchains文件夹下,获取文件路径: + +![](image/sdk_catalogue.png) + +> 注意,此处的hdc.exe如果版本较老,可能不能正常使用,需要获取新的hdc.exe文件 +> hdc命令介绍与下载详见:[hdc仓库地址](https://gitee.com/openharmony/developtools_hdc_standard) + + +并将此路径配置到环境变量中: + +![](image/sdk_environment_variable.png) + +重启电脑使环境变量生效 + +连接开发板,打开cmd命令窗口,执行hdc list targets,弹出窗口如下: + +![](image/cmd1.png) + +等待一段时间后,窗口出现如下打印,可回到输入 hdc list targets 的命令窗口继续操作: + +![](image/cmd2.png) + +再次输入hdc list targets,出现如下结果,说明hdc连接成功 + +![](image/cmd3.png) + +获取读写权限: + +``` +hdc target mount +``` +将签名好的 hap 包放入设备的 `/system/app` 目录下,并修改hap包的权限 + +``` +hdc file send 本地路径 /system/app/hap包名称 +例如:hdc file send adminprovisioning.hap /system/app/adminprovisioning.hap +``` +> 注意,如果设备不存在 `/system/app` 目录,则需要手动创建该目录并修改权限。 +> ``` +> hdc shell +> cd system +> mkdir app +> chmod 777 app +> ``` +> `/system/app` 目录放置系统应用,例如:Launcher,SystemUI,Settings 等。 +> +> 但hap包需要在该目录下手动设置权限 +> ``` +> chmod 666 hap包名 +> ``` +> 此目录应用不用手动安装,系统自动拉起。 +## 应用运行 +SystemUI属于系统应用,在将签名的 hap 包放入 `/system/app` 目录后,重启系统,应用会自动拉起。 +``` +hdc shell +reboot +(不可以直接执行hdc reboot,命令是无效的) +``` +> 注意,如果设备之前安装过系统应用,则需要执行如下两条命令清除设备中存储的应用信息才能够在设备重启的时候将我们装入设备的新 hap 包正常拉起。 +> ``` +> hdc shell rm -rf /data/misc_de/0/mdds/0/default/bundle_manager_service +> hdc shell rm -rf /data/accounts +> ``` +## 应用调试 +### log打印 +- 在程序中添加 log +```JS +console.info("adminprovisioning log info"); +``` +### log获取及过滤 +- log获取 + +将log输出至文件 +``` +hdc shell hilog > 输出文件名称 +``` + +例: +在真实环境查看log,将全log输出到当前目录的hilog.log文件中 +``` +hdc shell hilog > hilog.log +``` + +- log过滤 + +在命令行窗口中过滤log +``` +hilog │ grep 过滤信息 +``` + +例:过滤包含信息 Label 的 hilog +``` +hilog │ grep Label +``` +## 贡献代码 +### Fork 代码仓库 +1. 在码云上打开 AdminProvisioning 代码仓库([仓库地址](https://gitee.com/openharmony/applications_admin_provisioning))。 + +2. 点击仓库右上角的 Forked 按钮,在弹出的画面中,选择将仓库 fork 到哪里,点击确认。 + +3. Fork 成功之后,会在自己的账号下看见 fork 的代码仓库。 + +### 提交代码 +1. 访问我们自己在码云账号上 fork 的代码仓库,点击“克隆/下载”按钮,选择 SSH,点击“复制”按钮。 + +2. 在本地新建 AdminProvisioning 目录,在 AdminProvisioning 目录中执行如下命令 + ``` + git clone 步骤1中复制的地址 + ``` + +3. 修改代码。 + > 将代码引入工程,以及编译工程等相关内容请参见 **3. 代码使用** 部分的相关内容。 +4. 提交代码到 fork 仓库。 + > 修改后的代码,首先执行 `git add` 命令,然后执行 `git commit` 命令与 `git push` 命令,将代码 push 到我们自己的 fork 仓中。 + > 关于代码提交的这部分内容涉及 git 的使用,可以参照 [git官网](https://git-scm.com/) 的内容,在此不再赘述。 + +### 发起 Pull Request (PR) +在将代码提交到 fork 仓之后,我们可以通过发起 Pull Request(PR)的方式来为 OpenHarmony 的相关项目贡献代码。 + +1. 打开 fork 仓库。选择 `Pull Requests` → `新建 Pull Request` + +2. 在 `新建 Pull Request` 画面填入标题与说明,点击 `创建` 按钮。 + +3. 创建 Pull Request 完成。 PR 创建完成后,会有专门的代码审查人员对代码进行评审,评审通过之后会合入相应的代码库。 \ No newline at end of file diff --git a/doc/image/cmd1.png b/doc/image/cmd1.png new file mode 100755 index 0000000..43cec74 Binary files /dev/null and b/doc/image/cmd1.png differ diff --git a/doc/image/cmd2.png b/doc/image/cmd2.png new file mode 100755 index 0000000..b771fda Binary files /dev/null and b/doc/image/cmd2.png differ diff --git a/doc/image/cmd3.png b/doc/image/cmd3.png new file mode 100755 index 0000000..75cc11c Binary files /dev/null and b/doc/image/cmd3.png differ diff --git a/doc/image/ds_build_haps.png b/doc/image/ds_build_haps.png new file mode 100755 index 0000000..eb6be46 Binary files /dev/null and b/doc/image/ds_build_haps.png differ diff --git a/doc/image/ds_ohosbuild_output_dir_release.png b/doc/image/ds_ohosbuild_output_dir_release.png new file mode 100755 index 0000000..5efb65b Binary files /dev/null and b/doc/image/ds_ohosbuild_output_dir_release.png differ diff --git a/doc/image/ds_ohosbuild_variants.png b/doc/image/ds_ohosbuild_variants.png new file mode 100755 index 0000000..9c326f4 Binary files /dev/null and b/doc/image/ds_ohosbuild_variants.png differ diff --git a/doc/image/ds_ohosbuild_variants_debug.png b/doc/image/ds_ohosbuild_variants_debug.png new file mode 100755 index 0000000..7698c0b Binary files /dev/null and b/doc/image/ds_ohosbuild_variants_debug.png differ diff --git a/doc/image/ds_ohosbuild_variants_release.png b/doc/image/ds_ohosbuild_variants_release.png new file mode 100755 index 0000000..423deb7 Binary files /dev/null and b/doc/image/ds_ohosbuild_variants_release.png differ diff --git a/doc/image/sdk_catalogue.png b/doc/image/sdk_catalogue.png new file mode 100755 index 0000000..4faa2aa Binary files /dev/null and b/doc/image/sdk_catalogue.png differ diff --git a/doc/image/sdk_environment_variable.png b/doc/image/sdk_environment_variable.png new file mode 100755 index 0000000..789beda Binary files /dev/null and b/doc/image/sdk_environment_variable.png differ diff --git a/doc/image/signature_1.png b/doc/image/signature_1.png new file mode 100755 index 0000000..42aeb45 Binary files /dev/null and b/doc/image/signature_1.png differ diff --git a/doc/image/signature_2.png b/doc/image/signature_2.png new file mode 100755 index 0000000..cc28c02 Binary files /dev/null and b/doc/image/signature_2.png differ diff --git a/doc/image/signature_3.png b/doc/image/signature_3.png new file mode 100755 index 0000000..2b2e205 Binary files /dev/null and b/doc/image/signature_3.png differ diff --git a/entry/.gitignore b/entry/.gitignore new file mode 100755 index 0000000..f77260b --- /dev/null +++ b/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/entry/build.gradle b/entry/build.gradle new file mode 100755 index 0000000..c40c1f0 --- /dev/null +++ b/entry/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + compileSdkVersion 8 + defaultConfig { + compatibleSdkVersion 7 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/entry/proguard-rules.pro b/entry/proguard-rules.pro new file mode 100755 index 0000000..f7666e4 --- /dev/null +++ b/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/entry/src/main/config.json b/entry/src/main/config.json new file mode 100755 index 0000000..2024fc9 --- /dev/null +++ b/entry/src/main/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "com.ohos.adminprovisioning", + "vendor": "ohos", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "com.ohos.adminprovisioning", + "name": ".adminprovisioning", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "srcPath": "$media:icon", + "abilities": [ + { + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:description_mainability", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "singleton" + } + ], + "js": [ + { + "mode": { + "syntax": "ets", + "type": "pageAbility" + }, + "pages": [ + "pages/applicationInfo" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ], + "reqPermissions": [ + { + "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", + "reason": "get application information" + } + ] + } +} \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/app.ets b/entry/src/main/ets/MainAbility/app.ets new file mode 100755 index 0000000..6fe3ae4 --- /dev/null +++ b/entry/src/main/ets/MainAbility/app.ets @@ -0,0 +1,23 @@ +/* + * 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 { + onCreate() { + console.info('adminprovisioning onCreate') + }, + onDestroy() { + console.info('adminprovisioning onDestroy') + }, +} \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/model/appManagementImpl/appDetailData.ets b/entry/src/main/ets/MainAbility/model/appManagementImpl/appDetailData.ets new file mode 100755 index 0000000..3512bbd --- /dev/null +++ b/entry/src/main/ets/MainAbility/model/appManagementImpl/appDetailData.ets @@ -0,0 +1,143 @@ +/* + * 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 abilityFeatureAbility from '@ohos.ability.featureAbility'; +import bundle from '@ohos.bundle'; +import resourceManager from '@ohos.resourceManager'; +import baseData from '../baseData.ets'; + +let icon_default = $r('app.media.icon'); + +const permissionsDetailList: Array = [ + { + "permissionName": 'ohos.permission.EDM_MANAGE_DATETIME', + "permissionLabel": '设置系统时间', + "permissionDescription": '允许应用设置系统时间' + }, +]; + +export class AppDetailData { + public ret = { val: false }; + + async checkAppItem(elementNameVal) { + console.log('adminprovisioning checkAppItem in elementName:' + JSON.stringify(elementNameVal)); + let actionVal: string = 'ohos.action.ENT_ADMIN'; + let wantTemp = { "action": actionVal }; + let data = await bundle.queryAbilityByWant(wantTemp, bundle.BundleFlag.GET_BUNDLE_WITH_ABILITIES, baseData.USE_ID); + for (let item in data) { + console.log('adminprovisioning checkAppItem bundleName:' + data[item].bundleName + ' | name:' + data[item].name); + if (data[item].bundleName === elementNameVal.bundleName && data[item].name === elementNameVal.abilityName) { + this.ret.val = true; + return this.ret; + } + } + console.log('adminprovisioning checkAppItem return then false'); + this.ret.val = false; + return this.ret; + } + + async getBundleInfoItem(bundleName: string, appInfo) { + console.log('adminprovisioning getBundleInfoItem in bundleName:' + bundleName); + let data = await bundle.getBundleInfo(bundleName, bundle.BundleFlag.GET_BUNDLE_WITH_REQUESTED_PERMISSION); + await this.getResourceItem(bundleName, data, appInfo); + await this.getPermissionList(data, appInfo); + console.log('adminprovisioning getBundleInfoItem out'); + } + + async getAppInfoLabel(resMgr, id) { + let label = await resMgr.getString(id); + console.log('adminprovisioning getAppInfoLabel start label:' + label); + if (label == null || label == undefined || label == '') { + return ''; + } + return label; + } + + async getAppInfoIcon(resMgr, id) { + let iconVal = await resMgr.getMediaBase64(id); + console.log('adminprovisioning getAppInfoIcon start iconVal:' + iconVal); + if (iconVal == null || iconVal == undefined || iconVal == '') { + return ''; + } + return iconVal; + } + + async getResourceItem(bundleName, data, appInfo) { + console.log('adminprovisioning getResourceItem getResourceManager in'); + let resMgr = await resourceManager.getResourceManager(bundleName); + let appInfoTemp = data.appInfo; + let label = ''; + let iconVal = ''; + + if (appInfoTemp.labelId > 0) { + label = await this.getAppInfoLabel(resMgr, appInfoTemp.labelId); + console.log('adminprovisioning getResourceItem success appInfo.label:' + label); + } else { + label = appInfoTemp.label; + console.log('adminprovisioning getResourceItem defaults appInfo.label:' + label); + } + + if (appInfoTemp.iconId > 0) { + iconVal = await this.getAppInfoIcon(resMgr, appInfoTemp.iconId); + if (iconVal == '') { + appInfo.appIcon = icon_default; + appInfo.appTitle = label; + } + appInfo.appIcon = iconVal; + appInfo.appTitle = label; + AppStorage.SetOrCreate('applicationInfo', appInfo); + } + console.log('adminprovisioning getResourceItem getResourceManager out'); + } + + async terminateAbilityPage() { + console.log('adminprovisioning terminateAbilityPage in:'); + await abilityFeatureAbility.terminateSelf(); + } + + getPermissionInfoVal(permissionName): number { + for (let i = 0; i < permissionsDetailList.length; i++) { + if (permissionsDetailList[i].permissionName == permissionName) { + return i; + } + } + return -1; + } + + async getPermissionList(data, appInfo) { + let permissions = data.reqPermissions; + if (permissions != null && permissions != []) { + console.log('adminprovisioning getPermissionList permission length:' + permissions.length); + for (var i = 0; i < permissions.length; i++) { + console.log('adminprovisioning getPermissionList permission is in val:' + permissions[i]); + let j = this.getPermissionInfoVal(permissions[i]); + if (j >= 0) { + appInfo.appPermissionList.push({ + permissionName: permissionsDetailList[j].permissionName, + permissionLabel: permissionsDetailList[j].permissionLabel, + permissionDescription: permissionsDetailList[j].permissionDescription, + }); + } + } + console.log('adminprovisioning getPermissionList permission appInfo.appPermissionList:' + + JSON.stringify(appInfo.appPermissionList)); + } + console.log('adminprovisioning getPermissionList permission out'); + } +} + +let appDetailData = new AppDetailData(); + +export default appDetailData as AppDetailData; \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/model/baseData.ets b/entry/src/main/ets/MainAbility/model/baseData.ets new file mode 100755 index 0000000..df7cbbe --- /dev/null +++ b/entry/src/main/ets/MainAbility/model/baseData.ets @@ -0,0 +1,24 @@ +/* + * 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 class BaseData { + USE_ID = 100; + SELF_BUNDLE_NAME = 'com.ohos.adminprovisioning'; + MAX_LEN = 30; +} + +let baseData = new BaseData(); + +export default baseData as BaseData; \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/pages/applicationInfo.ets b/entry/src/main/ets/MainAbility/pages/applicationInfo.ets new file mode 100755 index 0000000..30d710f --- /dev/null +++ b/entry/src/main/ets/MainAbility/pages/applicationInfo.ets @@ -0,0 +1,367 @@ +/* + * 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 abilityFeatureAbility from '@ohos.ability.featureAbility'; +import edmEnterpriseDeviceManager from '@ohos.edm.enterpriseDeviceManager'; +import resourceManager from '@ohos.resourceManager'; +import router from '@system.router'; +import appDetailData from '../model/appManagementImpl/appDetailData.ets' +import baseData from '../model/baseData.ets'; +import entryComponent from './component/entryComponent.ets' +import headComponent from './component/headComponent.ets'; +import permissionListComponent from './component/permissionListComponent.ets'; + +let appInfo; +let elementNameVal; +let isAdminTypeVal; +let isActiveState; +let enterInfo; + +@Entry +@Component +struct ApplicationInfo { + @StorageLink('applicationInfo') applicationInfo: any = {}; + @State isShowActive: boolean = false; + @State isEnableButton: boolean = false; + @StorageLink('activeType') isAdminType: number = 0; + @State deviceAdminActive: string = ''; + @State deviceAdminDisActive: string = ''; + @State enterpriseName: string = ''; + @State enterpriseDescription: string = ''; + + build() { + Column() { + headComponent({ headName: $r('app.string.adminprovisioning') }); + + Row() { + entryComponent({ + appIcon: this.applicationInfo.appIcon, + appTitle: this.applicationInfo.appTitle, + }) + } + + Column() { + Text(this.enterpriseName) + .fontColor($r('app.color.color_333333_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }); + + Text(this.enterpriseDescription) + .fontColor($r('app.color.color_333333_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }); + } + .width('100%') + .alignItems(HorizontalAlign.Start) + .align(Alignment.Start) + + Column() { + Text(this.isShowActive ? this.deviceAdminActive : this.deviceAdminDisActive) + .fontColor($r('app.color.color_333333_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }); + + List() { + ForEach(appInfo.appPermissionList, (item) => { + ListItem() { + permissionListComponent({ + permissionName: item.permissionLabel, + permissionDescription: item.permissionDescription, + }); + } + }, item => JSON.stringify(item)); + } + } + .alignItems(HorizontalAlign.Start) + .align(Alignment.Start) + .layoutWeight(1) + + Row() { + Button() { + Text(this.isShowActive ? $r('app.string.deActivate') : $r('app.string.activation')) + .fontSize($r('app.float.font_20')) + .fontColor(this.isEnableButton ? Color.Blue : $r('app.color.color_999999_grey')) + } + .enabled(this.isEnableButton) + .backgroundColor($r('app.color.color_E3E3E3_grey')) + .height($r('app.float.button_height')) + .width($r('app.float.button_width')) + .margin({ + right: $r('app.float.wh_value_20'), + bottom: $r('app.float.wh_value_5'), + left: $r('app.float.wh_value_20') + }) + .onClick(() => { + console.log('adminprovisioning ApplicationInfo in button active:' + this.isShowActive); + this.activateAdmin(this.isAdminType); + }) + + Button() { + Text($r('app.string.cancel')) + .fontSize($r('app.float.font_20')) + .fontColor(Color.Blue) + } + .backgroundColor($r('app.color.color_E3E3E3_grey')) + .height($r('app.float.button_height')) + .width($r('app.float.button_width')) + .margin({ left: $r('app.float.wh_value_20'), bottom: $r('app.float.wh_value_5') }) + .onClick(() => { + console.log('adminprovisioning ApplicationInfo button cancel in isShowActive:' + this.isShowActive); + appDetailData.terminateAbilityPage(); + }) + } + .alignItems(VerticalAlign.Center) + } + } + + private aboutToAppear(): void { + appInfo = { + appIcon: '', + appTitle: '', + appBundleName: '', + appPermissionList: [], + }; + + elementNameVal = { + abilityName: '', + bundleName: '', + }; + + enterInfo = { + name: '', + description: '', + }; + + isAdminTypeVal = { admintype: 0 }; + console.log('adminprovisioning ApplicationInfo aboutToAppear in'); + this.getCheckAbilityList(appInfo, elementNameVal, isAdminTypeVal); + console.log('adminprovisioning ApplicationInfo aboutToAppear out'); + } + + private aboutToDisappear(): void { + console.log('adminprovisioning ApplicationInfo aboutToDisappear'); + } + + onPageShow(): void { + console.log('adminprovisioning ApplicationInfo onPageShow in'); + this.isAdminActive(); + console.log('adminprovisioning ApplicationInfo onPageShow isActiveState =' + isActiveState); + if (isActiveState == undefined || isActiveState == null) { + return; + } + this.isShowActive = isActiveState; + console.log('adminprovisioning ApplicationInfo onPageShow out'); + } + + onPageHide() { + console.log('adminprovisioning ApplicationInfo onPageHide'); + } + + onBackPress() { + console.log('adminprovisioning ApplicationInfo onBackPress'); + router.back(); + } + + async isAdminActive() { + let wantTemp = { + bundleName: elementNameVal.bundleName, + abilityName: elementNameVal.abilityName, + }; + let retAppState; + let retSuperState; + console.log('adminprovisioning isAdminActive elementNameVal.bundleName=' + elementNameVal.bundleName + + ' | elementNameVal.abilityName=' + elementNameVal.abilityName); + if (elementNameVal.bundleName == '' || elementNameVal.abilityName == '') { + console.log('adminprovisioning isAdminActive elementNameVal is null'); + return; + } + + retAppState = await edmEnterpriseDeviceManager.isAdminAppActive(wantTemp); + retSuperState = await edmEnterpriseDeviceManager.isSuperAdmin(elementNameVal.bundleName); + if (retAppState == false) { + this.isShowActive = false; + this.isEnableButton = true; + } else { + if (retSuperState == true) { + this.isEnableButton = false; + } else { + this.isEnableButton = true; + } + this.isShowActive = true; + } + console.log('adminprovisioning isAdminActive retAppState:' + retAppState + + ' | retSuperState:' + retSuperState); + isActiveState = this.isShowActive; + } + + async activateAdmin(adminType) { + console.log('adminprovisioning activateAdmin isShowActive:' + this.isShowActive); + let wantTemp = { + bundleName: elementNameVal.bundleName, + abilityName: elementNameVal.abilityName, + }; + await this.isAdminActive(); + let ret; + if (this.isShowActive == false) { + if (adminType == edmEnterpriseDeviceManager.AdminType.ADMIN_TYPE_NORMAL) { + ret = await edmEnterpriseDeviceManager.activateAdmin(wantTemp, + { name: enterInfo.name, description: enterInfo.description }, + edmEnterpriseDeviceManager.AdminType.ADMIN_TYPE_NORMAL); + } else { + ret = await edmEnterpriseDeviceManager.activateAdmin(wantTemp, + { name: enterInfo.name, description: enterInfo.description }, + edmEnterpriseDeviceManager.AdminType.ADMIN_TYPE_SUPER); + } + console.log('adminprovisioning activateAdmin Activate admin end'); + } else { + if (this.isEnableButton == true) { + ret = await edmEnterpriseDeviceManager.deactivateAdmin(wantTemp); + } else { + console.log('adminprovisioning activateAdmin not support super admin active'); + } + } + console.log('adminprovisioning activateAdmin adminType:' + adminType + ' | ret:' + ret); + appDetailData.terminateAbilityPage(); + } + + async getSelfResourceVal(resource) { + let item = await resourceManager.getResourceManager(baseData.SELF_BUNDLE_NAME); + console.log('adminprovisioning getSelfResourceVal in:'); + let value = await item.getString(resource.id); + console.log('adminprovisioning getSelfResourceVal finish value:' + value); + if (value == undefined || value == null || value == '') { + return ''; + } + return value; + } + + async getAbilityWantVal(appInfo, elementNameVal, adminType) { + console.log('adminprovisioning ApplicationInfo getAbilityWantVal in:'); + let data = await abilityFeatureAbility.getWant(); + let lengthVal = Object.keys(data.parameters).length; + let includeElementNameVal = Object.keys(data.parameters).indexOf('elementName'); + let includeActiveTypeVal = Object.keys(data.parameters).indexOf('activeType'); + let includeEnterpriseVal = Object.keys(data.parameters).indexOf('enterprise'); + if (lengthVal == 0 || includeElementNameVal == -1 || includeActiveTypeVal == -1 || + includeEnterpriseVal == -1) { + console.log('adminprovisioning data.parameters = ' + JSON.stringify(data.parameters)); + return; + } + elementNameVal.abilityName = data.parameters.elementName.abilityName; + elementNameVal.bundleName = data.parameters.elementName.bundleName; + + appInfo.appBundleName = data.parameters.elementName.bundleName; + adminType.admintype = data.parameters.activeType; + AppStorage.SetOrCreate('activeType', adminType.admintype); + + if (data.parameters.enterprise.name != null && data.parameters.enterprise.name != undefined) { + enterInfo.name = data.parameters.enterprise.name.substring(0, baseData.MAX_LEN); + } + + if (data.parameters.enterprise.description != null && + data.parameters.enterprise.description != undefined) { + enterInfo.description = data.parameters.enterprise.description.substring(0, baseData.MAX_LEN); + } + + console.log('adminprovisioning ApplicationInfo getAbilityWantVal out isAdminTypeVal.admintype:' + + isAdminTypeVal.admintype + ' enter.name=' + enterInfo.name + ' enter.des=' + enterInfo.description); + } + + async getCheckAbilityList(appInfo, elementNameVal, adminType) { + let deviceActiveOne = ''; + let deviceActiveTwo = ''; + let deviceDeactivate = ''; + let enterName = ''; + let enterDescription = ''; + let getName = ''; + let getDescription = ''; + console.log('adminprovisioning ApplicationInfo getCheckAbilityList in:'); + await this.getAbilityWantVal(appInfo, elementNameVal, adminType); + + let ret = await appDetailData.checkAppItem(elementNameVal); + if (!ret.val) { + console.log('adminprovisioning ApplicationInfo aboutToAppear not exist bundleName:' + appInfo.appBundleName); + appDetailData.terminateAbilityPage(); + return; + } + + await this.isAdminActive(); + + if (appInfo.appBundleName) { + await appDetailData.getBundleInfoItem(appInfo.appBundleName, appInfo); + } + + deviceActiveOne = await this.getSelfResourceVal($r('app.string.device_active_1')); + deviceActiveTwo = await this.getSelfResourceVal($r('app.string.device_active_2')); + deviceDeactivate = await this.getSelfResourceVal($r('app.string.device_deactivate')); + enterName = await this.getSelfResourceVal($r('app.string.enterprise_name')); + enterDescription = await this.getSelfResourceVal($r('app.string.enterprise_description')); + this.deviceAdminActive = deviceActiveOne + `${appInfo.appTitle}` + deviceActiveTwo; + this.deviceAdminDisActive = deviceDeactivate + `${appInfo.appTitle}` + deviceActiveTwo; + + let want = { + bundleName: elementNameVal.bundleName, + abilityName: elementNameVal.abilityName, + }; + let getEnterInfo = { + name: '', + description: '', + }; + if (this.isShowActive) { + console.log('adminprovisioning ApplicationInfo getCheckAbilityList getEnterInfo err=' + JSON.stringify(getEnterInfo)); + getEnterInfo = await edmEnterpriseDeviceManager.getEnterpriseInfo(want); + } + + console.log('adminprovisioning ApplicationInfo getCheckAbilityList enterpriseName=' + getEnterInfo.name + + ' enterpriseDescription=' + getEnterInfo.description); + if (getEnterInfo.name != null && getEnterInfo.name != undefined) { + getName = getEnterInfo.name.substring(0, baseData.MAX_LEN); + } + if (getEnterInfo.description != null && getEnterInfo.description != undefined) { + getDescription = getEnterInfo.description.substring(0, baseData.MAX_LEN); + } + + if (this.isShowActive) { + this.enterpriseName = enterName + getName; + this.enterpriseDescription = enterDescription + getDescription; + } else { + this.enterpriseName = enterName + enterInfo.name; + this.enterpriseDescription = enterDescription + enterInfo.description; + } + console.log('adminprovisioning ApplicationInfo getCheckAbilityList enterpriseName=' + this.enterpriseName + + ' enterpriseDescription=' + this.enterpriseDescription); + } +} \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/pages/component/entryComponent.ets b/entry/src/main/ets/MainAbility/pages/component/entryComponent.ets new file mode 100755 index 0000000..678e229 --- /dev/null +++ b/entry/src/main/ets/MainAbility/pages/component/entryComponent.ets @@ -0,0 +1,46 @@ +/* + * 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. + */ + +@Component +export default struct EntryComponent { + @Prop appIcon: string; + @Prop appTitle: string; + + build() { + Flex({ justifyContent: FlexAlign.SpaceBetween }) { + Row() { + Image(this.appIcon) + .width($r('app.float.wh_value_50')) + .height($r('app.float.wh_value_50')) + .margin({ right: $r('app.float.wh_value_10') }) + .visibility('' === this.appIcon ? Visibility.None : Visibility.Visible) + .objectFit(ImageFit.Contain); + + Text(this.appTitle) + .fontColor($r('app.color.color_333333_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .margin({ top: $r('app.float.wh_value_10'), bottom: $r('app.float.wh_value_5') }); + } + .flexShrink(0) + .alignItems(VerticalAlign.Center) + .align(Alignment.Start) + } + .margin({ left: $r('app.float.wh_value_15') }) + .width('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/pages/component/headComponent.ets b/entry/src/main/ets/MainAbility/pages/component/headComponent.ets new file mode 100755 index 0000000..022a85d --- /dev/null +++ b/entry/src/main/ets/MainAbility/pages/component/headComponent.ets @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@system.router'; + +@Entry +@Component +export default struct HeadComponent { + private headName: string = ''; + + build() { + Row() { + Image($r('app.media.ic_back')) + .width($r('app.float.wh_value_50')) + .height($r('app.float.wh_value_50')) + .borderRadius($r('app.float.wh_value_15')) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }) + .backgroundColor($r('app.color.color_00000000_transparent')) + .visibility(Visibility.Visible) + .onTouch(() => { + router.back(); + }) + Text(this.headName) + .fontSize($r('app.float.font_24')) + .fontWeight(FontWeight.Bold) + .fontColor(Color.Black) + .width('90%') + .maxLines(1) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .margin({ left: $r('app.float.wh_value_15'), right: $r('app.float.wh_value_15') }) + } + .width('100%') + .height($r('app.float.wh_value_70')) + .alignItems(VerticalAlign.Center) + .align(Alignment.Start) + } +} \ No newline at end of file diff --git a/entry/src/main/ets/MainAbility/pages/component/permissionListComponent.ets b/entry/src/main/ets/MainAbility/pages/component/permissionListComponent.ets new file mode 100755 index 0000000..efcb26d --- /dev/null +++ b/entry/src/main/ets/MainAbility/pages/component/permissionListComponent.ets @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@Component +export default struct PermissionListComponent { + private permissionName: string = ''; + private permissionDescription: string = ''; + + build() { + Row() { + Column() { + Text(this.permissionName) + .fontColor($r('app.color.color_333333_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .visibility('' === this.permissionName || undefined === this.permissionName + ? Visibility.None : Visibility.Visible) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }); + + Text(this.permissionDescription) + .fontColor($r('app.color.color_999999_grey')) + .fontSize($r('app.float.font_20')) + .textAlign(TextAlign.Start) + .maxLines(3) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .visibility('' === this.permissionDescription || undefined === this.permissionDescription + ? Visibility.None : Visibility.Visible) + .margin({ + left: $r('app.float.wh_value_15'), + top: $r('app.float.wh_value_5'), + bottom: $r('app.float.wh_value_5') + }); + } + .alignItems(HorizontalAlign.Start) + } + .align(Alignment.Start) + .alignItems(VerticalAlign.Center) + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json new file mode 100755 index 0000000..f511550 --- /dev/null +++ b/entry/src/main/resources/base/element/color.json @@ -0,0 +1,24 @@ +{ + "color": [ + { + "name": "color_333333_grey", + "value": "#333333" + }, + { + "name": "color_666666_grey", + "value": "#666666" + }, + { + "name": "color_999999_grey", + "value": "#999999" + }, + { + "name": "color_E3E3E3_grey", + "value": "#E3E3E3" + }, + { + "name": "color_00000000_transparent", + "value": "#00000000" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/float.json b/entry/src/main/resources/base/element/float.json new file mode 100755 index 0000000..8f424b7 --- /dev/null +++ b/entry/src/main/resources/base/element/float.json @@ -0,0 +1,121 @@ +{ + "float": [ + { + "name": "wh_value_1", + "value": "1" + }, + { + "name": "wh_value_5", + "value": "5" + }, + { + "name": "wh_value_10", + "value": "10" + }, + { + "name": "wh_value_15", + "value": "15" + }, + { + "name": "wh_value_20", + "value": "20" + }, + { + "name": "wh_value_30", + "value": "30" + }, + { + "name": "wh_value_40", + "value": "40" + }, + { + "name": "wh_value_50", + "value": "50" + }, + { + "name": "wh_value_60", + "value": "60" + }, + { + "name": "wh_value_65", + "value": "65" + }, + { + "name": "wh_value_70", + "value": "70" + }, + { + "name": "wh_value_80", + "value": "80" + }, + { + "name": "wh_value_100", + "value": "100" + }, + { + "name": "wh_value_130", + "value": "130" + }, + { + "name": "wh_value_160", + "value": "160" + }, + { + "name": "wh_value_230", + "value": "230" + }, + { + "name": "wh_value_280", + "value": "280" + }, + { + "name": "wh_value_390", + "value": "390" + }, + { + "name": "wh_value_400", + "value": "400" + }, + { + "name": "font_35", + "value": "35" + }, + { + "name": "font_18", + "value": "18" + }, + { + "name": "font_20", + "value": "20" + }, + { + "name": "font_21", + "value": "21" + }, + { + "name": "font_22", + "value": "22" + }, + { + "name": "font_24", + "value": "24" + }, + { + "name": "font_28", + "value": "28" + }, + { + "name": "font_50", + "value": "50" + }, + { + "name": "button_width", + "value": "160" + }, + { + "name": "button_height", + "value": "40" + } + + ] +} \ 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 100755 index 0000000..9095d01 --- /dev/null +++ b/entry/src/main/resources/base/element/string.json @@ -0,0 +1,60 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "设备管理配置" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + }, + { + "name": "adminprovisioning", + "value": "设备管理配置" + }, + { + "name": "appManagement", + "value": "应用管理" + }, + { + "name": "description_appmanagementmodel", + "value": "hap sample empty service" + }, + { + "name": "activation", + "value": "激活" + }, + { + "name": "deActivate", + "value": "解除激活" + }, + { + "name": "cancel", + "value": "取消" + }, + { + "name": "inActivated", + "value": "未激活" + }, + { + "name": "device_active_1", + "value": "此管理器已激活,允许应用\"" + }, + { + "name": "device_active_2", + "value": "\"执行以下操作:" + }, + { + "name": "device_deactivate", + "value": "激活此管理器可允许应用\"" + }, + { + "name": "enterprise_name", + "value": "enterprise name:" + }, + { + "name": "enterprise_description", + "value": "enterprise description:" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/media/ic_back.svg b/entry/src/main/resources/base/media/ic_back.svg new file mode 100755 index 0000000..efbe194 --- /dev/null +++ b/entry/src/main/resources/base/media/ic_back.svg @@ -0,0 +1,18 @@ + + + + + diff --git a/entry/src/main/resources/base/media/ic_settings_arrow.svg b/entry/src/main/resources/base/media/ic_settings_arrow.svg new file mode 100755 index 0000000..ff6293c --- /dev/null +++ b/entry/src/main/resources/base/media/ic_settings_arrow.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + diff --git a/entry/src/main/resources/base/media/icon.png b/entry/src/main/resources/base/media/icon.png new file mode 100755 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/en_AS/element/string.json b/entry/src/main/resources/en_AS/element/string.json new file mode 100755 index 0000000..266c08a --- /dev/null +++ b/entry/src/main/resources/en_AS/element/string.json @@ -0,0 +1,60 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "Device Management Configuration" + }, + { + "name": "description_mainability", + "value": "ETS_Empty Ability" + }, + { + "name": "adminprovisioning", + "value": "Device Management Configuration" + }, + { + "name": "appManagement", + "value": "Application Management" + }, + { + "name": "description_appmanagementmodel", + "value": "hap sample empty service" + }, + { + "name": "activation", + "value": "activate" + }, + { + "name": "deActivate", + "value": "Deactivate" + }, + { + "name": "cancel", + "value": "cancel" + }, + { + "name": "inActivated", + "value": "Inactive" + }, + { + "name": "device_active_1", + "value": "This device administrator is currently active and allows \"" + }, + { + "name": "device_active_2", + "value": "\" to perform the following operations:" + }, + { + "name": "device_deactivate", + "value": "Activating this administrator will allow \"" + }, + { + "name": "enterprise_name", + "value": "enterprise name:" + }, + { + "name": "enterprise_description", + "value": "enterprise description:" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json new file mode 100755 index 0000000..ca3929d --- /dev/null +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,60 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "设备管理配置" + }, + { + "name": "description_mainability", + "value": "ETS空能力" + }, + { + "name": "adminprovisioning", + "value": "设备管理配置" + }, + { + "name": "appManagement", + "value": "应用管理" + }, + { + "name": "description_appmanagementmodel", + "value": "hap样例空服务" + }, + { + "name": "activation", + "value": "激活" + }, + { + "name": "deActivate", + "value": "解除激活" + }, + { + "name": "cancel", + "value": "取消" + }, + { + "name": "inActivated", + "value": "未激活" + }, + { + "name": "device_active_1", + "value": "此管理器已激活,允许应用\"" + }, + { + "name": "device_active_2", + "value": "\"执行以下操作:" + }, + { + "name": "device_deactivate", + "value": "激活此管理器可允许应用\"" + }, + { + "name": "enterprise_name", + "value": "企业名字:" + }, + { + "name": "enterprise_description", + "value": "企业描述:" + } + ] +} \ No newline at end of file diff --git a/figures/adminProvisioning_architecture.png b/figures/adminProvisioning_architecture.png new file mode 100755 index 0000000..65c1e42 Binary files /dev/null and b/figures/adminProvisioning_architecture.png differ diff --git a/gradle.properties b/gradle.properties new file mode 100755 index 0000000..be49249 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,13 @@ +# Project-wide Gradle settings. +# IDE (e.g. DevEco Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# If the Chinese output is garbled, please configure the following parameter. +# This function is enabled by default when the DevEco Studio builds the hap/app,if you need disable gradle parallel,you should set org.gradle.parallel false. +# more information see https://docs.gradle.org/current/userguide/performance.html +# org.gradle.parallel=false +# org.gradle.jvmargs=-Dfile.encoding=GBK \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100755 index 0000000..62bd9b9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/local.properties b/local.properties new file mode 100755 index 0000000..25dd674 --- /dev/null +++ b/local.properties @@ -0,0 +1,12 @@ +## 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. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=XXX +nodejs.dir=XXX +npm.dir=XXX diff --git a/package.json b/package.json new file mode 100755 index 0000000..69a88e3 --- /dev/null +++ b/package.json @@ -0,0 +1 @@ +{} diff --git a/settings.gradle b/settings.gradle new file mode 100755 index 0000000..28d595f --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/signature/adminprovisioning.p7b b/signature/adminprovisioning.p7b new file mode 100755 index 0000000..1df4afe Binary files /dev/null and b/signature/adminprovisioning.p7b differ