Signed-off-by: zhuchengfeng <940848916@qq.com>
This commit is contained in:
zhuchengfeng 2022-03-08 16:45:48 +08:00
parent d228705e02
commit 3968f3dd2f
172 changed files with 8982 additions and 39 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
*.tgz filter=lfs diff=lfs merge=lfs -text
*.trp filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.asm filter=lfs diff=lfs merge=lfs -text
*.8svn filter=lfs diff=lfs merge=lfs -text
*.9svn filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/product/phone/build
/product/pc/build
/common/build
/build/
/features/batterycomponent/build/
/features/noticeitem/build/
/features/notificationservice/build/
/features/screenlock/build/
/.idea
/.gradle
local.properties

View File

@ -1,39 +0,0 @@
# applications_screenlock
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

46
README_zh.md Normal file
View File

@ -0,0 +1,46 @@
# 锁屏<a name="ZH-CN_TOPIC_0000001103330836"></a>
- [简介](#section11660541593)
- [架构图](#section125101832114213)
- [目录](#section161941989596)
- [相关仓](#section1371113476307)
## 简介<a name="section11660541593"></a>
锁屏应用是OpenHarmony中预置的系统应用为用户提供锁屏的基础能力提供滑动解锁密码解锁等解锁能力以及锁屏页面的信息展示。
### 架构图<a name="section125101832114213"></a>
![](figures/screenlock.png)
## 目录<a name="section161941989596"></a>
```
/applications/standard/screenlock
├── build.gradle # 全局编译配置文件
├── settings.gradle # 编译模块配置文件
├── LICENSE # 许可文件
├── common # 通用工具类目录
├── signature # 证书文件目录
├── features # 子组件目录
│ ├── batterycomponent # 电池组件
│ ├── noticeitem # 通知子组件
│ ├── notificationservice # 通知服务组件
│ ├── screenlock # 锁屏组件
│ ├── common # 通用工具
│ ├── model # 数据管理
│ ├── view # 组件样式管理
│ ├── vm # 数据样式绑定管理
├── product # 锁屏总体功能目录
│ ├── pc # 模块目录
│ ├── pages/slidesrceenlock # 滑动锁屏
│ ├── phone # 模块目录
│ ├── pages/slidesrceenlock # 滑动锁屏
```
## 相关仓<a name="section1371113476307"></a>
系统应用
**applications\_screenlock**

40
build.gradle Normal file
View File

@ -0,0 +1,40 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.huawei.ohos.app'
apply from: "./infra/config_exts.gradle"
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
supportSystem "standard"
}
buildscript {
repositories {
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
maven {
url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/'
allowInsecureProtocol = true
}
}
dependencies {
classpath 'com.huawei.ohos:hap:3.0.5.2'
}
}
allprojects {
repositories {
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
}
}

21
common/build.gradle Normal file
View File

@ -0,0 +1,21 @@
apply plugin: 'com.huawei.ohos.library'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
entryModules "phone"
}
dependencies {
}

View File

@ -0,0 +1,24 @@
{
"app": {
"bundleName": "com.ohos.screenlock",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {
},
"module": {
"package": "com.ohos.screenlock.common",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "common",
"moduleType": "har"
},
"srcPath": "default"
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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 CheckEmptyUtils {
/**
* Check obj is empty.
*
* @param {Object} obj need checked object
* @return {boolean} true(empty)
*/
static isEmpty(obj) {
return (typeof obj === 'undefined' || obj === null || obj === '' || Object.keys(obj).length === 0);
}
/**
* Check str is empty.
*
* @param {string} str need checked string
* @return {boolean} true(empty)
*/
static checkStrIsEmpty(str) {
return str.trim().length === 0;
}
/**
* Check array is empty.
*
* @param {Array} arr need checked array
* @return {boolean} true(empty)
*/
static isEmptyArr(arr) {
return arr.length === 0;
}
}

View File

@ -0,0 +1,84 @@
/**
* Copyright (c) 2021 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 DateTimeCommon {
getSystemTime(isUsing24hFormat: boolean) {
let dateTime = new Date();
let hours = dateTime.getHours();
if (!isUsing24hFormat && hours > 12) {
hours = hours % 12;
}
let minutes = dateTime.getMinutes();
let time = this.concatTime(hours, minutes)
return time;
}
getSystemDate(): {} {
let dateTime = new Date();
let result = {
'year': dateTime.getFullYear(),
'month': dateTime.getMonth() + 1,
'day': dateTime.getDate()
}
return result
}
getSystemWeek() {
let dateTime = new Date();
let days = dateTime.getDay();
let week = this.convert(days)
return week
}
concatTime(hours, minutes): string{
return `${this.fill(hours)}:${this.fill(minutes)}`;
};
fill(value) {
return (value > 9 ? "" : "0") + value;
};
convert(days) {
switch (days) {
case 0:
return $r('app.string.sunday');
break;
case 1:
return $r('app.string.monday');
break;
case 2:
return $r('app.string.tuesday');
break;
case 3:
return $r('app.string.wednesday');
break;
case 4:
return $r('app.string.thursday');
break;
case 5:
return $r('app.string.friday');
break;
case 6:
return $r('app.string.saturday');
break;
default:
break;
}
}
}
let dateTimeCommon = new DateTimeCommon();
export default dateTimeCommon as DateTimeCommon

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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.
*/
const TAG = 'ScreenLock-Default';
/**
* Basic log class
*/
export default class Log {
/**
* print info level log
*
* @param {string} tag - Page or class tag
* @param {string} log - Log needs to be printed
*/
static showInfo(tag, log) {
console.info(`${TAG} tag: ${tag} --> ${log}`);
}
/**
* print debug level log
*
* @param {string} tag - Page or class tag
* @param {string} log - Log needs to be printed
*/
static showDebug(tag, log) {
console.debug(`${TAG} tag: ${tag} --> ${log}`);
}
/**
* print error level log
*
* @param {string} tag - Page or class tag
* @param {string} log - Log needs to be printed
*/
static showError(tag, log) {
console.error(`${TAG} tag: ${tag} --> ${log}`);
}
}

View File

@ -0,0 +1,49 @@
/**
* Copyright (c) 2021 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 Log from './Log.ets';
import FileIo from '@ohos.fileio';
const DFAULT_SIZE = 4096;
const CHAR_CODE_AT_INDEX = 0;
const TAG = 'ReadConfigUtil';
export class ReadConfigUtil {
ReadConfigFile(fileName) {
Log.showInfo(TAG, `readConfigFile fileName:${fileName}`);
try {
let stream = FileIo.createStreamSync(fileName, 'r');
Log.showInfo(TAG, `readConfigFile stream:` + stream);
let buf = new ArrayBuffer(DFAULT_SIZE);
let len = stream.readSync(buf);
Log.showInfo(TAG, `readConfigFile len:` + len);
let arr = new Uint8Array(buf);
let charAt = ' '.charCodeAt(CHAR_CODE_AT_INDEX);
for (let i = len;i < DFAULT_SIZE; i++) {
arr[i] = charAt;
}
let content = String.fromCharCode.apply(null, arr);
stream.closeSync();
Log.showInfo(TAG, `readConfigFile content:` + JSON.stringify(content));
return JSON.parse(content);
} catch (error) {
Log.showInfo(TAG, `readConfigFile error:` + JSON.stringify(error));
}
}
}
let readConfigUtil = new ReadConfigUtil();
export default readConfigUtil as ReadConfigUtil

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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 Log from './Log.ets';
import FileIo from '@ohos.fileio';
const TAG = 'ScreenLock-ScreenLockCommon';
const DFAULT_SIZE = 4096;
const CHAR_CODE_AT_INDEX = 0;
export enum ScreenLockStatus {
Locking = 1,
Unlock = 2
}
export function ReadConfigFile(fileName) {
Log.showInfo(TAG, `readConfigFile fileName:${fileName}`);
try {
let stream = FileIo.createStreamSync(fileName, 'r');
Log.showInfo(TAG, `readConfigFile stream:` + stream);
let buf = new ArrayBuffer(DFAULT_SIZE);
let len = stream.readSync(buf);
Log.showInfo(TAG, `readConfigFile len:` + len);
let arr = new Uint8Array(buf);
let charAt = ' '.charCodeAt(CHAR_CODE_AT_INDEX);
for (let i = len;i < DFAULT_SIZE; i++) {
arr[i] = charAt;
}
let content = String.fromCharCode.apply(null, arr);
stream.closeSync();
Log.showInfo(TAG, `readConfigFile content:` + JSON.stringify(content));
return JSON.parse(content);
} catch (error) {
Log.showInfo(TAG, `readConfigFile error:` + JSON.stringify(error));
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 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 Window from '@ohos.window';
import display from '@ohos.display'
import Log from './Log.ets';
const TAG = 'WindowManager';
//const STATUS_BAR_H = 0.07;
const STATUS_BAR_H = 0.03;
var maxWidth;
var maxHeight;
var minHeight;
var quicklySettingH;
var notificationH;
/**
* Manage window size changes.
*/
export default class WindowManager {
initWindowManager() {
Log.showInfo(TAG, 'initWindowManager ');
maxWidth = AppStorage.SetAndLink("maxWidth", 0);
maxHeight = AppStorage.SetAndLink("maxHeight", 0);
minHeight = AppStorage.SetAndLink("minHeight", 0);
display.getDefaultDisplay()
.then(dis => {
maxWidth.set(dis.width);
maxHeight.set(dis.height);
minHeight.set(this.getStatusBarDefaultHeight(dis.height));
Log.showInfo(TAG, `initWindowManager maxWidth ${maxWidth.get()} maxHeight ${maxHeight.get()} minHeight ${minHeight.get()}`);
})
}
/**
* Set the window to the maximum size.
*
* @param {Object} callback - Callback function.
*/
setWindowMax(callback) {
Log.showInfo(TAG, 'enter setWindowMax =================');
Window.getTopWindow()
.then((windowData) => {
windowData.resetSize(maxWidth.get(), maxHeight.get())
.then((result) => {
Log.showInfo(TAG, result);
callback(result);
});
});
}
/**
* Set the window to the minimum size.
*
* @param {Object} callback - Callback function.
*/
setWindowMin(callback) {
Log.showInfo(TAG, 'enter setWindowMin =================');
Window.getTopWindow()
.then((windowData) => {
windowData.resetSize(maxWidth.get(), minHeight.get())
.then((result) => {
Log.showInfo(TAG, result);
callback(result);
});
});
}
getStatusBarDefaultHeight(maxheight) {
return parseInt((maxheight * STATUS_BAR_H).toString())
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 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 BundleMgr from '@ohos.bundle';
import Resmgr from '@ohos.resourceManager';
import Log from '../Log.ets';
const TAG = 'BRManager';
export default class BundleManager {
static getResourceManager(tag, bundleName, then) {
Log.showInfo(TAG, `getResourceManager from: ${tag}`);
Resmgr.getResourceManager(bundleName).then(then);
}
static getBundleInfo(tag, bundleName, getInfo, then) {
Log.showInfo(TAG, `getBundleInfo from: ${tag}`);
BundleMgr.getBundleInfo(bundleName, getInfo).then(then);
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2021 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 FeatureAbility from '@ohos.ability.featureAbility';
import Log from '../Log.ets';
const TAG = 'FeatureAbilityManager';
export default class FeatureAbilityManager {
openAbility(tag, want) {
Log.showInfo(TAG, `openAbility from: ${tag}`);
let result = FeatureAbility.startAbility(want)
.then(data =>
Log.showInfo(TAG, `tag: ${tag} promise then: ${JSON.stringify(data)}`))
.catch(error =>
Log.showError(TAG, `tag: ${tag} promise catch: ${JSON.stringify(error)}`));
Log.showInfo(TAG, `tag: ${tag} openAbility result: ${result}`);
}
getAbilityWant(listener) {
FeatureAbility.getWant((err, data) => {
Log.showInfo(TAG, `getAbilityWant callBack err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`);
if (err.code !== 0) {
Log.showError(TAG, `failed to getAbilityWant because ${err.message}`);
return;
} else {
if(listener != null && listener != undefined) {
listener(data);
}
}
});
}
finishAbilityWithResult(abilityResult) {
FeatureAbility.finishWithResult(abilityResult, (err, data) => {
if (err.code !== 0) {
Log.showError(TAG, `failed to finishWithResult because ${JSON.stringify(err)}`);
return;
}
FeatureAbilityManager.finishAbility();
});
}
static finishAbility() {
FeatureAbility.terminateAbility((err, data) => {
if (err.code !== 0) {
Log.showError(TAG, `failed to finishAbility because ${JSON.stringify(err)}`);
return;
}
Log.showInfo(TAG, ` finishAbility callback err: ${JSON.stringify(err)} data:${data}`);
});
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 { NotificationSubscriber } from './notification/notificationSubscriber';
import Notification from '@ohos.notification';
import Log from '../Log.ets';
const TAG = 'NotificationManager';
export default class NotificationManager {
static TYPE_BASIC: number = Notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT;
static TYPE_LONG: number = Notification.ContentType.NOTIFICATION_CONTENT_LONG_TEXT;
static TYPE_MULTI: number = Notification.ContentType.NOTIFICATION_CONTENT_MULTILINE;
static subscribeNotification(tag, subscriber, asyncCallback) {
Log.showInfo(TAG, `subscribeNotification from: ${tag}`);
Notification.subscribe(subscriber, asyncCallback);
}
static unsubscribeNotification(tag, subscriber) {
Log.showInfo(TAG, `subscribeNotification from: ${tag}`);
Notification.unsubscribe(subscriber);
}
static removeAll(tag, callback) {
Log.showInfo(TAG, `removeAll from: ${tag}`);
Notification.removeAll(callback);
}
static remove(tag, hashCode, callback) {
Log.showInfo(TAG, `remove from: ${tag}`);
Notification.remove(hashCode, callback)
}
static getAllActiveNotifications(tag, callback) {
Log.showInfo(TAG, `getAllActiveNotifications from: ${tag}`);
Notification.getAllActiveNotifications(callback);
}
}

View File

@ -0,0 +1,40 @@
{
"string": [
{
"name": "app_name",
"value": "ScreenLock"
},
{
"name": "mainability_description",
"value": "JS_Phone_Empty Feature Ability"
},
{
"name": "monday",
"value": "星期一"
},
{
"name": "tuesday",
"value": "星期二"
},
{
"name": "wednesday",
"value": "星期三"
},
{
"name": "thursday",
"value": "星期四"
},
{
"name": "friday",
"value": "星期五"
},
{
"name": "saturday",
"value": "星期六"
},
{
"name": "sunday",
"value": "星期日"
}
]
}

2
entry/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
/node_modules

22
entry/build.gradle Normal file
View File

@ -0,0 +1,22 @@
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 rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
}

1
entry/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1 @@
# config module specific ProGuard rules here.

View File

@ -0,0 +1,64 @@
{
"app": {
"bundleName": "com.ohos.screenlock",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.screenlock",
"name": ".MyApplication",
"deviceType": [
"phone","tablet"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": false
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"visible": true,
"name": "com.ohos.screenlock.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard",
"srcPath": "MainAbility",
"srcLanguage": "ets"
}
],
"js": [
{
"mode": {
"syntax": "ets",
"type": "pageAbility"
},
"pages": [
"pages/index"
],
"name": "MainAbility",
"window": {
"designWidth": 720,
"autoDesignWidth": false
}
}
],
"srcPath": "MainAbility"
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import AbilityStage from "@ohos.application.AbilityStage"
import Log from '../../../../common/src/main/ets/default/Log.ets'
const TAG = "MainAbilityStage"
export default class MainAbilityStage extends AbilityStage {
onCreate() {
Log.showInfo(TAG, "onCreate")
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Ability from "@ohos.application.Ability"
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.info('API8 A onCreate')
}
onWindowStageCreate(windowStage) {
console.info('API8 A onWindowStageCreate')
windowStage.setUIContent(this.content, "pages/index", null)
}
onForeground() {
console.info('API8 A onForeground')
}
onBackground() {
console.info('API8 A onBackground')
}
onWindowStageDestroy() {
console.info('API8 A onWindowStageDestroy')
}
onDestroy() {
console.info('API8 A onDestroy')
}
}

View File

@ -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('Application onCreate')
},
onDestroy() {
console.info('Application onDestroy')
},
}

View File

@ -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.
*/
@Entry
@Component
struct Index {
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text('Hello World API8 A')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
.height('100%')
}
}

View File

@ -0,0 +1,12 @@
{
"string": [
{
"name": "entry_MainAbility",
"value": "entry_MainAbility"
},
{
"name": "mainability_description",
"value": "eTS_Empty Ability"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

1
features/batterycomponent/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,19 @@
apply plugin: 'com.huawei.ohos.library'
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
}

View File

@ -0,0 +1,23 @@
{
"app": {
"bundleName": "com.ohos.systemui",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.systemui.batterycomponent",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "batterycomponent",
"moduleType": "har"
},
"srcPath": "default"
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 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 {
//layout params - Icon
static WHOLE_CONTAINER_MARGIN = 2
static WHOLE_CONTAINER_WIDTH = 100
static WHOLE_CONTAINER_HEIGHT = 24
static PIC_CONTAINER_WIDTH = '70%'
static PIC_CONTAINER_HEIGHT = '85%'
//layout params - Pic
static FULL_CONTAINER_WIDTH = '100%'
static FULL_CONTAINER_HEIGHT = '100%'
static BATTERY_BORDER_WIDTH = '88%'
static BATTERY_BORDER_HEIGHT = '80%'
static BATTERY_BORDER_RADIUS = 2
static BATTERY_BORDER_MARGIN = 2
static BATTERY_CONTENT_PADDING = 2
static BATTERY_DECORATOR_WIDTH = '10%'
static BATTERY_DECORATOR_HEIGHT = '50%'
static BATTERY_DECORATOR_MARGIN = 2
//layout params - Soc
static SOC_FONT_SIZE = 16
//value
static BATTERY_LEVEL_LOW = 20
static NONE = 0;
static ENABLE = 1;
static DISABLE = 2;
static FULL = 3;
static PERCENT_NUMBER = 100;
static DEFAULT_PROGRESS = 100;
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2021 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('Application onCreate')
},
onDestroy() {
console.info('Application onDestroy')
},
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../common/src/main/ets/default/Log.ets';
import Constants from './common/constants.ets';
import BatteryInfo from '@ohos.batteryInfo';
import BatterySubscriber from '@ohos.commonEvent';
const TAG = 'BatteryComponent-batteryModel';
let mProgress = Constants.DEFAULT_PROGRESS;
let mBatteryEventSubscriber = null;
let mBatteryEventSubscribeInfo = {
events: ['usual.event.BATTERY_CHANGED']
}
var mBatterySoc;
var mBatteryCharging;
export class BatteryModel {
initBatteryModel() {
Log.showInfo(TAG, 'initBatteryModel');
mBatterySoc = AppStorage.SetAndLink('batterySoc', 0);
mBatteryCharging = AppStorage.SetAndLink('batteryCharging', false);
if (mBatteryEventSubscriber == null) {
this.registerBatteryListener();
}
this.getBatteryStatus();
}
uninitBatteryModel() {
Log.showInfo(TAG, 'uninitBatteryModel');
this.unregisterBatteryListener();
}
/**
* Subscribe Battery events
*/
private registerBatteryListener() {
Log.showInfo(TAG, 'registerBatteryListener start');
BatterySubscriber.createSubscriber(
mBatteryEventSubscribeInfo,
this.createBatterySubscriberCallBack.bind(this)
);
}
/**
* Unsubscribe wifi events
*
*/
private unregisterBatteryListener() {
Log.showInfo(TAG, 'unregisterBatteryListener');
BatterySubscriber.unsubscribe(mBatteryEventSubscriber, () => {
Log.showInfo(TAG, `unregister Battery Status Listener ===============`);
});
}
/**
* Callback of the subscriber
*
* @param {Object} err - error returns from the caller
* @param {Object} data - data returns from the caller
*/
private createBatterySubscriberCallBack(err, data) {
Log.showInfo(TAG, `Subscriberregister createBatterySubscriberCallBack err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`);
mBatteryEventSubscriber = data;
BatterySubscriber.subscribe(mBatteryEventSubscriber, this.batterySubscriberCallBack.bind(this));
}
/**
* Callback of the events
*
* @param {Object} err - error returns from the caller
* @param {Object} data - data returns from the caller
*/
private batterySubscriberCallBack(err, data) {
Log.showInfo(TAG, `batterySubscriberCallBack err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`);
if (err.code == 0) {
if (data.event == 'usual.event.BATTERY_CHANGED') {
this.getBatteryStatus();
}
} else {
Log.showInfo(TAG, 'Subscriberregister error when subscribing ========');
}
}
/**
* Get battery status and remaining power
*/
private getBatteryStatus() {
Log.showInfo(TAG,'getBatteryStatus')
let batterySoc = BatteryInfo.batterySOC;
let batteryCharging = BatteryInfo.chargingStatus;
if (null == batterySoc) {
// Set the battery Soc as full when there is no battery hardware
batterySoc = mProgress;
}
if (batterySoc <= 0) {
// If the result is a negative number, set it as positive number.
batterySoc = Math.abs(batterySoc) * Constants.PERCENT_NUMBER;
}
// Set the battery status as charging when there is no battery hardware
this.checkBatteryStatus(batteryCharging, (result) => {
let batteryStatus = result;
mBatterySoc.set(batterySoc);
mBatteryCharging.set(batteryStatus);
});
}
/**
* Check the battery charging status
*
* @param {number} charging - the battery charging status
* @param {object} callback - Function callback
*/
private checkBatteryStatus(charging, callback) {
Log.showInfo(TAG, `checkBatteryStatus charging: ${charging}`);
let batteryStatus;
switch (charging) {
case Constants.NONE:
batteryStatus = false;
break;
case Constants.DISABLE:
case Constants.ENABLE:
case Constants.FULL:
batteryStatus = true;
break;
default:
batteryStatus = false;
break;
}
callback(batteryStatus);
}
}
let mBatteryModel = new BatteryModel();
export default mBatteryModel as BatteryModel;

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 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 {
//layout params - Icon
static WHOLE_CONTAINER_MARGIN = 2
static WHOLE_CONTAINER_WIDTH = 100
static WHOLE_CONTAINER_HEIGHT = 24
static PIC_CONTAINER_WIDTH = '70%'
static PIC_CONTAINER_HEIGHT = '85%'
//layout params - Pic
static FULL_CONTAINER_WIDTH = '100%'
static FULL_CONTAINER_HEIGHT = '100%'
static BATTERY_BORDER_WIDTH = '88%'
static BATTERY_BORDER_HEIGHT = '80%'
static BATTERY_BORDER_RADIUS = 2
static BATTERY_BORDER_MARGIN = 2
static BATTERY_CONTENT_PADDING = 2
static BATTERY_DECORATOR_WIDTH = '10%'
static BATTERY_DECORATOR_HEIGHT = '50%'
static BATTERY_DECORATOR_MARGIN = 2
//layout params - Soc
static SOC_FONT_SIZE = 16
//value
static BATTERY_LEVEL_LOW = 20
static NONE = 0;
static ENABLE = 1;
static DISABLE = 2;
static FULL = 3;
static PERCENT_NUMBER = 100;
static DEFAULT_PROGRESS = 100;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 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 mBatteryModel from '../batteryModel.ets';
import BatteryPic from './batteryPic.ets'
import BatterySoc from './batterySoc'
import Constants from '../common/constants.ets'
import Log from '../../../../../../../common/src/main/ets/default/Log.ets'
const TAG = 'BatteryComponent-batteryIcon'
@Component
export default struct BatteryIcon {
@StorageLink('batterySoc') batterySoc: number = 100
@StorageLink('StatusCoefficient') StatusCoefficient: number = 1.0
aboutToAppear() {
mBatteryModel.initBatteryModel();
Log.showInfo(TAG, 'aboutToAppear');
}
aboutToDisappear() {
mBatteryModel.uninitBatteryModel();
Log.showInfo(TAG, 'aboutToDisappear');
}
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
BatterySoc()
}
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
BatteryPic()
}
// .width('70%')
// .height('100%')
.width('40%')
.height('42%')
.margin({right:$r('app.float.battery_margin')})
}
.width(Constants.WHOLE_CONTAINER_WIDTH * this.StatusCoefficient)
.height(Constants.WHOLE_CONTAINER_HEIGHT * this.StatusCoefficient)
.margin($r('app.float.whole_container_margin'))
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets'
import Log from '../../../../../../../common/src/main/ets/default/Log.ets'
const TAG = 'BatteryComponent-batteryPic'
@Component
export default
struct BatteryPic {
@StorageLink('batterySoc') batterySoc: number = 100
@StorageLink('batteryCharging') batteryCharging : boolean = false
aboutToAppear(){
Log.showInfo(TAG,'aboutToAppear Start');
}
aboutToDisappear(){
Log.showInfo(TAG,'aboutToDisappear');
}
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
}
.height('100%')
.width(this.batterySoc + '%')
.backgroundColor(this.getBatteryColor(this.batterySoc, this.batteryCharging))
}
.width('88%')
.height('100%')
.backgroundColor($r('app.color.battery_background'))
.border({ width: $r('app.float.battery_border_width'),
color: $r('app.color.battery_border'),
radius: $r('app.float.battery_border_radius'),
style: BorderStyle.Solid })
.padding($r('app.float.battery_content_padding'))
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
}
.width('10%')
.height('50%')
.backgroundColor($r('app.color.battery_border'))
.borderRadius($r('app.float.battery_border_radius'))
.margin({ left: $r('app.float.battery_decorator_margin') })
}
.width('100%')
.height('100%')
}
private getBatteryColor(val, charging) {
Log.showInfo(TAG, `getBatteryColor, val: ${ val } charging: ${ charging } `);
if (charging) {
return $r('app.color.battery_charging_color');
} else if (val <= Constants.BATTERY_LEVEL_LOW) {
return $r('app.color.battery_low_color');
} else {
return $r('app.color.battery_default_color');
}
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../common/src/main/ets/default/Log.ets'
const TAG = 'BatteryComponent-batterySoc'
@Component
export default
struct BatterySoc {
@StorageLink('batterySoc') batterySoc: number = 100
aboutToAppear(){
Log.showInfo(TAG,'aboutToAppear Start');
}
aboutToDisappear(){
Log.showInfo(TAG,'aboutToDisappear');
}
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
Text(this.batterySoc + '%')
.height('100%')
.fontColor($r('app.color.battery_default_color'))
.fontSize($r('app.float.fontSize_network_state'))
}
}
}

View File

@ -0,0 +1,20 @@
{
"color": [
{
"name": "battery_low_color",
"value": "#ff0000"
},{
"name": "battery_default_color",
"value": "#ffffff"
},{
"name": "battery_charging_color",
"value": "#00ff21"
},{
"name": "battery_border",
"value": "#fff"
},{
"name": "battery_background",
"value": "#00000000"
}
]
}

View File

@ -0,0 +1,36 @@
{
"float": [
{
"name": "fontSize_network_state",
"value": "16"
},
{
"name": "whole_container_width",
"value": "100"
},
{
"name": "whole_container_margin",
"value": "2"
},
{
"name": "battery_decorator_margin",
"value": "2"
},
{
"name": "battery_border_radius",
"value": "2"
},
{
"name": "battery_content_padding",
"value": "2"
},
{
"name": "battery_border_width",
"value": "1"
},
{
"name": "battery_margin",
"value": "20"
}
]
}

View File

@ -0,0 +1,12 @@
{
"string": [
{
"name": "batterycomponent_MainAbility",
"value": "batterycomponent_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,12 @@
{
"string": [
{
"name": "batterycomponent_MainAbility",
"value": "batterycomponent_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
}
]
}

View File

@ -0,0 +1,12 @@
{
"string": [
{
"name": "batterycomponent_MainAbility",
"value": "batterycomponent_MainAbility"
},
{
"name": "mainability_description",
"value": "ETS_Empty Feature Ability"
}
]
}

View File

@ -0,0 +1,20 @@
apply plugin: 'com.huawei.ohos.library'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
}

View File

@ -0,0 +1,24 @@
{
"app": {
"bundleName": "com.ohos.systemui",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {
},
"module": {
"package": "com.ohos.noticeItem",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "noticeitem",
"moduleType": "har"
},
"srcPath": "default"
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2021 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 {
static NOTIFICATION_TYPE_BASIC: string = '0';
static NOTIFICATION_TYPE_LONG: string = '1';
static NOTIFICATION_TYPE_IMAGE: string = '2';
static NOTIFICATION_TYPE_MULTILINE: string = '4';
static NOTIFICATION_TYPE_SOCIAL: string = '3';
static NOTIFICATION_TYPE_MEDIA: string = '5';
static TEXT_MAX_LENGTH: number = 21;
static TEXT_EXPANDED_MAX_LENGTH: number = 13;
static TOUCH_TYPE_DOWN: number = 0;
static TOUCH_TYPE_UP: number = 1;
static TOUCH_TYPE_MOVE: number = 2;
static HIDDEN_TRANSLATE_X: number = 150;
static DISPLAY_TRANSLATE_X: number = -150;
static REMOVE_TRANSLATE_X: number = 150;
static DEFAULT_MAX_LINES: number= 1;
static EXPENDED_MAX_LINES: number= 8;
static CONTENT_LINE_HEIGHT: number = 20;
static SETTING_CONT_HEIGHT = '50';
static SETTING_DIALOG_WITH = '80%';
static SETTING_CONTENT_WITH = '100%'
static SETTING_DIALOG_HEIGHT = '380';
static CONFIRM_DIALOG_HEIGHT = '250'
static CONFIRM_DIALOG_WITH = '80%'
static CONFIRM_BUTTON_WITH = '50%'
static QUICKLY_SETTING_H = 83;
static ERROR_CALLBACK: number = 0;
static SUCCESS_CALLBACK: number = 1;
}
export interface NotificationItemData {
id: string;
hashcode: string;
contentType: string;
timestamp: number;
time: string;
appName: string;
want: any;
actionButtons: any[];
bundleName: string;
smallIcon?: Resource | string;
largeIcon?: Resource | string;
title?: string;
text?: string;
additionalText?: string;
briefText?: string;
expandedTitle?: string;
longText?: string;
lines?: any[];
longTitle?: string;
slotLevel?: any;
source?: number;
versionName?: string;
}
export interface NotificationServiceListener {
onNotificationConsume?: (data: NotificationItemData) => void;
onNotificationLoad?:(data: NotificationItemData) => void;
onNotificationCancel?:(data: NotificationItemData) => void;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets';
import {NotificationItemData} from '../../../../../../../../notificationService/src/main/ets/com/ohos/notificationservice/common/constants.ets';
@Component
export default struct BasicItem {
@State itemData: NotificationItemData= undefined
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
Text(this.itemData.text)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Clip })
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
.margin({ top: $r('app.float.content_margin_top') })
}.width('100%')
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets';
import {NotificationItemData} from '../../../../../../../../notificationService/src/main/ets/com/ohos/notificationservice/common/constants.ets';
@Component
export default
struct LongItem {
@State itemData: NotificationItemData= undefined
@Prop isExpand: boolean
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.isExpand ? this.itemData.expandedTitle : this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT) //not support Resource type
Text(this.isExpand ? this.itemData.longText : this.itemData.text)
.maxLines(this.isExpand ? Constants.EXPENDED_MAX_LINES : Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.constraintSize({ maxHeight: $r('app.float.notification_expanded_text_maxheight') })
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
.margin({ top: $r('app.float.content_margin_top') })
}.width('100%')
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets';
import {NotificationItemData} from '../../../../../../../../notificationService/src/main/ets/com/ohos/notificationservice/common/constants.ets';
@Component
export default struct MultiItem {
@State itemData: NotificationItemData= undefined
@Prop isExpand: boolean
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.isExpand ? this.itemData.longTitle : this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
if (this.isExpand) {
ForEach(this.itemData.lines,
(item: string) => {
Text(`${item}`)
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.margin({ top: $r('app.float.content_margin_top') })
}, (item: string) => item.toString()
)
} else {
Text(this.itemData.text)
.fontSize($r('app.float.notification_content_fontsize'))
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor($r('app.color.content_text_color'))
.margin({ top: $r('app.float.content_margin_top') })
}
}.width('100%')
}
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets';
import basicItem from './basicItem.ets';
import longItem from './longItem.ets';
import multiItem from './multiItem.ets';
import titleItem from './titleItem';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import CheckEmptyUtils from '../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
import mNotificationService from '../../../../../../../../../features/notificationService/src/main/ets/com/ohos/notificationservice/NotificationService.ets'
import WantAgent from '@ohos.wantAgent';
import WindowManager from '../../../../../../../../../common/src/main/ets/default/WindowManager.ets';
import {NotificationItemData} from '../../../../../../../../notificationService/src/main/ets/com/ohos/notificationservice/common/constants.ets';
const TAG = 'NoticeItem-NotificationItem';
let mWindowManager;
@Component
export default struct NotificationItem {
@Link showStatusBar: boolean
private itemData: NotificationItemData
@State hasPicture: boolean = false
@State isExpand: boolean = false
@State needExpand: boolean = true
@State deleteIconDisplay: boolean = false;
@State itemWidth: string = '100%'
startX: number = 0
startY: number = 0
@State moveX: number = 0
@State moveY: number = 0
aboutToAppear() {
Log.showInfo(TAG, `aboutToDisAppear Start`)
mWindowManager = new WindowManager();
if (CheckEmptyUtils.isEmpty(this.itemData.largeIcon)) {
this.hasPicture = false;
} else {
this.hasPicture = true;
}
this.needExpand=this.checkItemNeedExpand()
}
checkItemNeedExpand(){
if(this.itemData.contentType===Constants.NOTIFICATION_TYPE_BASIC&&(!(this.itemData.actionButtons?.length>0))){
return false;
}else{
return true;
}
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisAppear`);
}
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Row() {
Column() {
titleItem({
notificationSmallIcon: this.itemData.smallIcon,
notificationName: this.itemData.name,
notificationTime: this.itemData.time,
isExpand: $isExpand,
needExpand: this.needExpand
})
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_BASIC) {
basicItem({
itemData: this.itemData
});
}
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_LONG) {
longItem({
itemData: this.itemData,
isExpand: this.isExpand
});
}
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_MULTILINE) {
multiItem({
itemData: this.itemData,
isExpand: this.isExpand
});
}
}
.width(this.hasPicture ? '85%' : '100%')
.margin({ top: $r('app.float.body_margin_top') })
if (this.hasPicture) {
Column() {
Image(this.itemData.largeIcon)
.objectFit(ImageFit.Contain)
.width(50)
.height(50)
}
.alignItems(HorizontalAlign.End)
.width('15%')
}
}.onClick(this.clickItem.bind(this))
if(this.isExpand){
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
ForEach(this.itemData.actionButtons, (item: any) => {
Text(item.title)
.fontSize(20)
.height(30)
.fontColor(Color.Blue)
.margin({ right: 20 })
.onClick(() => {
Log.showInfo(TAG, `clickbuttonEvent: ${JSON.stringify(item.wantAgent)}`)
this.startTargetAbility(item.wantAgent)
})
})
}
.margin({ top: 10 })
}
}
.backgroundColor($r('app.color.notificationitem_background'))
.opacity($r('app.float.item_opicaty'))
.borderRadius($r('app.float.item_borderradius'))
.margin({
left: $r('app.float.item_marginleft'),
right: $r('app.float.item_marginright'),
top: $r('app.float.item_margintop')
})
.padding({
left: $r('app.float.item_paddingleft'),
right: $r('app.float.item_paddingright'),
bottom: $r('app.float.item_paddingbottom')
})
.onTouch(this.touchNotificationItem.bind(this))
.width(this.itemWidth)
if (this.deleteIconDisplay) {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
Image($r('app.media.delete')) //delete
.objectFit(ImageFit.Contain)
.width($r('app.float.item_delete_image_width'))
.height($r('app.float.item_delete_image_height'))
.onClick(() => {
this.removeNotificationItem(this.itemData.hashcode);
})
}
.width('30%')
}
}
}
}
touchNotificationItem(event: TouchEvent) {
if (event.type == Constants.TOUCH_TYPE_DOWN) { //down
this.startX = event.touches[0].x;
this.startY = event.touches[0].y;
Log.showInfo(TAG, `touchStart=======startX: ${this.startX}, startY: ${this.startY}`);
} else if (event.type == Constants.TOUCH_TYPE_MOVE) { //move
this.moveX = event.touches[0].x - this.startX;
this.moveY = event.touches[0].y - this.startY;
} else if (event.type == Constants.TOUCH_TYPE_UP) { //up
Log.showInfo(TAG, `touchEnd, moveX: ${this.moveX}, moveY: ${this.moveY}`);
if (this.deleteIconDisplay) {
if (this.moveX > Constants.HIDDEN_TRANSLATE_X) {
//hidden
this.deleteIconDisplay = false;
this.itemWidth = '100%';
Log.showInfo(TAG, 'hidden');
}
} else {
if (this.moveX < Constants.DISPLAY_TRANSLATE_X) {
this.deleteIconDisplay = true;
this.itemWidth = '70%';
Log.showInfo(TAG, 'display');
} else if (this.moveX > Constants.REMOVE_TRANSLATE_X) {
this.removeNotificationItem(this.itemData.hashcode);
}
}
}
}
removeNotificationItem(hashCode: string) {
Log.showInfo(TAG, 'removeNotificationItem');
mNotificationService.removeNotificationItem(hashCode, true);
}
clickItem() {
Log.showInfo(TAG, 'click Item');
this.startTargetAbility(this.itemData.want);
}
startTargetAbility(want) {
Log.showInfo(TAG, 'startTargetAbility');
//close window
this.showStatusBar = true;
mWindowManager.setWindowMin((result) => {
Log.showInfo(TAG, `setWindowMin ${result}`);
});
//open app
Log.showInfo(TAG, `itemClick wantAgent ${JSON.stringify(this.itemData.want)} id: ${this.itemData.id}`);
let TriggerInfo = {
code: 0,
want: '',
permission: '',
extraInfo: {}
};
WantAgent.trigger(want, TriggerInfo, ((err, data) => {
Log.showInfo(TAG, `itemClick wantAgent trigger err ${JSON.stringify(err)} data ${JSON.stringify(data)}`);
}));
//remove notification
this.removeNotificationItem(this.itemData.hashcode);
}
}

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2021 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 '../common/constants.ets';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import CheckEmptyUtils from '../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
const TAG = 'NoticeItem-TitleItem';
@Component
export default
struct TitleItem {
private notificationSmallIcon: PixelMap
@Prop notificationName: string
@Prop notificationTime: string
@State srcIconDisplay: any = $r('app.media.ic_notification_down')
@Link isExpand: boolean
@Prop needExpand: boolean
@State rowSpace: any = $r('app.float.titleitem_row_space')
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear Start`);
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisAppear`);
}
build() {
Row() {
Row({ space: this.rowSpace }) {
if (!CheckEmptyUtils.isEmpty(this.notificationSmallIcon)) {
Image(this.notificationSmallIcon)
.objectFit(ImageFit.Contain)
.width($r('app.float.title_image_width'))
.height($r('app.float.title_image_height'))
.flexShrink(0)
}
Text(this.notificationName)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.title_name_fontsize'))
.flexShrink(1)
Text(this.notificationTime)
.fontSize($r('app.float.title_time_fontsize'))
.flexShrink(0)
}
.width(this.needExpand ? '80%' : '100%')
if (this.needExpand) {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.End, alignItems: ItemAlign.Center }) {
Image(this.srcIconDisplay)
.objectFit(ImageFit.Contain)
.width($r('app.float.displayicon_width'))
.height($r('app.float.displayicon_height'))
}
.width('20%')
}
}
.height($r('app.float.titleitem_height'))
.width('100%')
.onClick(this.clickTitleItem.bind(this))
}
clickTitleItem() {
Log.showInfo(TAG, 'clickTitleItem');
if (this.needExpand) {
if (this.isExpand) {
this.isExpand = false;
this.srcIconDisplay = $r('app.media.ic_notification_down');
} else {
this.isExpand = true;
this.srcIconDisplay = $r('app.media.ic_notification_up');
}
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 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 ReadConfigUtil from '../../../../../../../../../common/src/main/ets/default/ReadConfigUtil.ets';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
const FILE_URI = '/data/accounts/account_0/applications/com.ohos.systemui'
+ '/com.ohos.systemui.statusbar/assets/{0}/resources/rawfile/notificationConfig.json'
const TAG = 'NotificationConfig'
export class NotificationConfig {
static USE_NOTIFICATION_ICON = true;
readNotificationConfig(deviceType: string): any{
Log.showInfo(TAG, `readSlidingLength deviceType:${deviceType}`);
let notificationConfig = ReadConfigUtil.ReadConfigFile(FILE_URI.replace('{0}', deviceType))
return notificationConfig
}
}
let notificationConfig = new NotificationConfig();
export default notificationConfig as NotificationConfig;

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 { NotificationSubscriber } from './notification/notificationSubscriber';
import Notification from '@ohos.notification';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
const TAG = 'NotificationManager';
export default class NotificationManager {
static TYPE_BASIC: number = Notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT;
static TYPE_LONG: number = Notification.ContentType.NOTIFICATION_CONTENT_LONG_TEXT;
static TYPE_MULTI: number = Notification.ContentType.NOTIFICATION_CONTENT_MULTILINE;
static subscribeNotification(tag, subscriber, asyncCallback) {
Log.showInfo(TAG, `subscribeNotification from: ${tag}`);
Notification.subscribe(subscriber, asyncCallback);
}
static unsubscribeNotification(tag, subscriber) {
Log.showInfo(TAG, `subscribeNotification from: ${tag}`);
Notification.unsubscribe(subscriber);
}
static removeAll(tag, callback) {
Log.showInfo(TAG, `removeAll from: ${tag}`);
Notification.removeAll(callback);
}
static remove(tag, hashCode, callback) {
Log.showInfo(TAG, `remove from: ${tag}`);
Notification.remove(hashCode, callback)
}
static getAllActiveNotifications(tag, callback) {
Log.showInfo(TAG, `getAllActiveNotifications from: ${tag}`);
Notification.getAllActiveNotifications(callback);
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2021 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 notification from '@ohos.notification';
import NotificationSubscriber from '@ohos.notificationSubscriber';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import NotificationManager from './NotificationManager.ets';
import ParseDataUtil from './ParseDataUtil.ets';
const TAG = 'NotificationService';
let mSubscriber;
let listeners;
/**
* notification service api
*/
export class NotificationService {
constructor() {
listeners = [];
this.init();
}
init() {
this.loadAllNotifications();
this.subscribeNotification(this.getSubscriber());
}
public register(listener) {
Log.showInfo(TAG, "register listener")
listeners.push(listener);
}
public unRegister(listener) {
Log.showInfo(TAG, "unRegister listener")
let removedIndex = listeners.indexOf(listener);
if (removedIndex == -1) {
Log.showInfo(TAG, "unRegister listener, listener is not found");
return;
}
listeners.splice(removedIndex, 1)
Log.showInfo(TAG, "unRegister listener success");
}
public removeAll(){
Log.showInfo(TAG, 'removeAll start');
NotificationManager.removeAll(TAG, (data) => {
Log.showInfo(TAG, `removeAll => data: ${JSON.stringify(data)}`);
});
}
public remove(code: string) {
NotificationManager.remove(TAG, code,(data) => {
Log.showInfo(TAG, `removeNotificationItem ==> data: ${JSON.stringify(data)}`);
})
}
public loadAllNotifications() {
NotificationManager.getAllActiveNotifications(TAG, (err, requestsArr) => {
Log.showInfo(TAG, `getAllActiveNotifications err: ${JSON.stringify(err)}`);
Log.showInfo(TAG, `getAllActiveNotifications requestsArr: ${JSON.stringify(requestsArr)}`);
if (Array.isArray(requestsArr)) {
for(let i = 0,len = requestsArr.length; i< len; i++) {
this.handleNotificationLoad(requestsArr[i]);
}
}
})
}
getSubscriber() {
if (mSubscriber == null || mSubscriber == undefined) {
mSubscriber = {
onConsume: this.handleNotificationAdd.bind(this),
onCancel: this.handleNotificationCancel.bind(this),
}
}
return mSubscriber;
}
handleNotificationAdd(data) {
Log.showInfo(TAG, 'handleNotificationAdd started');
Log.showInfo(TAG, 'sortingMap' + JSON.stringify(data.sortingMap||{}));
Log.showInfo(TAG, JSON.stringify(data));
ParseDataUtil.parseData(data, (err, record) => {
Log.showInfo(TAG, `parseData after = ${JSON.stringify(record)}`);
Log.showInfo(TAG, `listeners.length = ${JSON.stringify(data)}`);
for(let i = 0,len = listeners.length; i< len; i++) {
Log.showInfo(TAG, `notify listener ` + i);
listeners[i].onNotificationConsume(record);
}
});
}
handleNotificationCancel(data) {
console.info("===>handleNotificationCancel data : ==> " + `data:${JSON.stringify(data)}`);
ParseDataUtil.parseData(data, (err, record) => {
for(let i = 0,len = listeners.length; i< len; i++) {
listeners[i].onNotificationCancel(record);
}
});
}
handleNotificationLoad(data) {
console.info("===>handleNotificationLoad data : ==> " + `data:${JSON.stringify(data)}`);
ParseDataUtil.parseData(data, (err, record) => {
for(let i = 0,len = listeners.length; i< len; i++) {
listeners[i].onNotificationLoad(record);
}
});
}
subscribeNotification(subscriber) {
let callback = (err,data) => {
Log.showInfo(TAG, `subscribeCallback finished err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`)
};
NotificationManager.subscribeNotification(TAG, subscriber, callback);
}
}
let notificationService = new NotificationService();
export default notificationService as NotificationService;

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2021 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 Notification from '@ohos.notification';
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import BundleManager from '../../../../../../../../../common/src/main/ets/default/abilitymanager/bundleManager.ets';
import NotificationManager from './NotificationManager.ets';
import Constants,{NotificationItemData} from '../common/constants.ets';
import {NotificationConfig} from './NotificationConfig.ets';
let mDate;
let mAppName;
let mEmptyArray;
const TAG = 'Notification_ParseDataUtil';
mDate = new Date();
mAppName = new Map();
mEmptyArray = [];
let appDataMap = new Map();
/**
* parse data util class.
*/
export default class ParseDataUtil {
static parseData(data, callback) {
let request = data?.request;
if (request == null || request == undefined) {
Log.showInfo(TAG, 'consumeCallback request is empty');
callback(Constants.ERROR_CALLBACK, undefined);
return;
}
let slotLevel;
try {
slotLevel = data?.sortingMap?.sortings[request.hashCode]?.slot.level;
} catch (e) {
Log.showInfo(TAG, `slot level get error: ${e.toString()}`);
}
Log.showInfo(TAG, `want = ${JSON.stringify(request.wantAgent)}`);
Log.showInfo(TAG, `actionButtons = ${JSON.stringify(request.actionButtons)}`);
Log.showInfo(TAG, `largeIcon = ${request.largeIcon}`);
ParseDataUtil.getAppData(request.creatorBundleName, (err, appMessage) => {
let notificationItem: NotificationItemData = {
id: request.id,
hashcode: request.hashCode,
contentType: request?.content?.contentType + '',
timestamp: request.deliveryTime,
time: ParseDataUtil.getStandardTime(request.deliveryTime),
appName: appMessage.appName,
want: request.wantAgent,
bundleName: request.creatorBundleName,
actionButtons: request.actionButtons,
smallIcon: NotificationConfig.USE_NOTIFICATION_ICON ? (request?.smallIcon ?? appMessage.icon) : appMessage.icon,
largeIcon: request.largeIcon,
slotLevel: slotLevel,
source: request.source
};
Log.showInfo(TAG, `notificationItem construct over ====================`);
switch (request?.content?.contentType) {
case NotificationManager.TYPE_BASIC:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_BASIC_TEXT ====================`);
notificationItem.title = request.content.normal?.title ?? '';
notificationItem.text = request.content.normal?.text ?? '';
notificationItem.additionalText = request.content.normal?.additionalText ?? '';
break;
case NotificationManager.TYPE_LONG:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_LONG_TEXT ====================`);
notificationItem.title = request.content.longText?.title ?? '';
notificationItem.text = request.content.longText?.text ?? '';
notificationItem.additionalText = request.content.longText?.additionalText ?? '';
notificationItem.briefText = request.content.longText?.briefText ?? '';
notificationItem.expandedTitle = request.content.longText?.expandedTitle ?? '';
notificationItem.longText = request.content.longText?.longText ?? '';
break;
case NotificationManager.TYPE_MULTI:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_MULTILINE ====================`);
notificationItem.title = request.content.multiLine?.title ?? '';
notificationItem.text = request.content.multiLine?.text ?? '';
notificationItem.additionalText = request.content.multiLine?.additionalText ?? '';
notificationItem.briefText = request.content.multiLine?.briefText ?? '';
notificationItem.longTitle = request.content.multiLine?.longTitle ?? '';
notificationItem.lines = request.content.multiLine?.lines ?? mEmptyArray;
Log.showInfo(TAG, `multilines: ${JSON.stringify(request.content.multiLine?.lines)}`)
break;
default:
Log.showInfo(TAG, 'no match content type');
break;
}
callback(Constants.SUCCESS_CALLBACK, notificationItem);
})
}
/**
* Get app data by bundleName.
*
* @param {string} bundleName - BundleName of the target app.
* @return {object} appData
*/
static getAppData(bundleName, callback) {
Log.showInfo(TAG, 'getAppName start ====================');
if (appDataMap.has(bundleName)) {
callback(Constants.SUCCESS_CALLBACK,appDataMap.get(bundleName));
return;
}
BundleManager.getBundleInfo(TAG, bundleName, 0, (data) => {
Log.showInfo(TAG, `getBundleInfo` + JSON.stringify(data));
let labelId = data.appInfo.labelId;
let iconId = data.appInfo.iconId;
let appName = '';
BundleManager.getResourceManager(TAG, bundleName, (item) => {
Log.showInfo(TAG, `BundleManager.getResourceManager ${BundleManager.getResourceManager}`);
item.getString(labelId, (error, value) => {
Log.showInfo(TAG, `getString` + JSON.stringify(value));
if (value != null && value != undefined) {
appName = value
}
item.getMediaBase64(iconId, (error, MediaValue) => {
Log.showInfo(TAG, `getMediaBase64` + JSON.stringify(MediaValue));
if (MediaValue != null) {
let appMessage = {
'appName': appName,
'icon': MediaValue
}
Log.showInfo(TAG, `appDataMap set appInfo, appName = ` + JSON.stringify(appName));
if (appName != null && appName != undefined && appName != '') {
appDataMap.set(bundleName, appMessage);
}
Log.showInfo(TAG, `getAppData success, appMessage ` + JSON.stringify(appMessage));
callback(Constants.SUCCESS_CALLBACK,appDataMap.get(bundleName));
}
});
})
})
});
}
/**
* Reformat the timestamp to hh:mm.
*
* @param {number} timestamp - Target timestamp.
*/
static getStandardTime(timestamp) {
Log.showInfo(TAG, 'getStandardTime start ====================');
if (timestamp == 0 || timestamp == undefined || timestamp == null) {
return '';
}
mDate.setTime(timestamp);
let hoursNumber = mDate.getHours();
let minutesNumber = mDate.getMinutes();
let hours = hoursNumber < 10 ? '0' + hoursNumber : hoursNumber;
let minutes = minutesNumber < 10 ? '0' + minutesNumber : minutesNumber;
return hours + ':' + minutes;
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2021 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 interface RuleData {
isAllowBanner:boolean;
sound:string;
vibration:string;
isAllowLockScreen:boolean;
}

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2021 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 {NotificationItemData} from '../../common/constants.ets'
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
const TAG = 'RuleController';
export default class RuleController {
/**
* Check if this notification is allow show or not
*
* @param {notificationItemData} Data of the notification
* @param {callback} Data of the type to show the notification
*/
static getNotificationData(notificationItemData, callback) {
if (typeof notificationItemData !== NotificationItemData) {
Log.showInfo(TAG, "type is not NotificationItemData")
callback(undefined)
return
}
this.this.isAllowSendNotification(notificationItemData.name, 0, "", (isSuccess) => {
if (!isSuccess) {
Log.showInfo(TAG, "user is not allow this to send notification")
callback(undefined)
return
}
this.isTooMuchNotification((isSuccess) => {
if (!isSuccess) {
Log.showInfo(TAG, "There are too much notification")
callback(undefined)
return
}
this.isAppTooMuchNotification(notificationItemData.name, 0, (isSuccess) => {
if (!isSuccess) {
Log.showInfo(TAG, "There are too much notification")
callback(undefined)
}
this.getNotificationDataByApp(notificationItemData.name, 0, "", (originData) => {
this.updateNotificationDataBySense(originData, (finialData) => {
callback(finalData)
});
});
});
});
});
}
/**
* Check if user allow the app send notification or not
*
* @param {name} Package name of the app
* @param {uid} Uid of the app to distinguish twin app
* @param {channelId} The channel id of the app which is used to send notification
* @param {callback} The user allow the app send notification or not
*/
private static isAllowSendNotification(name, uid, channelId, callback) {
// TODO 权限管理
}
/**
* Check there have been too much notification that there is no need to show another
*
*
* @param {callback} Send too much notification or not
*/
private static isTooMuchNotification(callback) {
// TODO 通知总条数显示限制
}
/**
* Check if the app send too much notification to can not show another from this app
*
*
* @param {name} Package name of the app
* @param {uid} Uid of the app to distinguish twin app
* @param {callback} Send too much notification or not
*/
private static isAppTooMuchNotification(name, uid, callback) {
// TODO 单应用通知显示限制
}
/**
* Get notification data of the notification channel
*
* @param {name} Package name of the app which send notification
* @param {uid} Uid of the app which send notification to distinguish twin app
* @param {channelId} The channel id of the app which is used to send notification
* @param {callback} The type to show notification
*/
private static getNotificationDataByApp(name, uid, channelId, callback) {
// TODO 提醒方式
}
/**
* Check the sense of the phone to update the show type
*
* @param {notificationData} The origin notification data
* @param {callback} The finial notification data
*/
private static updateNotificationDataBySense(notificationData, callback) {
// TODO 场景管理
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import Constants from '../common/constants.ets';
import NotificationItem from './item/notificationItem.ets'
import ViewModel from '../viewmodel/ViewModel.ets'
const TAG = 'NoticeItem-NotificationListComponent';
@Component
export default struct NotificationListComponent {
@StorageLink('notificationList') notificationList: any[] = []
@StorageProp('maxHeight') maxHeight: number = 0
@StorageProp('minHeight') minHeight: number = 0
@State notificationH: number = 0
aboutToAppear() {
Log.showInfo(TAG, `notificationList, aboutToAppear`)
this.notificationH = this.maxHeight - (this.minHeight * 2) - Constants.QUICKLY_SETTING_H;
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisAppear`);
}
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
if (this.notificationList.length == 0) {
//text: no notification
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
Text($r('app.string.nonotification_text'))
.fontColor($r('app.color.nonotification_text_color'))
}
} else {
Stack({ alignContent: Alignment.TopStart }) {
List() {
ForEach(this.notificationList, (item: any) => {
ListItem() {
NotificationItem({ itemData: item })
}
}, (item: any) => item.hashcode.toString())
}
.onTouch((event: TouchEvent) => {
Log.showInfo(TAG, `Touch Event ${event.type} at Point ${event.touches[0].x}, ${event.touches[0].y}`)
event.stopPropagation();
})
Flex() { //bottom Line
}.width('100%').height('7%')
.opacity($r('app.float.deleteall_image_opacity'))
.position({ x: 0, y: '93%' })
}
.width('100%')
.height('100%')
}
}
.width('100%')
.height(this.notificationH)
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 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,{NotificationItemData} from '../../common/constants.ets';
@Component
export default struct BasicItem {
@State itemData: NotificationItemData= undefined
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
Text(this.itemData.text)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Clip })
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
.margin({ top: $r('app.float.content_margin_top') })
}.width('100%')
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 2021 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 '../../common/constants.ets';
import Log from '../../../../../../../../../../common/src/main/ets/default/Log.ets';
const TAG = 'NoticeItem-Confirm';
/**
* confirm dialog
*/
@CustomDialog
export default struct ConfirmDialog {
private title: string
private bundleName: string
public controller: CustomDialogController
public action: () => void
build() {
Column({ space: 30 }) {
Row() {
Text(this.title)
.fontSize($r('app.float.confirm_title_fontsize'))
.fontWeight(FontWeight.Bold)
}.width(Constants.SETTING_DIALOG_WITH)
.margin({ top: 20 })
Row() {
Text($r('app.string.confirm_message', this.bundleName))
.fontSize($r('app.float.confirm_cont_fontsize'))
}.width(Constants.SETTING_DIALOG_WITH)
Row() {
Column() {
Text($r('app.string.cancel'))
.fontSize($r('app.float.confirm_cont_fontsize'))
.fontColor(Color.Blue)
}.onClick(() => {
this.controller.close();
})
.alignItems(HorizontalAlign.Center)
.width(Constants.CONFIRM_BUTTON_WITH)
Divider()
.vertical(true)
.color($r('app.color.confirm_divider_color'))
.strokeWidth(1)
.height($r('app.float.confirm_divider_height'))
Column() {
Text($r('app.string.close'))
.fontSize($r('app.float.confirm_cont_fontsize'))
.fontColor(Color.Red)
}.onClick(() => {
Log.showInfo(TAG, `confirm button of TimeDialog on click`)
this.controller.close();
this.action();
})
.alignItems(HorizontalAlign.Center)
.width(Constants.CONFIRM_BUTTON_WITH)
}
.width(Constants.CONFIRM_DIALOG_WITH)
.height($r('app.float.confirm_button_height'))
}.height(Constants.CONFIRM_DIALOG_HEIGHT)
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 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,{NotificationItemData} from '../../common/constants.ets';
@Component
export default
struct LongItem {
@State itemData: NotificationItemData= undefined
@Prop isExpand: boolean
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.isExpand ? this.itemData.expandedTitle : this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT) //not support Resource type
Text(this.isExpand ? this.itemData.longText : this.itemData.text)
.maxLines(this.isExpand ? Constants.EXPENDED_MAX_LINES : Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.constraintSize({ maxHeight: $r('app.float.notification_expanded_text_maxheight') })
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
.margin({ top: $r('app.float.content_margin_top') })
}.width('100%')
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 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,{NotificationItemData} from '../../common/constants.ets';
@Component
export default struct MultiItem {
@State itemData: NotificationItemData= undefined
@Prop isExpand: boolean
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Text(this.isExpand ? this.itemData.longTitle : this.itemData.title)
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.notification_title_fontsize'))
.fontColor($r('app.color.title_text_color'))
.fontWeight(FontWeight.Bold)
.lineHeight(Constants.CONTENT_LINE_HEIGHT)
if (this.isExpand) {
ForEach(this.itemData.lines,
(item: string) => {
Text(`${item}`)
.fontSize($r('app.float.notification_content_fontsize'))
.fontColor($r('app.color.content_text_color'))
.margin({ top: $r('app.float.content_margin_top') })
}, (item: string) => item.toString()
)
} else {
Text(this.itemData.text)
.fontSize($r('app.float.notification_content_fontsize'))
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor($r('app.color.content_text_color'))
.margin({ top: $r('app.float.content_margin_top') })
}
}.width('100%')
}
}

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2021 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,{NotificationItemData} from '../../common/constants.ets';
import basicItem from './basicItem.ets';
import longItem from './longItem.ets';
import multiItem from './multiItem.ets';
import titleItem from './titleItem.ets';
import Log from '../../../../../../../../../../common/src/main/ets/default/Log.ets';
import CheckEmptyUtils from '../../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
import WantAgent from '@ohos.wantAgent';
import ViewModel from '../../viewmodel/ViewModel.ets';
import SettingDialog from './settingDialog.ets';
import ConfirmDialog from './confirmDialog.ets'
const TAG = 'NoticeItem-NotificationItem';
@Component
export default struct NotificationItem {
private itemData: any = {}
@State hasPicture: boolean = false
@State isExpand: boolean = false
@State needExpand: boolean = true
@State deleteIconDisplay : boolean = false;
@State itemWidth: string = '100%'
startX: number = 0
startY: number = 0
@State moveX: number = 0
@State moveY: number = 0
settingDialogController: CustomDialogController = new CustomDialogController({
builder: SettingDialog({
itemData: this.itemData,
action: this.showConfirmDialog.bind(this)
}),
autoCancel: false,
offset: { dx: 0, dy: 200 }
});
confirmDialogController: CustomDialogController = new CustomDialogController({
builder: ConfirmDialog({
title: $r('app.string.closeNovice'),
bundleName: this.itemData.name,
action: ViewModel.removeNotificationItem.bind(ViewModel,this.itemData,true)
}),
autoCancel: false,
offset: { dx: 0, dy: 250 }
});
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear Start`)
if (CheckEmptyUtils.isEmpty(this.itemData.largeIcon)) {
this.hasPicture = false;
} else {
this.hasPicture = true;
}
this.needExpand=this.checkItemNeedExpand()
}
checkItemNeedExpand(){
if(this.itemData.contentType===Constants.NOTIFICATION_TYPE_BASIC&&(!(this.itemData.actionButtons?.length>0))){
return false;
}else{
return true;
}
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`);
}
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Row() {
Column() {
titleItem({
notificationSmallIcon: this.itemData.smallIcon,
notificationName: this.itemData.appName,
notificationTime: this.itemData.time,
isExpand: $isExpand,
needExpand: this.needExpand
})
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_BASIC) {
basicItem({
itemData: this.itemData
});
}
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_LONG) {
longItem({
itemData: this.itemData,
isExpand: this.isExpand
});
}
if (this.itemData.contentType === Constants.NOTIFICATION_TYPE_MULTILINE) {
multiItem({
itemData: this.itemData,
isExpand: this.isExpand
});
}
}
.width(this.hasPicture ? '85%' : '100%')
.margin({ top: $r('app.float.body_margin_top') })
if (this.hasPicture) {
Column() {
Image(this.itemData.largeIcon)
.objectFit(ImageFit.Contain)
.width(50)
.height(50)
}
.alignItems(HorizontalAlign.End)
.width('15%')
}
}
.onClick(() => {
ViewModel.startTargetAbility(this.itemData);
})
if (this.isExpand) {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
ForEach(this.itemData.actionButtons, (item: any) => {
Text(item.title)
.fontSize(20)
.height(30)
.fontColor(Color.Blue)
.margin({ right: 20 })
.onClick(() => {
ViewModel.startTargetAbility(this.itemData);
})
})
}
.margin({ top: 10 })
}
}
.backgroundColor($r('app.color.notificationitem_background'))
.opacity($r('app.float.item_opicaty'))
.borderRadius($r('app.float.item_borderradius'))
.margin({
left: $r('app.float.item_marginleft'),
right: $r('app.float.item_marginright'),
top: $r('app.float.item_margintop')
})
.padding({
left: $r('app.float.item_paddingleft'),
right: $r('app.float.item_paddingright'),
bottom: $r('app.float.item_paddingbottom')
})
.onTouch(this.touchNotificationItem.bind(this))
.width(this.itemWidth)
if (this.deleteIconDisplay) {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround, alignItems: ItemAlign.Center }) {
Row({ space: 30 }) {
Image($r("app.media.ic_setting")) //setting
.objectFit(ImageFit.Contain)
.width($r('app.float.item_delete_image_width'))
.height($r('app.float.item_delete_image_height'))
.onClick(this.showSettingDialog.bind(this))
Image($r('app.media.delete')) //delete
.objectFit(ImageFit.Contain)
.width($r('app.float.item_delete_image_width'))
.height($r('app.float.item_delete_image_height'))
.onClick(() => {
ViewModel.removeNotificationItem(this.itemData, true);
})
}
}
.width('30%')
}
}
}
}
showSettingDialog() {
Log.showInfo(TAG, `showSettingDialog`)
this.settingDialogController.open()
}
showConfirmDialog() {
Log.showInfo(TAG, `showConfirmDialog`)
this.confirmDialogController.open()
}
touchNotificationItem(event: TouchEvent) {
if (event.type == Constants.TOUCH_TYPE_DOWN) { //down
this.startX = event.touches[0].x;
this.startY = event.touches[0].y;
Log.showInfo(TAG, `touchStart=======startX: ${this.startX}, startY: ${this.startY}`);
} else if (event.type == Constants.TOUCH_TYPE_MOVE) { //move
this.moveX = event.touches[0].x - this.startX;
this.moveY = event.touches[0].y - this.startY;
} else if (event.type == Constants.TOUCH_TYPE_UP) { //up
Log.showInfo(TAG, `touchEnd, moveX: ${this.moveX}, moveY: ${this.moveY}`);
if (this.deleteIconDisplay) {
if (this.moveX > Constants.HIDDEN_TRANSLATE_X) {
//hidden
this.deleteIconDisplay = false;
this.itemWidth = '100%';
Log.showInfo(TAG, 'hidden');
}
} else {
if (this.moveX < Constants.DISPLAY_TRANSLATE_X) {
this.deleteIconDisplay = true;
this.itemWidth = '70%';
Log.showInfo(TAG, 'display');
} else if (this.moveX > Constants.REMOVE_TRANSLATE_X) {
ViewModel.removeNotificationItem(this.itemData, true);
}
}
}
}
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2021 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,{NotificationItemData} from '../../common/constants.ets';
import Log from '../../../../../../../../../../common/src/main/ets/default/Log.ets';
import CheckEmptyUtils from '../../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
import FeatureAbilityManager from '../../../../../../../../../../common/src/main/ets/default/abilitymanager/featureAbilityManager.ets';
import WindowManager from '../../../../../../../../../../common/src/main/ets/default/WindowManager.ets'
import Notification from '@ohos.notification';
const TAG = 'NoticeItem-Setting';
/**
* Setting dialog
*/
@CustomDialog
export default struct SettingDialog {
private itemData: NotificationItemData
public controller: CustomDialogController
public action: () => void
build() {
Column({ space: 30 }) {
Row({ space: 10 }) {
if (!CheckEmptyUtils.isEmpty(this.itemData.smallIcon)) {
Image(this.itemData.smallIcon)
.objectFit(ImageFit.Contain)
.width($r('app.float.title_image_width'))
.height($r('app.float.title_image_height'))
}
Text(this.itemData.appName)
.fontSize($r('app.float.setting_title_fontsize'))
}.width(Constants.SETTING_DIALOG_WITH)
.margin({ top: 50 })
Row() {
Column() {
Text($r('app.string.closeNotification'))
.fontSize($r('app.float.setting_cont_fontsize'))
.fontColor($r('app.color.dialog_font_color'))
.height(Constants.SETTING_CONT_HEIGHT)
}.alignItems(HorizontalAlign.Center)
.width(Constants.SETTING_CONTENT_WITH)
}
.width(Constants.SETTING_DIALOG_WITH)
.alignItems(VerticalAlign.Center)
.align(Alignment.Center)
.border({ width: $r('app.float.setting_border_width'), color: Color.White,
radius: $r('app.float.setting_border_radius') })
.backgroundColor($r('app.color.dialog_font_back_color'))
.onClick(this.closeNotification.bind(this))
Row() {
Column() {
Text($r('app.string.moreSettings'))
.fontSize($r('app.float.setting_cont_fontsize'))
.fontColor($r('app.color.dialog_font_color'))
.height(Constants.SETTING_CONT_HEIGHT)
}.alignItems(HorizontalAlign.Center)
.width(Constants.SETTING_CONTENT_WITH)
}
.width(Constants.SETTING_DIALOG_WITH)
.alignItems(VerticalAlign.Center)
.align(Alignment.Center)
.border({ width: $r('app.float.setting_border_width'), color: Color.White,
radius: $r('app.float.setting_border_radius') })
.backgroundColor($r('app.color.dialog_font_back_color'))
.onClick(this.openAbility.bind(this))
Row() {
Column() {
Text($r('app.string.cancel'))
.maxLines(Constants.DEFAULT_MAX_LINES)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontSize($r('app.float.setting_cont_fontsize'))
.fontColor($r('app.color.dialog_font_back_color'))
.height(Constants.SETTING_CONT_HEIGHT)
}.alignItems(HorizontalAlign.Center)
.width(Constants.SETTING_CONTENT_WITH)
}
.width(Constants.SETTING_DIALOG_WITH)
.alignItems(VerticalAlign.Center)
.align(Alignment.Center)
.border({ width: $r('app.float.setting_border_width'), color: Color.White,
radius: $r('app.float.setting_border_radius') })
.backgroundColor($r('app.color.dialog_font_color'))
.onClick(this.closeAbility.bind(this))
}.height(Constants.SETTING_DIALOG_HEIGHT)
}
closeNotification() {
this.action()
this.closeAbility()
}
openAbility() {
Log.showInfo(TAG, ` openAbility:showNotificationManagement`)
let mWindowManager = new WindowManager();
mWindowManager.setWindowMin((result) => {
Log.showInfo(TAG, `showNotificationManagement setWindowMin`)
let mFeatureAbilityManager = new FeatureAbilityManager()
mFeatureAbilityManager.openAbility(TAG, {
want: {
bundleName: 'com.ohos.systemui',
abilityName: 'com.ohos.systemui.notificationmanagement.MainAbility'
}
});
});
AppStorage.Set("showStatusBar", true);
this.closeAbility()
}
closeAbility() {
Log.showInfo(TAG, `closeAbility`)
this.controller.close()
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2021 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 '../../common/constants.ets';
import Log from '../../../../../../../../../../common/src/main/ets/default/Log.ets';
import CheckEmptyUtils from '../../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
const TAG = 'NoticeItem-TitleItem';
@Component
export default
struct TitleItem {
private notificationSmallIcon: PixelMap
@Prop notificationName: string
@Prop notificationTime: string
@State srcIconDisplay: any = $r('app.media.ic_notification_down')
@Link isExpand: boolean
@Prop needExpand: boolean
@State rowSpace: any = $r('app.float.titleitem_row_space')
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear Start`);
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisAppear`);
}
build() {
Row() {
Row({ space: this.rowSpace }) {
if (!CheckEmptyUtils.isEmpty(this.notificationSmallIcon)) {
Image(this.notificationSmallIcon)
.objectFit(ImageFit.Contain)
.width($r('app.float.title_image_width'))
.height($r('app.float.title_image_height'))
.flexShrink(0)
}
Text(this.notificationName)
.maxLines(Constants.DEFAULT_MAX_LINES)
.fontSize($r('app.float.title_name_fontsize'))
.flexShrink(1)
Text(this.notificationTime)
.fontSize($r('app.float.title_time_fontsize'))
.flexShrink(0)
}
.width(this.needExpand ? '80%' : '100%')
if (this.needExpand) {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.End, alignItems: ItemAlign.Center }) {
Image(this.srcIconDisplay)
.objectFit(ImageFit.Contain)
.width($r('app.float.displayicon_width'))
.height($r('app.float.displayicon_height'))
}
.width('20%')
}
}
.height($r('app.float.titleitem_height'))
.width('100%')
.onClick(this.clickTitleItem.bind(this))
}
clickTitleItem() {
Log.showInfo(TAG, 'clickTitleItem');
if (this.needExpand) {
if (this.isExpand) {
this.isExpand = false;
this.srcIconDisplay = $r('app.media.ic_notification_down');
} else {
this.isExpand = true;
this.srcIconDisplay = $r('app.media.ic_notification_up');
}
}
}
}

View File

@ -0,0 +1,314 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets';
import media from '@ohos.multimedia.media';
import NotificationService from '../model/NotificationService.ets'
import wantAgent from '@ohos.wantAgent';
import WindowManager from '../../../../../../../../../common/src/main/ets/default/WindowManager.ets';
import SourceType from '@ohos.notification'
import NotificationConfig from '../model/NotificationConfig.ets';
import CheckEmptyUtils from '../../../../../../../../../common/src/main/ets/default/CheckEmptyUtils.ets';
const TAG = 'NotificationViewModel';
const GROUP_THRESHOLD = 10;
/**
* Notification ViewModel class.
*/
export class ViewModel {
mWindowManager: WindowManager
audioPlayer: any
mNotificationList: any[];
mAppNotificationCount: any;
mCallback: any;
mNotificationCtrl: any = {}
constructor() {
this.mWindowManager = new WindowManager();
let tempLink = AppStorage.SetAndLink('notificationList', []);
this.mNotificationList = tempLink.get();
this.mAppNotificationCount = new Map();
this.audioPlayer = media.createAudioPlayer();
this.audioPlayer.src = 'file://system/etc/Light.ogg';
this.registerCallback();
this.loadFlowControlInfos()
}
registerCallback() {
this.mCallback = {
onNotificationConsume: this.onNotificationConsume.bind(this),
onNotificationCancel: this.onNotificationCancel.bind(this),
onNotificationLoad: this.onNotificationLoad.bind(this)
}
NotificationService.register(this.mCallback);
}
unregisterCallback() {
NotificationService.unRegister(this.mCallback);
}
/**
* notification CancelCallback
*
* @param {Object} data - return notificationItemData.
*/
onNotificationConsume(notificationItemData) {
Log.showInfo(TAG, `onNotificationConsume ${JSON.stringify(notificationItemData)}`);
//Verify the notifications can be displayed
if (!this.isCanShow(notificationItemData.bundleName)) {
//can not displayed
return;
}
if (!this.mAppNotificationCount.has(notificationItemData.appName)) {
this.mAppNotificationCount.set(notificationItemData.appName, 0);
}
this.mAppNotificationCount[notificationItemData.appName] += 1;
if (this.mAppNotificationCount[notificationItemData.appName] >= GROUP_THRESHOLD) {
this.groupNotification(notificationItemData, this.mAppNotificationCount[notificationItemData.appName]);
} else {
// Todo 排序插入
this.mNotificationList.unshift(notificationItemData);
this.updateFlowControlInfos(notificationItemData.bundleName, true)
this.updateNotification();
}
// Todo doAction(notificationItemData); 根据ruleData做处理
}
/**
* notification CancelCallback
*/
onNotificationCancel(notificationItemData) {
Log.showInfo(TAG, `onNotificationCancel ${JSON.stringify(notificationItemData)}`);
if (this.mAppNotificationCount[notificationItemData.appName] >= GROUP_THRESHOLD) {
// 组通知删除逻辑处理
return;
}
// 普通通知删除逻辑处理
for (let i = 0, len = this.mNotificationList.length; i < len; i++) {
if (this.mNotificationList[i].hashcode == notificationItemData.hashcode) {
Log.showInfo(TAG, `onNotificationCancel i = ${i}`);
this.mAppNotificationCount[notificationItemData.appName] -= 1;
let removeItemArr = this.mNotificationList.splice(i, 1);
Log.showInfo(TAG, `onNotificationCancel removeItemArr= ${JSON.stringify(removeItemArr)}`);
if (!CheckEmptyUtils.isEmpty(removeItemArr)) {
this.updateFlowControlInfos(removeItemArr[0].bundleName, false)
}
break;
}
}
}
onNotificationLoad() {
}
/**
* notification CancelCallback
*
* @param {Object} data - return notificationItemData.
*/
groupNotification(notificationItemData, num) {
if (num == GROUP_THRESHOLD) {
// 组通知转化
} else {
// 组通知添加
}
}
updateNotification() {
Log.showInfo(TAG, `updateNotification list: ${JSON.stringify(this.mNotificationList)}`);
Log.showInfo(TAG, `updateNotification len: ${this.mNotificationList.length}`);
this.sortNotification()
let listLink = AppStorage.Link('notificationList');
listLink.set(this.mNotificationList);
Log.showInfo(TAG, `updateNotification list: ${JSON.stringify(listLink.get())}`);
}
/**
* Sort the notifications.
*/
sortNotification() {
Log.showInfo(TAG, `sortNotification`);
if (this.mNotificationList == undefined || this.mNotificationList == null || this.mNotificationList.length < 1) {
return
}
this.mNotificationList.sort((itemA, itemB) => {
//long term notification come first
if (itemA.source == SourceType.TYPE_CONTINUOUS && itemB.source != SourceType.TYPE_CONTINUOUS) {
return -1
}
//long term notification come first
if (itemA.source != SourceType.TYPE_CONTINUOUS && itemB.source == SourceType.TYPE_CONTINUOUS) {
return 1
}
if ((itemA.source == SourceType.TYPE_CONTINUOUS && itemB.source == SourceType.TYPE_CONTINUOUS) ||
(itemA.source != SourceType.TYPE_CONTINUOUS && itemB.source != SourceType.TYPE_CONTINUOUS)
) {
return -1 * (itemA.timestamp - itemB.timestamp)
}
})
}
/**
* Remove all notifications.
*/
removeAllNotifications() {
if (this.mNotificationList == undefined || this.mNotificationList == null || this.mNotificationList.length < 1) {
this.mNotificationList = []
} else {
let index = this.mNotificationList.length
while (index--) {
Log.showInfo(TAG, `mNotificationList[${index}].source: ${this.mNotificationList[index].source}`);
//Except the Long term notifications
if (this.mNotificationList[index].source != SourceType.TYPE_CONTINUOUS) {
Log.showInfo(TAG, `mNotificationList[${index}].hashcode: ${this.mNotificationList[index].hashcode}`);
let hashCode = this.mNotificationList[index].hashcode
this.removeSysNotificationItem(hashCode)
let removeItemArr = this.mNotificationList.splice(index, 1)
Log.showInfo(TAG, `removeAllNotifications removeItemArr= ${JSON.stringify(removeItemArr)}`);
if (!CheckEmptyUtils.isEmpty(removeItemArr)) {
this.updateFlowControlInfos(removeItemArr[0].bundleName, false)
}
}
}
}
this.updateNotification()
}
removeNotificationItem(itemData, isDelSysConent) {
Log.showInfo(TAG, `removeNotificationItem, hashcode: ${itemData.hashcode}`);
for (let i = 0, len = this.mNotificationList.length; i < len; i++) {
if (this.mNotificationList[i].hashcode == itemData.hashcode) {
Log.showInfo(TAG, `this.mNotificationList[i].hashcode=${this.mNotificationList[i].hashcode}, itemData.hashcode=${itemData.hashcode}`);
Log.showInfo(TAG, `removeNotificationItem i = ${i}`);
this.mAppNotificationCount[itemData.appName] -= 1;
let removeItemArr = this.mNotificationList.splice(i, 1);
Log.showInfo(TAG, `removeNotificationItem removeItemArr= ${JSON.stringify(removeItemArr)}`);
if (!CheckEmptyUtils.isEmpty(removeItemArr)) {
this.updateFlowControlInfos(removeItemArr[0].bundleName, false)
}
break;
}
}
this.updateNotification();
if (isDelSysConent) {
this.removeSysNotificationItem(itemData.hashcode);
}
}
removeSysNotificationItem(hashcode) {
NotificationService.remove(hashcode);
}
startTargetAbility(itemData) {
Log.showInfo(TAG, 'startTargetAbility');
//close window
AppStorage.Set("showStatusBar", true);
this.mWindowManager.setWindowMin((result) => {
Log.showInfo(TAG, `setWindowMin ${result}`);
});
//open app
Log.showInfo(TAG, `itemClick wantAgent ${JSON.stringify(itemData.want)} id: ${itemData.id}`);
let TriggerInfo = {
code: 0,
want: '',
permission: '',
extraInfo: {}
};
wantAgent.trigger(itemData.want, TriggerInfo, ((err, data) => {
Log.showInfo(TAG, `itemClick wantAgent trigger err ${JSON.stringify(err)} data ${JSON.stringify(data)}`);
}));
//remove notification
this.removeNotificationItem(itemData, true);
}
loadFlowControlInfos() {
Log.showInfo(TAG, 'loadFlowControlInfos enter');
let notificationConfig = NotificationConfig.readNotificationConfig('statusbar')
Log.showInfo(TAG, 'NotificationConfig: ' + JSON.stringify(notificationConfig));
if (CheckEmptyUtils.isEmpty(notificationConfig)) {
Log.showInfo(TAG, 'NotificationConfig is no definition');
Log.showInfo(TAG, 'loadFlowControlInfos end');
return
}
this.mNotificationCtrl['currentTotal'] = 0;
this.mNotificationCtrl['limitTotal'] = notificationConfig.limitTotal
this.mNotificationCtrl['app'] = new Map();
for (let item of notificationConfig.app) {
let tmp = {
'canShow': item.canShow,
'currentNum': 0,
'limit': item.limit
}
this.mNotificationCtrl['app'].set(item.bundleName, tmp);
}
Log.showInfo(TAG, 'mNotificationCtrl: ' + JSON.stringify(this.mNotificationCtrl));
Log.showInfo(TAG, 'loadFlowControlInfos end');
}
isCanShow(bundleName: string): boolean {
Log.showInfo(TAG, 'isCanShow');
let result: boolean = true
if (!CheckEmptyUtils.isEmpty(this.mNotificationCtrl)) {
let currentTotal = this.mNotificationCtrl['currentTotal']
let limitTotal = this.mNotificationCtrl['limitTotal']
Log.showInfo(TAG, `isCanShow Total: currentTotal=${currentTotal},limitTotal=${limitTotal}`);
if (currentTotal + 1 > limitTotal) {
result = false
} else if (this.mNotificationCtrl['app'].has(bundleName)) {
let tmp = this.mNotificationCtrl['app'].get(bundleName)
Log.showInfo(TAG, `isCanShow appTotal: canShow=${tmp['canShow']},tmp['currentNum']=${tmp['currentNum']}`);
if (tmp['canShow'] === false || (tmp['currentNum'] + 1 > tmp['limit'])) {
result = false
}
}
}
Log.showInfo(TAG, `isCanShow :${result}`);
return result;
}
updateFlowControlInfos(bundleName: string, plusOrMinus: boolean): void {
Log.showInfo(TAG, `updateFlowControlInfos`);
if (!CheckEmptyUtils.isEmpty(this.mNotificationCtrl)) {
if (this.mNotificationCtrl['app'].has(bundleName)) {
let tmp = this.mNotificationCtrl['app'].get(bundleName)
if (plusOrMinus) {
tmp['currentNum'] += 1
} else if (tmp['currentNum'] > 0) {
tmp['currentNum'] -= 1
}
this.mNotificationCtrl['app'].set(bundleName, tmp)
}
if (plusOrMinus) {
this.mNotificationCtrl['currentTotal'] += 1
} else if (this.mNotificationCtrl['currentTotal'] > 0) {
this.mNotificationCtrl['currentTotal'] -= 1
}
}
Log.showInfo(TAG, `updateFlowControlInfos:${JSON.stringify(this.mNotificationCtrl)}`);
}
}
let viewModel = new ViewModel();
export default viewModel as ViewModel;

View File

@ -0,0 +1,36 @@
{
"color": [
{
"name":"notificationitem_background",
"value":"#ffffff"
},
{
"name":"title_text_color",
"value":"#222D37"
},
{
"name":"content_text_color",
"value":"#FF435563"
},
{
"name":"name_text_color",
"value":"#435563"
},
{
"name": "nonotification_text_color",
"value": "#ffffffff"
},
{
"name":"dialog_font_color",
"value":"#ffffff"
},
{
"name":"dialog_font_back_color",
"value":"#0759f6"
},
{
"name": "confirm_divider_color",
"value": "#E3E3E3"
}
]
}

View File

@ -0,0 +1,148 @@
{
"float": [
{
"name": "notification_title_fontsize",
"value": "20"
},
{
"name": "notification_expanded_text_maxheight",
"value": "295"
},
{
"name": "notification_content_fontsize",
"value": "20"
},
{
"name": "notification_content_lineheight",
"value": "20"
},
{
"name": "notification_content_maxlines",
"value": "1"
},
{
"name": "content_margin_top",
"value": "10"
},
{
"name": "body_margin_top",
"value": "10"
},
{
"name": "item_opicaty",
"value": "0.9"
},
{
"name": "item_borderradius",
"value": "20"
},
{
"name": "item_margintop",
"value": "10"
},
{
"name": "item_marginleft",
"value": "10"
},
{
"name": "item_marginright",
"value": "10"
},
{
"name": "item_paddingleft",
"value": "20"
},
{
"name": "item_paddingright",
"value": "20"
},
{
"name": "item_paddingbottom",
"value": "20"
},
{
"name": "item_setting_image_width",
"value": "30"
},
{
"name": "item_setting_image_height",
"value": "30"
},
{
"name": "item_delete_image_width",
"value": "30"
},
{
"name": "item_delete_image_height",
"value": "30"
},
{
"name": "titleitem_row_space",
"value": "10"
},
{
"name": "titleitem_height",
"value": "50"
},
{
"name": "title_image_width",
"value": "30"
},
{
"name": "title_image_height",
"value": "30"
},
{
"name": "title_name_fontsize",
"value": "20"
},
{
"name": "title_time_fontsize",
"value": "20"
},
{
"name": "displayicon_width",
"value": "20"
},
{
"name": "displayicon_height",
"value": "20"
},
{
"name": "deleteall_image_opacity",
"value": "0.9"
},
{
"name": "setting_title_fontsize",
"value": "28"
},
{
"name": "setting_cont_fontsize",
"value": "26"
},
{
"name": "setting_border_width",
"value": "1"
},
{
"name": "setting_border_radius",
"value": "30"
},
{
"name": "confirm_title_fontsize",
"value": "28"
},
{
"name": "confirm_cont_fontsize",
"value": "26"
},
{
"name": "confirm_divider_height",
"value": "20"
},
{
"name": "confirm_button_height",
"value": "60"
}
]
}

View File

@ -0,0 +1,36 @@
{
"string": [
{
"name": "noticeitem",
"value": "noticeitem"
},
{
"name": "nonotification_text",
"value": "无通知"
},
{
"name": "closeNotification",
"value": "关闭通知"
},
{
"name": "moreSettings",
"value": "更多设置"
},
{
"name": "cancel",
"value": "取消"
},
{
"name": "close",
"value": "关闭"
},
{
"name": "closeNovice",
"value": "关闭通知"
},
{
"name": "confirm_message",
"value": "是否关掉”%s“的所有通知?"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1,36 @@
{
"string": [
{
"name": "noticeitem",
"value": "noticeitem"
},
{
"name": "nonotification_text",
"value": "no notification"
},
{
"name": "closeNotification",
"value": "Close Notification"
},
{
"name": "moreSettings",
"value": "More Settings"
},
{
"name": "cancel",
"value": "Cancel"
},
{
"name": "close",
"value": "Turn Off"
},
{
"name": "closeNovice",
"value": "Turn Off Notificaiton"
},
{
"name": "confirm_message",
"value": "Do you want to turn off all notifications of '%s'?"
}
]
}

View File

@ -0,0 +1,8 @@
{
"limitTotal":6,
"app":
[
{ "bundleName": "com.example.actsanspublishsoundtest","canShow":true, "limit": 5 },
{ "bundleName": "com.ohos.app2","canShow":true, "limit": 3 }
]
}

View File

@ -0,0 +1,36 @@
{
"string": [
{
"name": "noticeitem",
"value": "noticeitem"
},
{
"name": "nonotification_text",
"value": "无通知"
},
{
"name": "closeNotification",
"value": "关闭通知"
},
{
"name": "moreSettings",
"value": "更多设置"
},
{
"name": "cancel",
"value": "取消"
},
{
"name": "close",
"value": "关闭"
},
{
"name": "closeNovice",
"value": "关闭通知"
},
{
"name": "confirm_message",
"value": "是否关掉”%s“的所有通知?"
}
]
}

View File

@ -0,0 +1,19 @@
apply plugin: 'com.huawei.ohos.library'
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
}

View File

@ -0,0 +1,23 @@
{
"app": {
"bundleName": "com.ohos.systemui",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {
},
"module": {
"package": "com.ohos.notificationservice",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "notificationservice",
"moduleType": "har"
}
}
}

View File

@ -0,0 +1,357 @@
/*
* Copyright (c) 2021 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 NotificationManager from '../../../../../../../../common/src/main/ets/default/abilitymanager/notificationManager.ets';
import BundleManager from '../../../../../../../../common/src/main/ets/default/abilitymanager/bundleManager.ets';
import Log from '../../../../../../../../common/src/main/ets/default/Log.ets';
import Constants,{NotificationItemData} from './common/constants.ets';
import {SlotLevel} from '@ohos.notification'
import Media from '@ohos.multimedia.media'
const TAG = 'NotificationService';
let mNotificationList;
let mSubscriber;
let mDate;
let mAppName;
let mEmptyArray;
/**
* Responsible for notification binding and interaction between View and Model.
*/
export class NotificationService {
media:any
constructor() {
let tempLink = AppStorage.SetAndLink('notificationList', [])
mNotificationList = tempLink.get()
Log.showInfo(TAG, `NotificationService constructor ${JSON.stringify(mNotificationList)}`)
this.media=Media.createAudioPlayer()
this.media.src='file://system/etc/Light.ogg'
}
initNotificationService() {
Log.showInfo(TAG, 'initNotificationCenter')
mDate = new Date();
mAppName = new Map();
mEmptyArray = [];
if (mSubscriber == undefined || mSubscriber == null) {
this.createNotificationCallback();
Log.showInfo(TAG, `initNotificationCenter, if: ${JSON.stringify(mSubscriber)}`);
}
this.getAllActiveNotifications();
Log.showInfo(TAG, 'initNotificationCenter end')
}
updateNotification() {
Log.showInfo(TAG, `updateNotification list: ${JSON.stringify(mNotificationList)}`);
Log.showInfo(TAG, `updateNotification len: ${mNotificationList.length}`);
let listLink = AppStorage.Link('notificationList');
listLink.set(mNotificationList);
Log.showInfo(TAG, `updateNotification list: ${JSON.stringify(listLink.get())}`);
}
/**
* Call the method to receive notification events.
*/
createNotificationCallback() {
Log.showInfo(TAG, 'createNotificationCallback enter ====================');
mSubscriber = {
onConsume: this.consumeCallback.bind(this),
onCancel: this.OnCancelCallback.bind(this)
}
Log.showInfo(TAG, `createNotificationCallback, ${JSON.stringify(mSubscriber)}`);
Log.showInfo(TAG, `createNotificationCallback, ${JSON.stringify(mSubscriber.onConsume)}`);
Log.showInfo(TAG, `createNotificationCallback, ${JSON.stringify(mSubscriber.onCancel)}`);
NotificationManager.subscribeNotification(TAG, mSubscriber, this.subscribeCallback.bind(this));
Log.showInfo(TAG, 'createNotificationCallback end ====================');
}
/**
* Call the method before current process finished.
*/
async unRegisterNotificationSubscriber() {
if (mSubscriber != undefined && mSubscriber != null) {
NotificationManager.unsubscribeNotification(TAG, mSubscriber);
}
}
/**
* The callback method that will be called after receiving a notification
*
* @param {Object} err - Error may occur.
* @param {Object} data - Callback data.
*/
consumeCallback(err, data) {
Log.showInfo(TAG, 'consumeCallback started');
Log.showInfo(TAG, 'sortingMap' + JSON.stringify(data.sortingMap||{}))
Log.showInfo(TAG, JSON.stringify(data));
let request = data?.request;
if (request == null || request == undefined) {
Log.showInfo(TAG, 'consumeCallback request is empty');
return;
}
let sortingMap = data?.sortingMap;
if (sortingMap == null || sortingMap == undefined) {
Log.showInfo(TAG, 'consumeCallback sortingMap is empty');
return;
}
this.handleRequest(request,sortingMap,Constants.GET_NEW_NOTIFICATION);
}
parseRequest(request,appName,icon){
Log.showInfo(TAG, `want = ${JSON.stringify(request.wantAgent)}`);
Log.showInfo(TAG, `actionButtons = ${JSON.stringify(request.actionButtons)}`);
Log.showInfo(TAG, `largeIcon = ${request.largeIcon}`);
let notificationItem:NotificationItemData = {
id: request.id,
hashcode: request.hashCode,
contentType: request?.content?.contentType + '',
timestamp: request.deliveryTime,
time: this.getStandardTime(request.deliveryTime),
name: appName,
want: request.wantAgent,
bundleName: request.creatorBundleName,
actionButtons: request.actionButtons,
smallIcon: icon,
largeIcon: request.largeIcon,
};
switch (request?.content?.contentType) {
case NotificationManager.TYPE_BASIC:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_BASIC_TEXT ====================`);
notificationItem.title = request.content.normal?.title ?? '';
notificationItem.text = request.content.normal?.text ?? '';
notificationItem.additionalText = request.content.normal?.additionalText ?? '';
break;
case NotificationManager.TYPE_LONG:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_LONG_TEXT ====================`);
notificationItem.title = request.content.longText?.title ?? '';
notificationItem.text = request.content.longText?.text ?? '';
notificationItem.additionalText = request.content.longText?.additionalText ?? '';
notificationItem.briefText = request.content.longText?.briefText ?? '';
notificationItem.expandedTitle = request.content.longText?.expandedTitle ?? '';
notificationItem.longText = request.content.longText?.longText ?? '';
break;
case NotificationManager.TYPE_MULTI:
Log.showInfo(TAG, `contentType NOTIFICATION_CONTENT_MULTILINE ====================`);
notificationItem.title = request.content.multiLine?.title ?? '';
notificationItem.text = request.content.multiLine?.text ?? '';
notificationItem.additionalText = request.content.multiLine?.additionalText ?? '';
notificationItem.briefText = request.content.multiLine?.briefText ?? '';
notificationItem.longTitle = request.content.multiLine?.longTitle ?? '';
notificationItem.lines = request.content.multiLine?.lines ?? mEmptyArray;
Log.showInfo(TAG, `multilines: ${JSON.stringify(request.content.multiLine?.lines)}`)
break;
default:
Log.showInfo(TAG, 'no match content type');
break;
}
return notificationItem
}
handleRequest(request,sortingMap, processType) {
Log.showInfo(TAG, `request : ${JSON.stringify(request)}`)
Log.showInfo(TAG, `processType : ${processType}`)
let contentType = request?.content?.contentType;
if (contentType == null || contentType == undefined) {
Log.showInfo(TAG, 'Request contentType is empty');
return;
}
let slotLevel;
try{
slotLevel=sortingMap?.sortings[request.hashCode]?.slot.level;
}catch(e){
Log.showInfo(TAG, `slot level get error: ${e.toString()}`);
}
Log.showInfo(TAG, `slotLevel = ${slotLevel}`);
this.getAppName(request.creatorBundleName, (AppName) => {
Log.showInfo(TAG, `notificationItem AppName = ${JSON.stringify(AppName)}`);
let notificationItem:NotificationItemData = this.parseRequest(request,AppName.appName,AppName.icon)
Log.showInfo(TAG, `notificationItem = ${JSON.stringify(notificationItem)}`);
if(slotLevel===SlotLevel.LEVEL_HIGH){
try{
this.media.play()
}catch(e){
Log.showInfo(TAG, `notificationItem id£º${notificationItem.id} alert error: ${e.toString()}`);
}
}
switch (processType) {
case Constants.GET_NEW_NOTIFICATION:
this.removeNotificationItem(notificationItem['hashcode'], false);
mNotificationList.unshift(notificationItem);
// mNotificationList.sort(this.compare('timestamp'));
this.updateNotification();
break;
case Constants.GET_EXIST_NOTIFICATION:
mNotificationList.unshift(notificationItem);
this.updateNotification();
break;
default:
Log.showInfo(TAG, 'no match process type');
break;
}
});
}
/**
* Get app name with bundleName.
*
* @param {string} bundleName - BundleName of the target app.
*/
getAppName(bundleName, callback) {
Log.showInfo(TAG, 'getAppName start ====================');
if (mAppName.has(bundleName)) {
callback(mAppName.get(bundleName));
Log.showInfo(TAG, 'HAS BUNDLENAME');
} else {
BundleManager.getBundleInfo(TAG, bundleName, 0, (data) => {
Log.showInfo(TAG, `getBundleInfo` + JSON.stringify(data));
let labelId = data.appInfo.labelId;
let iconId = data.appInfo.iconId;
let appName = '';
BundleManager.getResourceManager(TAG, bundleName, (item) => {
Log.showInfo(TAG, `BundleManager.getResourceManager ${BundleManager.getResourceManager}`);
item.getString(labelId, (error, value) => {
Log.showInfo(TAG, `getString` + JSON.stringify(value));
if (value != null && value != undefined) {
appName = value
}
item.getMediaBase64(iconId, (error, MediaValue) => {
Log.showInfo(TAG, `getMediaBase64` + JSON.stringify(MediaValue));
if (MediaValue != null) {
let appMessage = {
'appName': appName,
'icon': MediaValue
}
if (appName != null && appName != undefined && appName != '') {
mAppName.set(bundleName, appMessage);
}
callback(appMessage);
}
});
})
})
});
Log.showInfo(TAG, 'getAppName end ====================');
}
}
/**
* notification CancelCallback
*
* @param {Object} err - return err Message.
* @param {Object} data - return data Message.
*/
OnCancelCallback(err, data) {
console.info("===>OnCancelCallback data : ==> " + ` err:${JSON.stringify(err)} data:${JSON.stringify(data)}`);
this.removeNotificationItem(data.request.hashCode, false);
}
onUpdateCallback(err, data) {
Log.showInfo(TAG, `onUpdateCallback = ${JSON.stringify(data.request)}`);
}
/**
* The callback will be called after registered callback.
*
* @param {Object} err - Error may occur.
* @param {Object} data - Callback data.
*/
subscribeCallback(err, data) {
Log.showInfo(TAG, `subscribeCallback finished err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`)
}
/**
* Reformat the timestamp to hh:mm.
*
* @param {number} timestamp - Target timestamp.
*/
getStandardTime(timestamp) {
Log.showInfo(TAG, 'getStandardTime start ====================');
if (timestamp == 0 || timestamp == undefined || timestamp == null) {
return '';
}
mDate.setTime(timestamp);
let hoursNumber = mDate.getHours();
let minutesNumber = mDate.getMinutes();
let hours = hoursNumber < 10 ? '0' + hoursNumber : hoursNumber;
let minutes = minutesNumber < 10 ? '0' + minutesNumber : minutesNumber;
return hours + ':' + minutes;
}
/**
* Compare method will be used when sorting a two-dimensional array.
*
* @param {string} property - Property in the object will be sorted.
*/
compare(params) {
return function (item1, item2) {
var itemTime1 = item1[params];
var itemTime2 = item2[params];
return itemTime2 - itemTime1;
}
}
/**
* Remove all notifications.
*/
removeAllNotifications() {
mNotificationList = []
this.updateNotification()
NotificationManager.removeAll(TAG, (err, data) => {
Log.showInfo(TAG, `removeAll , err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`);
});
}
removeNotificationItem(hashCode, isDelSysConent) {
Log.showInfo(TAG, `removeNotificationItem start, hashCode: ${hashCode}`);
for (let i = 0, len = mNotificationList.length; i < len; i++) {
if (mNotificationList[i].hashcode == hashCode) {
Log.showInfo(TAG, `removeNotificationItem i = ${i}`);
mNotificationList.splice(i, 1);
// mNotificationList.pop(i);
break;
}
}
this.updateNotification()
if (isDelSysConent) {
this.removeSysNotificationItem(hashCode);
}
}
removeSysNotificationItem(hashCode) {
NotificationManager.remove(TAG, hashCode, (err, data) => {
Log.showInfo(TAG, `removeNotificationItem, err: ${JSON.stringify(err)} data: ${JSON.stringify(data)}`);
})
Log.showInfo(TAG, `removeNotificationItem end, length: ${mNotificationList.length}`);
}
getAllActiveNotifications() {
Log.showInfo(TAG, `getAllActiveNotifications`);
NotificationManager.getAllActiveNotifications(TAG, (err, requestsArr) => {
Log.showInfo(TAG, `getAllActiveNotifications err: ${JSON.stringify(err)}`);
Log.showInfo(TAG, `getAllActiveNotifications requestsArr: ${JSON.stringify(requestsArr)}`);
if (Array.isArray(requestsArr)) {
for(let i = 0,len = requestsArr.length; i< len; i++) {
this.handleRequest(requestsArr[i],null, Constants.GET_EXIST_NOTIFICATION);
}
} else {
mNotificationList = [];
}
})
}
}
let notificationService = new NotificationService();
export default notificationService as NotificationService;

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 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 {
static GET_NEW_NOTIFICATION: number = 0;
static GET_EXIST_NOTIFICATION: number = 1;
}
export interface NotificationItemData{
id:string;
hashcode:string;
contentType:string;
timestamp:string;
time:string;
name:string;
want:any;
actionButtons:any[];
bundleName:string;
smallIcon?:Resource|string;
largeIcon?:Resource|string;
title?:string;
text?:string;
additionalText?:string;
briefText?:string;
expandedTitle?:string;
longText?:string;
lines?:any[];
longTitle?:string;
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "quicklysetting_library",
"value": "quicklysetting_library"
}
]
}

View File

@ -0,0 +1,22 @@
apply plugin: 'com.huawei.ohos.library'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion rootProject.ext.version.compileSdk
defaultConfig {
compatibleSdkVersion rootProject.ext.version.compatibleSdk
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
implementation project(':common')
implementation project(':features:batterycomponent')
}

View File

@ -0,0 +1,23 @@
{
"app": {
"bundleName": "com.ohos.screenlock",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.screenlock",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "screenlock",
"moduleType": "har"
},
"srcPath": "default"
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 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 {
static WIN_NAME = "ScreenLockWindow"
//Shortcut params
static SHORTCUT_CIRCLE_WIDTH = '80px'
static SHORTCUT_CIRCLE_HEIGHT = '80px'
static SHORTCUT_TEXT_SIZE = '24px'
static SHORTCUT_TEXT_WIDTH = '48px'
static SHORTCUT_TEXT_HEIGHT = '34px'
static SHORTCUT_BLOCK_HEIGHT = '10px'
static SHORTCUT_HEIGHT = '150px'
//layout params - Pic
static FULL_CONTAINER_WIDTH = '100%'
static FULL_CONTAINER_HEIGHT = '100%'
static HALF_CONTAINER_WIDTH = '50%'
//The refresh interval
static INTERVAL = 1000
//digitalpssword mask diameter
static DIGITALPSD_IC_DIAMETER = 12
//digitalpssword keybord background diameter
static DIGITALPSD_BUTTON_DIAMETER = 60
//digitalpssword keybord background diameter
static DIGITALPSD_BUTTON_RECT_WH = 100
static DIGITALPSD_BUTTON_RECT_HH = 50
//digital keybord
static CALL_PHONE = -1
static DEL_PWD = -2
static GO_BACK = -3
static NUMKEY_BOARD = [{index: 0, row1: '1', row2: ' ', value: 1, bkg: false},
{index: 1, row1: '2', row2: 'ABC', value: 2, bkg: false},
{index: 2, row1: '3', row2: 'DEF', value: 3, bkg: false},
{index: 3, row1: '4', row2: 'GHI', value: 4, bkg: false},
{index: 4, row1: '5', row2: 'JKL', value: 5, bkg: false},
{index: 5, row1: '6', row2: 'MNO', value: 6, bkg: false},
{index: 6, row1: '7', row2: 'PQRS', value: 7, bkg: false},
{index: 7, row1: '8', row2: 'TUV', value: 8, bkg: false},
{index: 8, row1: '9', row2: 'WXYZ', value: 9, bkg: false},
{index: 9, row1: $r('app.string.emergency_call'), row2: '', value: Constants.CALL_PHONE, bkg: false},
{index: 10,row1: '0', row2: '+', value: 0, bkg: false},
{index: 11,row1: $r('app.string.back'), row2: '', value: Constants.GO_BACK, bkg: false}];
//max password length
static PASSWORD_MAX_LEN = 32
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export interface UserData {
userId:number;
userName:string;
userIconPath:string;
}

View File

@ -0,0 +1,103 @@
/*
* 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 account_osAccount from '@ohos.account.osAccount'
import commonEvent from '@ohos.commonEvent';
import Log from '../../../../../../../../common/src/main/ets/default/Log.ets'
import {UserData} from '../data/userData.ets'
const TAG = "ScreenLock-AccountsModel"
const TYPE_ADMIN = 0;
const TYPE_NORMAL = 1;
const TYPE_GUEST = 2;
let mCommonEventSubscribeInfo = {
events: [
commonEvent.Support.COMMON_EVENT_USER_ADDED,
commonEvent.Support.COMMON_EVENT_USER_REMOVED
]
};
let mEventSubscriber
export default class AccountsModel {
modelInit() {
Log.showInfo(TAG, "start ModelInit")
this.getAllUsers()
commonEvent.createSubscriber(mCommonEventSubscribeInfo, this.createSubscriberCallBack.bind(this));
Log.showInfo(TAG, "start ModelInit finish")
}
private createSubscriberCallBack(err, data) {
Log.showInfo(TAG, "start createSubscriberCallBack " + JSON.stringify(data))
mEventSubscriber = data
commonEvent.subscribe(data, this.getAllUsers.bind(this));
Log.showInfo(TAG, "start createSubscriberCallBack finish")
}
private getAllUsers() {
Log.showInfo(TAG, "start getAllUsers")
let tempLink = AppStorage.SetAndLink('userList', []);
let accountList = tempLink.get();
let count = accountList.length;
accountList.splice(0, count)
Log.showInfo(TAG, "start query")
account_osAccount.getAccountManager().queryAllCreatedOsAccounts().then((list) => {
Log.showInfo(TAG, "start sort")
list.sort(this.sortAccount.bind(this));
for (const user of list) {
Log.showInfo(TAG, "start get user" + JSON.stringify(user))
if (user.isActived) {
AppStorage.SetOrCreate('userId', user.localId)
}
account_osAccount.getAccountManager().getOsAccountProfilePhoto(user.localId).then((path) => {
Log.showInfo(TAG, "start get photo:" + path)
let userData: UserData = {
userId: user.localId,
userName: user.localName,
userIconPath: path
}
accountList.push(userData)
})
}
})
}
private sortAccount(info1, info2): number {
if (info1.isActived || info2.isActived) {
return info1.isActived ? -1 : 1;
} else if (info1.type.ADMIN == TYPE_ADMIN || info2.type.ADMIN == TYPE_ADMIN) {
return info1.type.ADMIN == TYPE_ADMIN ? -1 : 1;
} else if ( info1.type.GUEST == TYPE_GUEST || info2.type.GUEST == TYPE_GUEST) {
return info1.type.GUEST == TYPE_GUEST ? 1 : -1;
} else {
return info2.localId - info1.localId;
}
}
onUserSwitch(userId: number) {
Log.showInfo(TAG, "onUserSwitch:" + userId)
account_osAccount.getAccountManager().activateOsAccount(userId).then(() => {
Log.showInfo(TAG, "activateOsAccount")
})
Log.showInfo(TAG, "onUserSwitch:" + userId + "finish")
}
modelFinish() {
Log.showInfo(TAG, "start modelFinish")
commonEvent.unsubscribe(mEventSubscriber);
}
}

View File

@ -0,0 +1,230 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../common/src/main/ets/default/Log.ets'
import ScreenLockMar from '@ohos.screenlock';
import featureAbility from '@ohos.ability.featureAbility'
import settings from '@ohos.settingsnapi';
import windowManager from '@ohos.window'
import Constants from '../common/constants.ets'
import UserIDM from '@ohos.useridm'
import UserAuth from '@ohos.userauth'
import PinAuth from '@ohos.pinauth'
import util from '@ohos.util';
import WallpaperMar from '@ohos.app.wallpaperability'
const TAG = 'ScreenLock-ScreenLockModel';
export enum AuthType {
//Authentication type pin.
PIN = 1,
//Authentication type face.
FACE = 2
}
export enum AuthSubType {
//Authentication sub type six number pin.
PIN_SIX = 10000,
//Authentication sub type self defined number pin.
PIN_NUMBER = 10001,
//Authentication sub type mixed number pin.
PIN_MIXED = 10002,
//Authentication sub type 2D face.
FACE_2D = 20000,
//Authentication sub type 3D face.
FACE_3D = 20001
}
export enum AuthTurstLevel {
//Authentication result trusted level 1.
ATL1 = 10000,
//Authentication result trusted level 2.
ATL2 = 20000,
//Authentication result trusted level 3.
ATL3 = 30000,
//Authentication result trusted level 4.
ATL4 = 40000
}
export enum GetPropertyType {
//Authentication remain times.
AUTH_SUB_TYPE = 1,
//Authentication remain times.
REMAIN_TIMES = 2,
//Authentication remain times.
FREEZING_TIME = 3
}
export enum ResultCode {
//success
SUCCESS = 0,
//fails
FAIL = 1,
}
export default class ScreenLockModel {
static UserIdentityManager = new UserIDM.UserIdentityManager();
static UserAuthManager = new UserAuth.UserAuth();
static PINAuthManager = new PinAuth.PINAuth();
static getScreenLockWallpaper(callback) {
Log.showInfo(TAG, 'getScreenLockWallpaper');
WallpaperMar.getPixelMap(WallpaperMar.WALLPAPER_LOCKSCREEN, callback)
}
static eventListener(typeName: string, callback) {
Log.showInfo(TAG, `eventListener:typeName ${typeName}`);
ScreenLockMar.on(typeName, (err, data) => {
Log.showInfo(TAG, `eventListener:callback err:${JSON.stringify(err)} data:${JSON.stringify(data)}`);
callback(data);
})
}
static sendScreenLockEvent(typeName: string, typeNo: number, callback) {
Log.showInfo(TAG, `sendScreenLockEvent: typeName ${typeName} typeNo ${typeNo} `);
ScreenLockMar.sendScreenLockEvent(typeName, typeNo, (err, data) => {
Log.showInfo(TAG, `sendScreenLockEvent:callback err:${JSON.stringify(err)} data:${JSON.stringify(data)}`);
callback(err, data);
})
}
static showScreenLockWindow(callback) {
Log.showInfo(TAG, 'showScreenLockWindow');
windowManager.find(Constants.WIN_NAME).then((win) => {
Log.showInfo(TAG, 'find window finish');
win.show().then(() => {
Log.showInfo(TAG, `window show`);
callback();
})
})
}
static hiddenScreenLockWindow(callback) {
Log.showInfo(TAG, 'hiddenScreenLockWindow');
windowManager.find(Constants.WIN_NAME).then((win) => {
Log.showInfo(TAG, 'find window finish');
win.hide().then(() => {
Log.showInfo(TAG, `window hide`);
callback();
})
})
}
static timeFormatMonitor(callback): void {
Log.showInfo(TAG, 'timeFormatMonitor');
let urivar = settings.getUri('settings.time.format')
let helper = featureAbility.acquireDataAbilityHelper(urivar);
callback(ScreenLockModel.isUsing24hFormat(helper));
helper.on("dataChange", urivar, (err) => {
if (err.code !== 0) {
Log.showError(TAG, `failed to getAbilityWant because ${err.message}`);
return;
} else {
callback(ScreenLockModel.isUsing24hFormat(helper));
}
Log.showInfo(TAG, 'observer reveive notifychange on success data : ' + JSON.stringify(err))
})
}
static isUsing24hFormat(helper): boolean {
Log.showInfo(TAG, 'isUsing24hFormat');
let isUsing24hFormat: boolean = false;
let getRetValue = settings.getValue(helper, 'settings.time.format', '24')
if (getRetValue === '12') {
isUsing24hFormat = false;
} else if (getRetValue === '24') {
isUsing24hFormat = true;
}
return isUsing24hFormat;
}
static openIDMSession(callback) {
Log.showInfo(TAG, 'openIDMSession');
ScreenLockModel.UserIdentityManager.openSession().then((credentialId) => {
Log.showInfo(TAG, `openIDMSession credentialId:${credentialId}`);
callback(credentialId);
}).catch((error) => {
Log.showInfo(TAG, `openIDMSession error:${JSON.stringify(error)}`);
})
}
static closeIDMSession() {
Log.showInfo(TAG, 'closeIDMSession');
ScreenLockModel.UserIdentityManager.closeSession();
}
static authUser(userId: number, challenge, callback) {
Log.showInfo(TAG, `authUser param: userId ${userId} challenge ${challenge}`);
ScreenLockModel.UserAuthManager.authUser(userId, challenge, AuthType.PIN,
AuthTurstLevel.ATL4, {
onResult: (result, extraInfo) => {
Log.showInfo(TAG, `authUser UserAuthManager.authUser onResult`);
callback(result, extraInfo);
},
onAcquireInfo: (moduleId, acquire, extraInfo) => {
Log.showInfo(TAG, `authUser UserAuthManager.authUser onAcquireInfo`);
}
}
)
}
static getAuthProperty(authType, keyArray, callback) {
Log.showInfo(TAG, `getAuthProperty param: authType ${authType} keyArray ${keyArray}`);
let request = {
'authType': authType,
'keys': keyArray
}
ScreenLockModel.UserAuthManager.getProperty(request).then((properties) => {
Log.showInfo(TAG, `getAuthProperty properties ${JSON.stringify(properties)}`);
callback(properties)
})
}
static registerPWDInputer(passType, password): Promise<void> {
Log.showInfo(TAG, `registerPWDInputer`);
return new Promise(function (resolve, reject) {
let result = ScreenLockModel.registerInputer(passType, password);
if (!result) {
Log.showInfo(TAG, `registerPWDInputer again`);
ScreenLockModel.unregisterInputer();
ScreenLockModel.registerInputer(passType, password);
}
if (result) {
resolve();
} else {
reject();
}
})
}
static registerInputer(passType, password): boolean {
Log.showInfo(TAG, `registerInputer`);
let result = ScreenLockModel.PINAuthManager.registerInputer({
onGetData: (passType, inputData) => {
Log.showInfo(TAG, `registerInputer onSetData passType:${passType}`);
let textEncoder = new util.TextEncoder();
let uint8PW = textEncoder.encode(password);
Log.showInfo(TAG, `registerInputer onSetData call`);
inputData.onSetData(passType, uint8PW);
}
})
Log.showInfo(TAG, `registerInputer result:${result} `);
return result;
}
static unregisterInputer() {
Log.showInfo(TAG, `unregisterInputer`);
ScreenLockModel.PINAuthManager.unregisterInputer();
}
}

View File

@ -0,0 +1,232 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../common/src/main/ets/default/Log.ets';
import ScreenLockModel, {AuthType, AuthSubType, GetPropertyType} from './screenLockModel';
import {ScreenLockStatus} from '../../../../../../../../common/src/main/ets/default/ScreenLockCommon.ets';
import Router from '@system.router';
const TAG = 'ScreenLock-ScreenLockService';
const URI_DIGITALPASSWORD = 'pages/digitalPassword'
const URI_MIXEDPASSWORD = 'pages/mixedPassword'
const URI_CUSTOMPASSWORD = 'pages/customPassword'
//Event type name
const EVENT_BEGIN_WAKEUP: string = 'beginWakeUp' //设备将要唤醒
const EVENT_END_WAKEUP: string = 'endWakeUp' //设备唤醒
const EVENT_BEGIN_SCREENON: string = 'beginScreenOn' //开始亮屏
const EVENT_END_SCREENON: string = 'endScreenOn' //设备亮屏
const EVENT_BEGIN_SCREENOFF: string = 'beginScreenOff' //开始灭屏
const EVENT_END_SCREENOFF: string = 'endScreenOff' //设备灭屏
const EVENT_UNLOCK_SCREEN: string = 'unlockScreen' //请求屏幕解锁
const EVENT_BEGIN_EXITANIMATION: string = 'beginExitAnimation' //动画结束
const EVENT_BEGIN_SLEEP: string = 'beginSleep' // 设备将要休眠
const EVENT_END_SLEEP: string = 'endSleep' //设备休眠
const EVENT_CHANGE_USER: string = 'changeUser' //切换用户
const EVENT_SCREENLOCK_ENABLE: string = 'screenlockEnabled' //锁屏锁屏应用是否可用
const UNLOCK_SCREEN_RESULT: string = 'unlockScreenResult' //请求解锁
const SCREENLOCK_DRAW_DONE: string = 'screenDrawDone' // 解锁界面绘制完成
const CHALLENGE_INT = 0
const MAIN_USER = 100
export enum UnlockResult {
Success = 0,
Fail = 1,
Cancel = 2
}
export {AuthSubType};
export class ScreenLockService {
init() {
Log.showInfo(TAG, 'init');
this.lockScreen();
this.monitorEvents();
}
monitorEvents() {
Log.showInfo(TAG, 'registered events start');
//设备将要唤醒
ScreenLockModel.eventListener(EVENT_BEGIN_WAKEUP, (data) => {
Log.showInfo(TAG, `EVENT_BEGIN_WAKEUP event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//设备唤醒
ScreenLockModel.eventListener(EVENT_END_WAKEUP, (data) => {
Log.showInfo(TAG, `EVENT_END_WAKEUP event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//开始亮屏
ScreenLockModel.eventListener(EVENT_BEGIN_SCREENON, (data) => {
Log.showInfo(TAG, `EVENT_BEGIN_SCREENON event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//设备亮屏
ScreenLockModel.eventListener(EVENT_END_SCREENON, (data) => {
Log.showInfo(TAG, `EVENT_END_SCREENON event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//设备将要休眠
ScreenLockModel.eventListener(EVENT_BEGIN_SLEEP, (data) => {
Log.showInfo(TAG, `EVENT_BEGIN_SLEEP event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//设备休眠
ScreenLockModel.eventListener(EVENT_END_SLEEP, (data) => {
Log.showInfo(TAG, `EVENT_END_SLEEP event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//设备灭屏
ScreenLockModel.eventListener(EVENT_END_SCREENOFF, (data) => {
Log.showInfo(TAG, `EVENT_END_SCREENOFF event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//切换用户
ScreenLockModel.eventListener(EVENT_CHANGE_USER, (data) => {
Log.showInfo(TAG, `EVENT_CHANGE_USER event data:${JSON.stringify(data)}`);
this.lockScreen();
})
//接收到屏幕解锁请求
ScreenLockModel.eventListener(EVENT_UNLOCK_SCREEN, (data) => {
Log.showInfo(TAG, `EVENT_UNLOCK_SCREEN event data:${JSON.stringify(data)}`);
this.unlockScreen();
});
Log.showInfo(TAG, 'registered events end');
}
lockScreen() {
Log.showInfo(TAG, `lockScreen`);
let status = AppStorage.Link('lockStatus')
Log.showInfo(TAG, `lockScreen lockStatus.get:${status?.get()}`);
let length = Router.getLength()
Log.showInfo(TAG, `Router.getLength: ${length}`)
for (let index = 1;index < length; index++) {
Log.showInfo(TAG, `back to index`);
Router.back();
}
if (!!status && status.get() == ScreenLockStatus.Locking) {
Log.showInfo(TAG, `lockScreen return`);
return;
}
//set the lockStatus to 'locking'
AppStorage.SetOrCreate('lockStatus', ScreenLockStatus.Locking);
//lock the screen
ScreenLockModel.showScreenLockWindow(() => {
Log.showInfo(TAG, `showScreenLockWindow finish`);
});
}
unlockScreen() {
Log.showInfo(TAG, `unlockScreen`);
ScreenLockModel.getAuthProperty(AuthType.PIN, [GetPropertyType.AUTH_SUB_TYPE, GetPropertyType.REMAIN_TIMES,
GetPropertyType.FREEZING_TIME], (properties) => {
Log.showInfo(TAG, `unlockScreenAUTH_SUB_TYPE:${properties.authSubType}`);
switch (properties.authSubType) {
case AuthSubType.PIN_SIX:
Log.showInfo(TAG, `unlockScreen Router.push:digitalPassword`);
Router.push({ uri: URI_DIGITALPASSWORD });
break;
case AuthSubType.PIN_MIXED:
Log.showInfo(TAG, `unlockScreen Router.push:mixedPassword`);
Router.push({ uri: URI_MIXEDPASSWORD });
break;
case AuthSubType.PIN_NUMBER:
Log.showInfo(TAG, `unlockScreen Router.push:customPassword`);
Router.push({ uri: URI_CUSTOMPASSWORD });
break;
default:
Log.showInfo(TAG, `unlock the screen`);
this.unlocking();
}
});
}
unlocking() {
Log.showInfo(TAG, `unlocking`);
let status = AppStorage.Link('lockStatus')
Log.showInfo(TAG, `unlocking lockStatus:${JSON.stringify(status?.get())}`);
if (!!status && status.get() == ScreenLockStatus.Unlock) {
Log.showInfo(TAG, `unlocking return`);
return;
}
//set the lockStatus to 'Unlock'
AppStorage.SetOrCreate('lockStatus', ScreenLockStatus.Unlock);
//unlock the screen
ScreenLockModel.hiddenScreenLockWindow(() => {
Log.showInfo(TAG, `hiddenScreenLockWindow finish`);
//notify the base service that the unlock is completed
this.notifyScreenResult(UnlockResult.Success);
});
}
notifyScreenResult(result: UnlockResult) {
Log.showInfo(TAG, `notifyScreenResult`);
ScreenLockModel.sendScreenLockEvent(UNLOCK_SCREEN_RESULT, result, (error, data) => {
Log.showInfo(TAG, `notifyScreenResult: error:${JSON.stringify(error)} data:${JSON.stringify(data)}`);
});
}
notifyDrawDone() {
Log.showInfo(TAG, `notifyDrawDone`);
//notify the base service that the screen is loaded
ScreenLockModel.sendScreenLockEvent(SCREENLOCK_DRAW_DONE, 0, (error, result) => {
Log.showInfo(TAG, `notifyDrawDone: error:${JSON.stringify(error)} result:${JSON.stringify(result)}`);
});
}
authUser(authSubType: AuthSubType, passwordData: number[] | string, callback): void {
Log.showInfo(TAG, `authUser authSubType:${authSubType}`);
let password: string = '';
if (typeof passwordData == 'string') {
password = passwordData;
} else {
password = passwordData.join('');
}
ScreenLockModel.registerPWDInputer(authSubType, password).then(() => {
Log.showInfo(TAG, `registerPWDInputer success`);
let userIdLink = AppStorage.Link('userId');
ScreenLockModel.authUser(userIdLink?.get() ?? MAIN_USER, CHALLENGE_INT, (result, extraInfo) => {
Log.showInfo(TAG, `authUser callback:${result} extraInfo:${JSON.stringify(extraInfo)}`);
ScreenLockModel.unregisterInputer();
callback(result, extraInfo);
})
}).catch(() => {
Log.showInfo(TAG, `registerPWDInputer fails`);
})
}
goBack() {
Log.showInfo(TAG, `goBack`);
Router.back();
ScreenLockModel.unregisterInputer();
}
}
let screenLockService = new ScreenLockService();
export default screenLockService as ScreenLockService;

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../common/src/main/ets/default/Log.ets'
import {ReadConfigFile} from '../../../../../../../../common/src/main/ets/default/ScreenLockCommon.ets'
const FILE_URI = '/data/accounts/account_0/applications/com.ohos.screenlock'
+ '/com.ohos.screenlock/assets/{0}/resources/rawfile/screenlock.json'
const TAG = 'ScreenLock-ScreenlockStyle';
export enum LockStyleMode {
SlideScreenLock = 1,
JournalScreenLock = 2,
CustomScreenLock = 3
}
class ScreenlockStyle {
private screenMode: LockStyleMode = LockStyleMode.SlideScreenLock
setMode(mode: LockStyleMode): number {
Log.showInfo(TAG, 'setMode:${mode}');
return this.screenMode = mode
}
getMode(): number {
Log.showInfo(TAG, 'getMode');
return this.screenMode
}
readMode(deviceType: string): number{
Log.showInfo(TAG, `readMode deviceType:${deviceType}`);
let modeJson = ReadConfigFile(FILE_URI.replace('{0}', deviceType))
Log.showInfo(TAG, `ReadConfigFile content:` + JSON.stringify(modeJson));
this.screenMode = modeJson.mode
return this.screenMode
}
}
let screenlockStyle = new ScreenlockStyle()
export default screenlockStyle as ScreenlockStyle

View File

@ -0,0 +1,78 @@
/**
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import ViewModel from '../../vm/accountsViewModel.ets'
import Constants from '../../common/constants.ets'
import {UserData} from '../../data/userData.ets'
const TAG = 'ScreenLock-Accounts'
@Component
export default struct Accounts {
@StorageLink("userList") accountList: UserData[] = []
private mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
this.mViewModel.viewModelInit()
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
this.mViewModel.viewModelFinish()
}
build() {
Row() {
List() {
ForEach(this.accountList, (item: any) => {
ListItem() {
UserItem({ userItem: item, viewModel: this.mViewModel })
}
})
}
.listDirection(Axis.Horizontal)
}
}
}
@Component
struct UserItem {
private userItem: any;
private viewModel: ViewModel;
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
if (this.userItem.userIconPath.length == 0) {
Image($r('app.media.ic_user_portrait'))
.width(Constants.SHORTCUT_CIRCLE_WIDTH)
.height(Constants.SHORTCUT_CIRCLE_WIDTH)
} else {
Image(this.userItem.userIconPath)
.width(Constants.SHORTCUT_CIRCLE_WIDTH)
.height(Constants.SHORTCUT_CIRCLE_WIDTH)
}
Text(this.userItem.userName)
.fontSize(Constants.SHORTCUT_TEXT_SIZE)
.fontColor($r('app.color.shortcut_text_color'))
//.fontWeight(FontWeight.Bold)
}
.onClick(event => {
this.viewModel.onUserSwitch(this.userItem.userId)
})
}
}

View File

@ -0,0 +1,36 @@
/**
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import ViewModel from '../../vm/batterySocViewModel.ets'
import Constants from '../../common/constants.ets'
const TAG = 'ScreenLock-BatterySoc'
@Component
export default struct BatterySoc {
@State mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
this.mViewModel.ViewModelInit()
}
build() {
Text(this.mViewModel.batterySocStr)
.fontSize($r('app.float.batterysoc_fontsize'))
.fontColor($r('app.color.batterysoc_text_color'))
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
import NumkeyBoard from './numkeyBoard.ets'
import ViewModel from '../../vm/customPSDViewModel.ets'
const TAG = 'ScreenLock-CustomPSD'
@Component
export default struct CustomPSD {
@State mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
Text(this.mViewModel.prompt)
.fontSize($r('app.float.custompsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ bottom: $r('app.float.custompsd_prompt_margin_bottom') })
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.width($r('app.float.custompsd_prompt_width'))
.height($r('app.float.custompsd_prompt_height'))
TextInput({ placeholder: '', text: this.mViewModel.password })
.type(InputType.Password)
.maxLength(Constants.PASSWORD_MAX_LEN)
.fontSize($r('app.float.custompsd_prompt_fontsize'))
.width($r('app.float.custompsd_input_width'))
.height($r('app.float.custompsd_input_height'))
.backgroundColor(Color.White)
.enterKeyType(EnterKeyType.Done)
.border({ width: 2, color: Color.Gray, radius: 15 })
.enabled(false)
.margin({ bottom: $r('app.float.custompsd_input_margin_bottom') })
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Text($r('app.string.emergency_call'))
.fontSize($r('app.float.custompsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.onClick(this.mViewModel.onCallPhone.bind(this.mViewModel))
Text($r('app.string.done'))
.fontSize($r('app.float.custompsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.onClick(() => {
Log.showInfo(TAG, `onClick`)
this.mViewModel.onAuthPassword(() => {
Log.showInfo(TAG, `onClick callback promptText:${JSON.stringify(this.mViewModel.prompt)}`)
});
})
}
.width(Constants.HALF_CONTAINER_WIDTH)
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height($r('app.float.custompsd_input_area_height'))
.margin({ bottom: $r('app.float.custompsd_passwdmask_margin_bottom') })
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
NumkeyBoard({
onKeypress: (index, callback) => this.mViewModel.onKeyPress(index, callback)
})
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height($r('app.float.custompsd_key_area_height'))
.margin({ bottom: $r('app.float.custompsd_key_area_margin_bottom') })
}
.width(Constants.FULL_CONTAINER_WIDTH)
}
}

View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import ViewModel from '../../vm/dateTimeViewModel.ets'
import Constants from '../../common/constants.ets'
import {ScreenLockStatus} from '../../../../../../../../../common/src/main/ets/default/ScreenLockCommon.ets'
const TAG = 'ScreenLock-DateTime'
@Component
export default struct DateTime {
@StorageLink('lockStatus') @Watch("onStatusChange") lockStatus: ScreenLockStatus = ScreenLockStatus.Locking
@State mViewModel: ViewModel = new ViewModel()
private isShowData: boolean= true
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
this.mViewModel.ViewModelInit()
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
this.mViewModel.stopPolling()
}
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
Text(this.mViewModel.timeVal)
.fontSize($r('app.float.time_fontsize'))
.fontColor($r('app.color.date_time_color'))
.margin({ top: $r('app.float.time_top_margin'), bottom: $r('app.float.time_bottom_margin') })
if (this.isShowData) {
Row() {
Text($r('app.string.yyyy_mm_dd', this.mViewModel.dateVal.year, this.mViewModel.dateVal.month, this.mViewModel.dateVal.day))
.fontSize($r('app.float.date_fontsize'))
.fontColor($r('app.color.date_time_color'))
Text(this.mViewModel.weekVal).fontSize($r('app.float.date_fontsize'))
.fontColor($r('app.color.date_time_color'))
}
}
}
.width(Constants.FULL_CONTAINER_WIDTH)
}
onStatusChange(propName: string): void {
Log.showInfo(TAG, `onStatusChange`)
this.mViewModel.onStatusChange(this.lockStatus)
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
import NumkeyBoard from './numkeyBoard.ets'
import ViewModel from '../../vm/digitalPSDViewModel.ets'
const TAG = 'ScreenLock-DigitalPSD'
@Component
export default struct DigitalPSD {
@State mViewModel: ViewModel = new ViewModel()
@StorageLink('passwdMaskArr') passwdMaskArr: any[] = this.mViewModel.passwdMaskArr
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
Text(this.mViewModel.prompt)
.fontSize($r('app.float.digitalpsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ bottom: $r('app.float.digitalpsd_prompt_margin_bottom') })
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.width($r('app.float.digitalpsd_prompt_width'))
.height($r('app.float.digitalpsd_prompt_height'))
Grid() {
ForEach(this.passwdMaskArr, (item) => {
GridItem() {
Column()
.backgroundColor(item)
.clip(new Circle({ width: Constants.DIGITALPSD_IC_DIAMETER, height: Constants.DIGITALPSD_IC_DIAMETER }))
.width(Constants.DIGITALPSD_IC_DIAMETER)
.height(Constants.DIGITALPSD_IC_DIAMETER)
.border({ width: 2, color: $r('app.color.circle_background'), radius: 45 })
.alignItems(HorizontalAlign.Center)
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
.width($r('app.float.digitalpsd_passwdmask_width'))
.height($r('app.float.digitalpsd_passwdmask_height'))
.margin(0)
}
.margin({ bottom: $r('app.float.digitalpsd_passwdmask_margin_bottom') })
.width(Constants.FULL_CONTAINER_WIDTH)
.height( $r('app.float.digitalpsd_input_area_height'))
.flexShrink(1)
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
NumkeyBoard({
onKeypress: (index, callback) => this.mViewModel.onKeyPress(index, callback)
})
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height($r('app.float.digitalpsd_key_area_height'))
.margin({ bottom: $r('app.float.digitalpsd_key_area_margin_bottom') })
.flexShrink(0)
}
.width(Constants.FULL_CONTAINER_WIDTH)
}
}

View File

@ -0,0 +1,52 @@
/**
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import {ScreenLockStatus} from '../../../../../../../../../common/src/main/ets/default/ScreenLockCommon.ets'
import ViewModel from '../../vm/lockIconViewModel.ets'
import Constants from '../../common/constants.ets'
const TAG = 'ScreenLock-LockIcon'
@Component
export default struct LockIcon {
@StorageLink('lockStatus') @Watch("onStatusChange") lockStatus: ScreenLockStatus = ScreenLockStatus.Locking
@State mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
this.mViewModel.ViewModelInit()
}
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Image(this.mViewModel.iconPath)
.margin({ top: $r('app.float.lockicon_top_margin'), bottom: $r('app.float.lockicon_bottom_margin') })
.objectFit(ImageFit.Contain)
.width($r('app.float.lockicon_width'))
.height($r('app.float.lockicon_height'))
.fillColor($r('app.color.lock_ic_color'))
Text(this.mViewModel.cutMessage).fontSize($r('app.float.lock_prompt_fontsize'))
.fontColor($r('app.color.lock_prompt_color'))
}
.width(Constants.FULL_CONTAINER_WIDTH)
}
onStatusChange(propName: string): void {
Log.showInfo(TAG, `onStatusChange`)
Log.showInfo(TAG, `lockStatus:${this.lockStatus}`);
this.mViewModel.onStatusChange(this.lockStatus)
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
import ViewModel from '../../vm/mixedPSDViewModel.ets'
const TAG = 'ScreenLock-MixedPSD'
@Component
export default struct MixedPSD {
@State mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.mViewModel.prompt)
.fontSize($r('app.float.mixedpsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ bottom: $r('app.float.mixedpsd_prompt_margin_bottom') })
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.width($r('app.float.mixedpsd_prompt_width'))
.height($r('app.float.mixedpsd_prompt_height'))
TextInput({ placeholder: '', text: this.mViewModel.password })
.type(InputType.Password)
.maxLength(Constants.PASSWORD_MAX_LEN)
.fontSize($r('app.float.mixedpsd_prompt_fontsize'))
.width($r('app.float.mixedpsd_input_width'))
.height($r('app.float.mixedpsd_input_height'))
.backgroundColor(Color.White)
.enterKeyType(EnterKeyType.Done)
.border({ width: 2, color: Color.Gray, radius: 15 })
.enabled(!this.mViewModel.inhibitInput)
.onChange(this.mViewModel.onInputChange.bind(this.mViewModel))
.margin({ bottom: $r('app.float.mixedpsd_input_margin_bottom') })
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceBetween }) {
Text($r('app.string.emergency_call'))
.fontSize($r('app.float.mixedpsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.onClick(this.mViewModel.onCallPhone.bind(this.mViewModel));
Text($r('app.string.done'))
.fontSize($r('app.float.mixedpsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.textOverflow({ overflow: TextOverflow.None })
.onClick(() => {
Log.showInfo(TAG, `onClick`)
this.mViewModel.onAuthPassword(() => {
Log.showInfo(TAG, `onClick callback prompt:${this.mViewModel.prompt} inhibitInput:${this.mViewModel.inhibitInput}`)
});
})
}
.width(Constants.HALF_CONTAINER_WIDTH)
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height(Constants.FULL_CONTAINER_HEIGHT)
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height(Constants.FULL_CONTAINER_HEIGHT)
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
const TAG = 'ScreenLock-NumkeyBoard'
@Component
export default struct NumkeyBoard {
private onKeypress: (params, callback) => void;
@StorageLink('numKeyboard') numKeyboard: any[] = Constants.NUMKEY_BOARD;
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
aboutToDisappear() {
Log.showInfo(TAG, `aboutToDisappear`)
}
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Grid() {
ForEach(this.numKeyboard, (item: any) => {
GridItem() {
Stack({ alignContent: Alignment.Center }) {
Column({ space: 0 }) {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center
}) {
if (item.value == Constants.CALL_PHONE ||
item.value == Constants.GO_BACK ||
item.value == Constants.DEL_PWD) {
Text(item.row1)
.fontSize($r('app.float.digitalpsd_prompt_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width(Constants.FULL_CONTAINER_WIDTH)
.padding(0)
.margin(0)
} else {
Text(item.row1)
.fontSize($r('app.float.digitalpsd_row1_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width(Constants.FULL_CONTAINER_WIDTH)
.padding(0)
.margin(0)
}
if (!!item.row2) {
Text(item.row2)
.fontSize($r('app.float.digitalpsd_row2_fontsize'))
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.textAlign(TextAlign.Center)
.width(Constants.FULL_CONTAINER_WIDTH)
.padding(0)
.margin(0)
}
}
.height($r('app.float.digitalpsd_row_height'))
}
if (item.bkg) {
if (item.value == Constants.CALL_PHONE ||
item.value == Constants.GO_BACK ||
item.value == Constants.DEL_PWD) {
Column()
.backgroundColor(Color.Gray)
.opacity(0.5)
.clip(new Rect({
width: Constants.DIGITALPSD_BUTTON_RECT_WH,
height: Constants.DIGITALPSD_BUTTON_RECT_HH
}))
.width(Constants.DIGITALPSD_BUTTON_RECT_WH)
.height(Constants.DIGITALPSD_BUTTON_RECT_HH)
} else {
Column()
.backgroundColor(Color.Gray)
.opacity(0.5)
.clip(new Circle({
width: Constants.DIGITALPSD_BUTTON_DIAMETER,
height: Constants.DIGITALPSD_BUTTON_DIAMETER
}))
.width(Constants.DIGITALPSD_BUTTON_DIAMETER)
.height(Constants.DIGITALPSD_BUTTON_DIAMETER)
}
}
}
.onTouch((event: TouchEvent) => {
Log.showInfo(TAG, `onTouch`)
if (event.type == TouchType.Down) {
Log.showInfo(TAG, `TouchType.Down`)
item.bkg = true;
} else if (event.type == TouchType.Up) {
Log.showInfo(TAG, `TouchType.Up`)
item.bkg = false
}
})
.onClick(() => {
Log.showInfo(TAG, `onClick:${item.index}`)
setTimeout(this.onKeypress.bind(this), 0, item.index, (data) => {
Log.showInfo(TAG, `onClick callback is called`)
});
})
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr')
.width(Constants.FULL_CONTAINER_WIDTH)
.height(Constants.FULL_CONTAINER_HEIGHT)
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height(Constants.FULL_CONTAINER_HEIGHT)
}
}

View File

@ -0,0 +1,114 @@
/**
* 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
import power from '@ohos.power'
const TAG = 'ScreenLock-Shortcut'
const TAG_Shutdown = 'ScreenLock-Shutdown'
const TAG_Reboot = 'ScreenLock-Reboot'
@Component
export default struct Shortcut {
private shutdownIcon: Resource = $r("app.media.shutdown")
private shutdownLabel: Resource = $r("app.string.shutdown")
private rebootIcon: Resource = $r("app.media.reboot")
private rebootLabel: Resource = $r("app.string.reboot")
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
build() {
Row({ space:'30px' }) {
ShortcutComponent({
mIcon: this.shutdownIcon,
mLabel: this.shutdownLabel,
mClickEvent: () => this.onShutdownClick()
})
ShortcutComponent({
mIcon: this.rebootIcon,
mLabel: this.rebootLabel,
mClickEvent: () => this.onRebootClick()
})
}
.margin({left: '50px'})
}
onShutdownClick() {
Log.showInfo(TAG, `onShutdownClick`)
power.shutdownDevice("shutdown_device")
Log.showInfo(TAG, `power shutdown success`)
}
onRebootClick() {
Log.showInfo(TAG, `onRebootClick`)
power.rebootDevice("reboot_device")
Log.showInfo(TAG, `power reboot success`)
}
}
@Component
struct ShortcutComponent {
private mIcon: Resource
private mLabel: Resource
private mClickEvent: Function
aboutToAppear() {
Log.showInfo(TAG_Shutdown, `aboutToAppear Start`)
}
aboutToDisappear() {
Log.showInfo(TAG_Shutdown, `aboutToDisAppear`)
}
build() {
Column() {
Stack() {
Flex()
.backgroundColor($r('app.color.shortcut_icon_color'))
.clip(new Circle({ width: Constants.SHORTCUT_CIRCLE_WIDTH, height: Constants.SHORTCUT_CIRCLE_HEIGHT }))
.width(Constants.SHORTCUT_CIRCLE_WIDTH)
.height(Constants.SHORTCUT_CIRCLE_HEIGHT)
Image(this.mIcon)
.size({ width: Constants.SHORTCUT_CIRCLE_WIDTH, height: Constants.SHORTCUT_CIRCLE_HEIGHT})
.objectFit(ImageFit.Contain)
}
Column()
.width(Constants.SHORTCUT_CIRCLE_WIDTH)
.height(Constants.SHORTCUT_BLOCK_HEIGHT)
Text(this.mLabel)
.fontSize(Constants.SHORTCUT_TEXT_SIZE)
.fontColor($r('app.color.shortcut_text_color'))
.width(Constants.SHORTCUT_TEXT_WIDTH)
.height(Constants.SHORTCUT_TEXT_HEIGHT)
}
.width(Constants.SHORTCUT_CIRCLE_WIDTH)
.onClick(this.onItemClick.bind(this))
}
onItemClick(event: ClickEvent) {
Log.showInfo(TAG, `onItemClick`)
if (this.mClickEvent) {
this.mClickEvent()
}
}
}

View File

@ -0,0 +1,38 @@
/**
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import Constants from '../../common/constants.ets'
import BatteryIcon from '../../../../../../../../../features/batterycomponent/src/main/ets/default/pages/batteryIcon.ets'
const TAG = 'ScreenLock-StatusBar'
@Component
export default struct statusBar {
@StorageLink('minHeight') minHeight: number = 0
build() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.End }) {
BatteryIcon()
}
.width(Constants.FULL_CONTAINER_WIDTH)
.height(this.minHeight)
}
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) 2021 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 Log from '../../../../../../../../../common/src/main/ets/default/Log.ets'
import ViewModel from '../../vm/wallpaperViewModel.ets'
import Constants from '../../common/constants.ets'
const TAG = 'ScreenLock-Wallpaper'
@Component
export default struct Wallpaper {
@State mViewModel: ViewModel = new ViewModel()
aboutToAppear() {
Log.showInfo(TAG, `aboutToAppear`)
this.mViewModel.ViewModelInit()
}
build() {
Image(this.mViewModel.screenlockWallpaper)
.width(Constants.FULL_CONTAINER_WIDTH)
.height(Constants.FULL_CONTAINER_HEIGHT)
.objectFit(ImageFit.Cover)
}
}

Some files were not shown because too many files have changed in this diff Show More