diff --git a/UI/MultimodalEvent/README_en.md b/UI/MultimodalEvent/README_en.md
new file mode 100644
index 0000000000000000000000000000000000000000..625d4c1ef835c089f8b269ac7795710fd069ed09
--- /dev/null
+++ b/UI/MultimodalEvent/README_en.md
@@ -0,0 +1,26 @@
+# Multimodal Input Standard Event
+
+##### Introduction
+
+In this sample, the **MultimodalEventHandle** class is used to register a standard event that is derived from the base class **StandardizedEventHandle**, handle the standard event, and map the input events from different devices to the standard event.
+
+##### Usage
+
+1. Call the **registerStandardizedEventHandle** method in the **MultimodalEventHandle** class to register a standard event.
+
+2. Implement the method for handling this standard event and execute the corresponding logic function.
+
+3. After the event is handled, call the **unregisterStandardizedEventHandle** method to unregister the event.
+
+In this sample, when an input event occurs, a dialog box is displayed for users. This indicates that the standard event handling is complete.
+
+##### Constraints
+
+For details about the applicable devices of multimodal input standard events, see [Multimodal Input Standard Event Overview](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ui-multimodal-standard-event-overview-0000001079953054).
+
+In addition to **CommonEventHandle**, **MediaEventHandle**, **SystemEventHandle**, and **TelephoneEventHandle**, Multimodal Input provides the **KeyEventHandle** and **TouchEventHandle** classes for handling standard key events and standard touch events, respectively.
+
+1. When receiving an original input event such as a key or touch event, Multimodal Input first determines whether to map the event to a standard common event \(handled by **CommonEventHandle**\), standard media event \(handled by **MediaEventHandle**\), standard system event \(handled by **SystemEventHandle**\), or standard call event \(handled by **TelephoneEventHandle**\). If any of these standard events has been registered and the original input event hits an action in this standard event, the callback of this standard event will be executed.
+2. If this original event is not mapped to any of the preceding four standard events, Multimodal Input further determines whether to map it to a standard key event \(handled by **KeyEventHandle**\) or standard touch event \(handled by **TouchEventHandle**\). If the mapping is established and the two types of standard events have been registered, their callbacks will be executed.
+3. If no standard event has been registered or the original input event does not have a mapped standard event, the **Ability** object continues dispatching this original input event.
+
diff --git a/UI/MultimodalEvent/README_zh.md b/UI/MultimodalEvent/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..bc7dd8d8c793c48f79be95465296871cbd630eb2
--- /dev/null
+++ b/UI/MultimodalEvent/README_zh.md
@@ -0,0 +1,30 @@
+# 多模输入事件标准化
+
+##### 简介
+
+本示例通过提供处理标准化事件的类MultimodalEventHandle对标准化基类StandardizedEventHandle衍生出来的其它标准化事件进行注册,然后对相应的事件进行处理,将不同输入设备的输入事件映射到标准化事件上。
+
+##### 使用说明
+
+1. 通过调用类MultimodalEventHandle的registerStandardizedEventHandle方法对相应的标准化事件进行注册;
+
+2. 实现相应的标准化事件的接口,执行相应的逻辑功能;
+
+3. 事件处理完成之后,需要利用unregisterStandardizedEventHandle取消注册。
+
+
+本示例当相应的触发事件发生时,系统会弹框提示,表示事件处理完成。
+
+##### 约束与限制
+
+多模输入标准化事件适用设备情况请[点击链接](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-multimodal-standard-event-overview-0000001079953054)查看。
+
+除了通用标准化事件(CommonEventHandle),媒体类标准化事件(MediaEventHandle),系统类标准化事件(SystemEventHandle),通话类标准化事件(TelephoneEventHandle)外,为了提供完整的事件处理能力,多模输入提供按键和触屏事件的回调接口类KeyEventHandle和TouchEventHandle;
+
+1. 在收到按键、触屏等原始输入事件时,会优先判断是否需要映射为通用标准化事件(CommonEventHandle),媒体类标准化事件(MediaEventHandle),系统类标准化事件(SystemEventHandle),通话类标准化事件(TelephoneEventHandle)。如果注册了以上四种标准化事件中的一种,且原始输入事件满足该标准事件中某一场景,就会执行该标准化事件提供的回调。
+
+2. 如果不需要映射为上述四种标准化事件,则会继续判断是否需要映射为按键标准化事件(KeyEventHandle)和触摸标准化事件(TouchEventHandle)。只要注册了这两种标准化事件,分别执行这两种标准化事件中对应的回调。
+
+3. 如果没有注册标准化事件,或者传统输入事件没有对应的标准化事件,则会由Ability继续分发给传统输入事件。
+
+
diff --git a/UI/MultimodalEvent/build.gradle b/UI/MultimodalEvent/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..1ce01d8202dede3a761267d58bd910197a647d83
--- /dev/null
+++ b/UI/MultimodalEvent/build.gradle
@@ -0,0 +1,36 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+
+allprojects {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
diff --git a/UI/MultimodalEvent/entry/build.gradle b/UI/MultimodalEvent/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..b6bee94b6625b4ec8f34cbeb5d33ec5033d45315
--- /dev/null
+++ b/UI/MultimodalEvent/entry/build.gradle
@@ -0,0 +1,21 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+}
+
diff --git a/UI/MultimodalEvent/entry/src/main/config.json b/UI/MultimodalEvent/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..5023dc838abe0db3ba8fa92f069b7963ef926234
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/config.json
@@ -0,0 +1,43 @@
+{
+ "app": {
+ "bundleName": "ohos.samples.multimodalevent",
+ "version": {
+ "code": 1000000,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "ohos.samples.multimodalevent",
+ "name": ".MyApplication",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "ohos.samples.multimodalevent.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MainAbility.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..22efe120d854a463bb1725b749a855bff9561fe8
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MainAbility.java
@@ -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.
+ */
+
+package ohos.samples.multimodalevent;
+
+import ohos.samples.multimodalevent.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * MainAbility
+ *
+ * @since 2021-05-24
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MyApplication.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..d31a6d018105a9e215d7015b1e8ededeee8e487e
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/MyApplication.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @since 2021-05-24
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/CommonEventAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/CommonEventAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..8801d7b0bfb86002912bc5f0b3afaeedfe9c9ff9
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/CommonEventAbilitySlice.java
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.event.MultimodalEvent;
+import ohos.multimodalinput.standard.CommonEventHandle;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * CommonEventAbilitySlice
+ *
+ * @since 2021-05-25
+ */
+public class CommonEventAbilitySlice extends AbilitySlice {
+ private static final String TAG = MediaEventAbilitySlice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private String message = "This is CommonEvent";
+
+ private Utils utils = Utils.getInstance();
+
+ private CommonEventHandle commonEventHandle = new CommonEventHandle() {
+ @Override
+ public boolean onShowMenu(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onSend(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onCopy(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onCopy");
+ if (multimodalEvent != null) {
+ showCommonEvent();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPaste(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onPaste");
+ if (multimodalEvent != null) {
+ showCommonEvent();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onCut(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onUndo(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onRefresh(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onStartDrag(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onCancel(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onEnter(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onPrevious(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onNext(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onBack(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onPrint(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+ };
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_common_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), commonEventHandle);
+ }
+
+ private void showCommonEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), commonEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/KeyEventAbilitySclice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/KeyEventAbilitySclice.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5b32471823290cb11149b58d8307627bc23ae06
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/KeyEventAbilitySclice.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.standard.KeyEventHandle;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * KeyEventAbilitySclice
+ *
+ * @since 2021-05-24
+ */
+public class KeyEventAbilitySclice extends AbilitySlice {
+ private static final String TAG = KeyEventAbilitySclice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private String message = "This is keyEvent";
+
+ private Utils utils = Utils.getInstance();
+
+ private KeyEventHandle keyEventHandle = keyEvent -> {
+ HiLog.info(LABEL_LOG, "keyEvent");
+ if (keyEvent != null && keyEvent.isKeyDown()) {
+ showKeyEvent();
+ }
+ return false;
+ };
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_key_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), keyEventHandle);
+ }
+
+ private void showKeyEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), keyEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MainAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..aabf4cf9f0625b8bdd0044514fbfcfc716a6bef8
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MainAbilitySlice.java
@@ -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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import ohos.agp.components.Component;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+
+/**
+ * MainAbilitySlice
+ *
+ * @since 2021-05-24
+ */
+public class MainAbilitySlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_main_ability_slice);
+ initComponents();
+ }
+
+ private void initComponents() {
+ Component componentTouch = findComponentById(ResourceTable.Id_touch_event);
+ componentTouch.setClickedListener(listener -> present(new TouchEventAbilitySlice(), new Intent()));
+ Component componentKey = findComponentById(ResourceTable.Id_key_event);
+ componentKey.setClickedListener(listener -> present(new KeyEventAbilitySclice(), new Intent()));
+ Component componentMedia = findComponentById(ResourceTable.Id_media_event);
+ componentMedia.setClickedListener(listener -> present(new MediaEventAbilitySlice(), new Intent()));
+ Component componentSystem = findComponentById(ResourceTable.Id_system_event);
+ componentSystem.setClickedListener(listener -> present(new SystemEventAbilitySlice(), new Intent()));
+ Component componentCommon = findComponentById(ResourceTable.Id_common_event);
+ componentCommon.setClickedListener(listener -> present(new CommonEventAbilitySlice(), new Intent()));
+ Component componentTel = findComponentById(ResourceTable.Id_telephone_event);
+ componentTel.setClickedListener(listener -> present(new TelephoneEventAbilitySlice(), new Intent()));
+ }
+
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MediaEventAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MediaEventAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ac60e54fcfef81f6359f4eca2ed921e9c60aa05
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/MediaEventAbilitySlice.java
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.event.MultimodalEvent;
+import ohos.multimodalinput.standard.MediaEventHandle;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * MediaEventAbilitySlice
+ *
+ * @since 2021-05-24
+ */
+public class MediaEventAbilitySlice extends AbilitySlice {
+ private static final String TAG = MediaEventAbilitySlice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private String message = "This is mediaEvent";
+
+ private Utils utils = Utils.getInstance();
+
+ private MediaEventHandle mediaEventHandle = new MediaEventHandle() {
+ @Override
+ public boolean onPlay(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onPlay");
+ return false;
+ }
+
+ @Override
+ public boolean onPause(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onPause");
+ return false;
+ }
+
+ @Override
+ public boolean onMediaControl(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onMediaControl");
+ if (multimodalEvent != null) {
+ showMediaEvent();
+ }
+ return false;
+ }
+ };
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_media_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), mediaEventHandle);
+ }
+
+ private void showMediaEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), mediaEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/SystemEventAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/SystemEventAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..b54bf6707cc8dc8ae051ea766ffe5c316e749df5
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/SystemEventAbilitySlice.java
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.event.MultimodalEvent;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.multimodalinput.standard.SystemEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * SystemEventAbilitySlice
+ *
+ * @since 2021-05-25
+ */
+public class SystemEventAbilitySlice extends AbilitySlice {
+ private static final String TAG = KeyEventAbilitySclice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private String message = "Page closed";
+
+ private Utils utils = Utils.getInstance();
+
+ private SystemEventHandle systemEventHandle = new SystemEventHandle() {
+ @Override
+ public boolean onMute(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onClosePage(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onClosePage");
+ if (multimodalEvent != null) {
+ showSystemEvent();
+ }
+ return false;
+ }
+ };
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_system_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), systemEventHandle);
+ }
+
+ private void showSystemEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), systemEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TelephoneEventAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TelephoneEventAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..18b0c791cac1ac8e76da71ad6a2bfad6c0cec607
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TelephoneEventAbilitySlice.java
@@ -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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.event.MultimodalEvent;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.multimodalinput.standard.TelephoneEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * TelephoneEventAbilitySlice
+ *
+ * @since 2021-05-24
+ */
+public class TelephoneEventAbilitySlice extends AbilitySlice {
+ private static final String TAG = TelephoneEventAbilitySlice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private String message = "This is showTelephoneEvent";
+
+ private Utils utils = Utils.getInstance();
+
+ private TelephoneEventHandle telephoneEventHandle = new TelephoneEventHandle() {
+ @Override
+ public boolean onAnswer(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onRefuse(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onHangup(MultimodalEvent multimodalEvent) {
+ return false;
+ }
+
+ @Override
+ public boolean onTelephoneControl(MultimodalEvent multimodalEvent) {
+ HiLog.info(LABEL_LOG, "onTelephoneControl");
+ if (multimodalEvent != null) {
+ showTelphoneEvent();
+ }
+ return false;
+ }
+ };
+
+ private void showTelphoneEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_tel_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), telephoneEventHandle);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), telephoneEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TouchEventAbilitySlice.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TouchEventAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..475ab350c49519df3ab5bd709c7745eccce3e3bd
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/slice/TouchEventAbilitySlice.java
@@ -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.
+ */
+
+package ohos.samples.multimodalevent.slice;
+
+import java.lang.ref.WeakReference;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.app.Context;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.multimodalinput.standard.MultimodalEventHandle;
+import ohos.multimodalinput.standard.TouchEventHandle;
+import ohos.samples.multimodalevent.ResourceTable;
+import ohos.samples.multimodalevent.utils.Utils;
+
+/**
+ * TouchEventAbilitySlice
+ *
+ * @since 2021-05-24
+ */
+public class TouchEventAbilitySlice extends AbilitySlice {
+ private static final String TAG = MediaEventAbilitySlice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private static int count = 0;
+
+ private String message = "This is touchEvent";
+
+ private Utils utils = Utils.getInstance();
+
+ private TouchEventHandle touchEventHandle = touchEvent -> {
+ HiLog.info(LABEL_LOG, "ontouch touchevent2");
+ if (touchEvent != null) {
+ if (count > 0) {
+ return false;
+ }
+ count++;
+ showTouchEvent();
+ }
+ return false;
+ };
+
+ private void showTouchEvent() {
+ WeakReference referenceContext = new WeakReference<>(getContext());
+ utils.showDialogBox(message, referenceContext);
+ }
+
+ @Override
+ protected void onStart(Intent intent) {
+ super.onStart(intent);
+ setUIContent(ResourceTable.Layout_touch_event_ability_slice);
+ MultimodalEventHandle.registerStandardizedEventHandle(getAbility(), touchEventHandle);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ utils.distroyDialogBox();
+ MultimodalEventHandle.unregisterStandardizedEventHandle(getAbility(), touchEventHandle);
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/utils/Utils.java b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/utils/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d738574b38b497a227989b5020258ae75a91c25
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/java/ohos/samples/multimodalevent/utils/Utils.java
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.multimodalevent.utils;
+
+import java.lang.ref.WeakReference;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import ohos.agp.utils.TextAlignment;
+import ohos.agp.window.dialog.ListDialog;
+import ohos.app.Context;
+
+import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT;
+
+/**
+ * Utils
+ *
+ * @since 2021-06-08
+ */
+public class Utils {
+ private static final int DIALOG_BOX_WIDTH = 985;
+
+ private static Utils instance;
+
+ /**
+ * listDialog ListDialog
+ */
+ public static ListDialog listDialog;
+
+ private Utils (){
+ }
+
+ public static synchronized Utils getInstance() {
+ if (instance == null) {
+ instance = new Utils();
+ }
+ return instance;
+ }
+
+ /**
+ * showDialogBox
+ *
+ * @param message string
+ * @param weakReference WeakReference
+ */
+ public void showDialogBox(String message, WeakReference weakReference) {
+ String[] items = new String[] {
+ message, "Current Time:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
+ Locale.getDefault()).format(new Date().getTime())
+ };
+ listDialog = new ListDialog(weakReference.get());
+ listDialog.setAlignment(TextAlignment.CENTER);
+ listDialog.setSize(DIALOG_BOX_WIDTH, MATCH_CONTENT);
+ listDialog.setAutoClosable(true);
+ listDialog.setItems(items);
+ listDialog.show();
+ }
+
+ /**
+ * showDialogBox
+ */
+ public void distroyDialogBox() {
+ if (listDialog != null) {
+ listDialog.destroy();
+ }
+ }
+}
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/element/string.json b/UI/MultimodalEvent/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..faf30b1e0d46eea8ea019867ee8a3427e0b133e1
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MultimodalEvent"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "HelloWorld",
+ "value": "Hello World"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/graphic/background_button_element.xml b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/background_button_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1b15820a7662627164f303e0dd2fb0df35b16108
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/background_button_element.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/graphic/button_bg.xml b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/button_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c84d3de4f0888266cabda5c83cd697ad1e94f375
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/button_bg.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/graphic/common_bg.xml b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/common_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..42d1786cf6ba1181305c5defb0cca1f350b12a2d
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/common_bg.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/graphic/textfield_bg.xml b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/textfield_bg.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1ebac0334db4e9963b7c76dfe3c787b69b2f2f41
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/graphic/textfield_bg.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/common_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/common_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..293e7ff4803ac222e001d3a53c8c9e39230830c3
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/common_event_ability_slice.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/key_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/key_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..02cdd781ddb25f6630f660cce836095414adc59f
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/key_event_ability_slice.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/main_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/main_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..58e8466b68f59988956ab3c6b703360f0417b411
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/main_ability_slice.xml
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/media_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/media_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..983900e02b4b5857734c57de30e4b7a9e5ae5747
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/media_event_ability_slice.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/system_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/system_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3b1ffe81fe04a40d18f111d928250dd77a5b3013
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/system_event_ability_slice.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/tel_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/tel_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..401f70a45883fea58a8e4d20b4165c2850516513
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/tel_event_ability_slice.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/layout/touch_event_ability_slice.xml b/UI/MultimodalEvent/entry/src/main/resources/base/layout/touch_event_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2ed5b865042b3d0f1beb49cdc0a3fd959bebe49e
--- /dev/null
+++ b/UI/MultimodalEvent/entry/src/main/resources/base/layout/touch_event_ability_slice.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UI/MultimodalEvent/entry/src/main/resources/base/media/icon.png b/UI/MultimodalEvent/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/UI/MultimodalEvent/entry/src/main/resources/base/media/icon.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/key_event.png b/UI/MultimodalEvent/screenshots/device/key_event.png
new file mode 100644
index 0000000000000000000000000000000000000000..571a5e1ce1eb4f4754b9dd83022907f332fe7c47
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/key_event.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/media_event.png b/UI/MultimodalEvent/screenshots/device/media_event.png
new file mode 100644
index 0000000000000000000000000000000000000000..7da8e7ddfd23bfbbc9bea241881d5ce5b32d84a8
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/media_event.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/multi_mode_event.png b/UI/MultimodalEvent/screenshots/device/multi_mode_event.png
new file mode 100644
index 0000000000000000000000000000000000000000..38612068918f042aa3ca084f3c299593abf8a2f0
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/multi_mode_event.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/sys_event.png b/UI/MultimodalEvent/screenshots/device/sys_event.png
new file mode 100644
index 0000000000000000000000000000000000000000..c18f438e0af101b49fcc1b5d31b0e22133577523
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/sys_event.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/tel_event.png b/UI/MultimodalEvent/screenshots/device/tel_event.png
new file mode 100644
index 0000000000000000000000000000000000000000..451ceb06c55307bd2eb783b001f0bd031e827191
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/tel_event.png differ
diff --git a/UI/MultimodalEvent/screenshots/device/touch_event .png b/UI/MultimodalEvent/screenshots/device/touch_event .png
new file mode 100644
index 0000000000000000000000000000000000000000..fe18251cca3cc5189ab84f1e3d2d24e036d6b7e8
Binary files /dev/null and b/UI/MultimodalEvent/screenshots/device/touch_event .png differ
diff --git a/UI/MultimodalEvent/settings.gradle b/UI/MultimodalEvent/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7dc3285c045cc590e49d231a4280ef52ba646d91
--- /dev/null
+++ b/UI/MultimodalEvent/settings.gradle
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
+include ':entry'
diff --git a/ability/Delegator/README_en.md b/ability/Delegator/README_en.md
new file mode 100644
index 0000000000000000000000000000000000000000..c8cb87cd30466384c132377f42a49c19220ff38a
--- /dev/null
+++ b/ability/Delegator/README_en.md
@@ -0,0 +1,21 @@
+# AbilityDelegator
+
+
+
+### Introduction
+
+This sample shows how to use the AbilityDelegator to perform operations on the UI of an ability after the ability is developed. In addition, this sample enables test automation by handing over some click and observe operations to the AbilityDelegator.
+
+### Usage
+
+The procedure for using this sample is as follows:
+
+1. Open this project in DevEco Studio.
+2. Select an emulator \([instructions](https://developer.harmonyos.com/en/docs/documentation/doc-guides/run_simulator-0000001053303709)\) or connect to a real device \([instructions](https://developer.harmonyos.com/en/docs/documentation/doc-guides/run_phone_tablat-0000001064774652)\).
+3. Select the **MainAbilitySliceTest.java** file in the **ohosTest** directory and run the file.
+4. If the operation is successful, the message "test passed: 2" is displayed.
+
+### Constraints
+
+This sample can be run only on the standard system.
+
diff --git a/ability/Delegator/README_zh.md b/ability/Delegator/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..aa29ec11eb8f0284f247f8c18be42d6884845578
--- /dev/null
+++ b/ability/Delegator/README_zh.md
@@ -0,0 +1,21 @@
+# Ability测试
+
+
+
+### 简介
+
+本示例展示了开发者开发完Ability之后,如何通过AbilityDelegator工具,将对元能力界面的操作交给工具
+
+完成,从而实现测试自动化。
+
+### 使用说明
+
+本示例的使用步骤:
+
+1. 在DevEco Studio配置并选择模拟器([配置链接](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_simulator-0000001053303709))或真机设备([配置链接](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/run_phone_tablat-0000001064774652))。
+2. 在DevEco Studio中选择ohosTest目录下的MainAbilitySliceTest.java文件,运行当前文件。
+3. 在run窗口会出现test passed:2。
+
+### 约束与限制
+
+本示例仅支持在标准系统上运行。
\ No newline at end of file
diff --git a/ability/Delegator/build.gradle b/ability/Delegator/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..6b71753b3e5eb0626395119563c32a5afc991f1a
--- /dev/null
+++ b/ability/Delegator/build.gradle
@@ -0,0 +1,35 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+buildscript {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ classpath 'com.huawei.ohos:decctest:1.0.0.6'
+ }
+}
+allprojects {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
\ No newline at end of file
diff --git a/ability/Delegator/entry/build.gradle b/ability/Delegator/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..5a74e821e7de76169b064aa3b6d6fea5ea43bf8e
--- /dev/null
+++ b/ability/Delegator/entry/build.gradle
@@ -0,0 +1,27 @@
+apply plugin: 'com.huawei.ohos.hap'
+apply plugin: 'com.huawei.ohos.decctest'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+
+}
+
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+ testImplementation 'junit:junit:4.13'
+ ohosTestImplementation 'decc.testkit:harmonyjunitrunner:0.3'
+}
+decc {
+ supportType = ['html', 'xml']
+}
diff --git a/ability/Delegator/entry/src/main/config.json b/ability/Delegator/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..49c815154a176f2e70665935c07ce6e1ce901f75
--- /dev/null
+++ b/ability/Delegator/entry/src/main/config.json
@@ -0,0 +1,61 @@
+{
+ "app": {
+ "bundleName": "ohos.samples.delegator",
+ "version": {
+ "code": 1000000,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "ohos.samples.delegator",
+ "name": ".MyApplication",
+ "deviceType": [
+ "default"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "name": "ohos.samples.delegator.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "ohos.samples.delegator.FirstAbility",
+ "icon": "$media:icon",
+ "description": "$string:firstability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "orientation": "unspecified",
+ "name": "ohos.samples.delegator.SecondAbility",
+ "icon": "$media:icon",
+ "description": "$string:secondability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/FirstAbility.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/FirstAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..594ad94f77eb7afd11b1e2705586d938cf2d37ba
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/FirstAbility.java
@@ -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.
+ */
+
+package ohos.samples.delegator;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.samples.delegator.slice.FirstAbilitySlice;
+
+/**
+ * FirstAbility
+ *
+ * @since 2021-05-19
+ */
+public class FirstAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(FirstAbilitySlice.class.getName());
+ }
+
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MainAbility.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..144a11fc17437728d63fb430dcd60c370066cbc3
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MainAbility.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator;
+
+import ohos.samples.delegator.slice.MainAbilitySlice;
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+
+/**
+ * MainAbility
+ *
+ * @since 2021-05-19
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MyApplication.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..4350c68caba167bcb0bc492530dcd28fef105f44
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/MyApplication.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @since 2021-05-19
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/SecondAbility.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/SecondAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..32aed30066f5d5db9a30e2cc6ac4dce5e17cff7d
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/SecondAbility.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.samples.delegator.slice.SecondAbilitySlice;
+
+/**
+ * SecondAbility
+ *
+ * @since 2021-05-19
+ */
+public class SecondAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(SecondAbilitySlice.class.getName());
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/FirstAbilitySlice.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/FirstAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..42c1362f27551a12337419beccfcdb0201cfddad
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/FirstAbilitySlice.java
@@ -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.
+ */
+
+package ohos.samples.delegator.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.samples.delegator.ResourceTable;
+
+/**
+ * FirstAbilitySlice
+ *
+ * @since 2021-05-19
+ */
+public class FirstAbilitySlice extends AbilitySlice {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_first);
+ Component setResult = findComponentById(ResourceTable.Id_button_first_to_main);
+ Component receivedTextComponent = findComponentById(ResourceTable.Id_text_main_to_first);
+ if (receivedTextComponent instanceof Text) {
+ Text receivedText = (Text) receivedTextComponent;
+ if (intent != null) {
+ String content = intent.getStringParam("First");
+ receivedText.setText(content);
+ }
+ }
+ setResult.setClickedListener(component -> {
+ terminateAbility();
+ });
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/MainAbilitySlice.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4bff2cb5f897464dc3c3a6b58d46f84aefdc779
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/MainAbilitySlice.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextField;
+import ohos.bundle.ElementName;
+import ohos.samples.delegator.ResourceTable;
+
+import static ohos.samples.delegator.utils.Const.REQUEST_CODE;
+import static ohos.samples.delegator.utils.Const.RESULT_OK;
+
+/**
+ * MainAbilitySlice
+ *
+ * @since 2021-05-19
+ */
+public class MainAbilitySlice extends AbilitySlice {
+ private static final String BUNDLE_NAME = "ohos.samples.delegator";
+ private Button startAbility;
+ private Button startAbilityForResult;
+ private Text displayText;
+ private TextField editText;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_main);
+ initView();
+ initEventListener();
+ }
+
+ private void initView() {
+ Component startAbilityComment = findComponentById(ResourceTable.Id_button_startAbility);
+ if (startAbilityComment instanceof Button) {
+ startAbility = (Button) startAbilityComment;
+ }
+ Component startAbilityForResultComponent = findComponentById(ResourceTable.Id_button_startAbilityForResult);
+ if (startAbilityForResultComponent instanceof Button) {
+ startAbilityForResult = (Button) startAbilityForResultComponent;
+ }
+ Component displayTextComponent = findComponentById(ResourceTable.Id_text_displayText);
+ if (displayTextComponent instanceof Text) {
+ displayText = (Text) displayTextComponent;
+ }
+ Component editTextComment = findComponentById(ResourceTable.Id_text_editMain);
+ if (editTextComment instanceof TextField) {
+ editText = (TextField) editTextComment;
+ }
+ }
+
+ private void initEventListener() {
+ startAbility.setClickedListener(component -> {
+ ElementName elementNameFirst = new ElementName();
+ elementNameFirst.setBundleName(BUNDLE_NAME);
+ elementNameFirst.setAbilityName("FirstAbility");
+ Intent intentFirstAbility = new Intent();
+ intentFirstAbility.setElement(elementNameFirst);
+ intentFirstAbility.setParam("First", editText.getText());
+ startAbility(intentFirstAbility);
+
+ });
+ startAbilityForResult.setClickedListener(component -> {
+ ElementName elementNameSecond = new ElementName();
+ elementNameSecond.setBundleName(BUNDLE_NAME);
+ elementNameSecond.setAbilityName("SecondAbility");
+ Intent intentSecondAbility = new Intent();
+ intentSecondAbility.setElement(elementNameSecond);
+ intentSecondAbility.setParam("Second", editText.getText());
+ startAbilityForResult(intentSecondAbility, REQUEST_CODE);
+ });
+ }
+
+ @Override
+ protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
+ if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
+ if (resultData != null) {
+ String response = resultData.getStringParam("Main");
+ displayText.setText(response);
+ }
+ }
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/SecondAbilitySlice.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/SecondAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..a51ad8977454e17ae7ee85c03a950202dac4c06e
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/slice/SecondAbilitySlice.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator.slice;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextField;
+import ohos.samples.delegator.ResourceTable;
+
+import static ohos.samples.delegator.utils.Const.RESULT_OK;
+
+/**
+ * SecondAbilitySlice
+ *
+ * @since 2021-05-19
+ */
+public class SecondAbilitySlice extends AbilitySlice {
+ private TextField resposeText;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_ability_second);
+ Component setResult = findComponentById(ResourceTable.Id_button_second_to_main);
+ Component receivedTextComponent = findComponentById(ResourceTable.Id_text_main_to_second);
+ if ( receivedTextComponent instanceof Text) {
+ Text receivedText = (Text) receivedTextComponent;
+ if (intent != null) {
+ String content = intent.getStringParam("Second");
+ receivedText.setText(content);
+ }
+ }
+ Component resposeTextComment = findComponentById(ResourceTable.Id_text_editSecond);
+ if (resposeTextComment instanceof TextField) {
+ resposeText = (TextField) resposeTextComment;
+ }
+ setResult.setClickedListener(component -> {
+ Intent response = new Intent();
+ String res = resposeText.getText();
+ response.setParam("Main", res);
+ getAbility().setResult(RESULT_OK, response);
+ terminateAbility();
+ });
+ }
+}
diff --git a/ability/Delegator/entry/src/main/java/ohos/samples/delegator/utils/Const.java b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/utils/Const.java
new file mode 100644
index 0000000000000000000000000000000000000000..95fc5daff0c1ddb9b7e970ce529ea8729f8686ab
--- /dev/null
+++ b/ability/Delegator/entry/src/main/java/ohos/samples/delegator/utils/Const.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator.utils;
+
+/**
+ * Const
+ *
+ * @since 2021-05-17
+ */
+public class Const {
+ /**
+ * Intent Request Code
+ */
+ public static final int REQUEST_CODE = 0;
+
+ /**
+ * Intent Result Code
+ */
+ public static final int RESULT_OK = 1;
+}
diff --git a/ability/Delegator/entry/src/main/resources/base/element/float.json b/ability/Delegator/entry/src/main/resources/base/element/float.json
new file mode 100644
index 0000000000000000000000000000000000000000..15faa133fc46e30b074f0fa7e03e9ebd91f7a55c
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/element/float.json
@@ -0,0 +1,20 @@
+{
+ "float": [
+ {
+ "name": "top_margin",
+ "value": "20vp"
+ },
+ {
+ "name": "text_size",
+ "value": "20fp"
+ },
+ {
+ "name": "right_padding",
+ "value": "15vp"
+ },
+ {
+ "name": "left_padding",
+ "value": "15vp"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/element/string.json b/ability/Delegator/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..4750e8d777f07482b0590baa1a14a9b6da7d6caf
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,44 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "Delegator"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "firstability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "secondability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "hint_message",
+ "value": "Input Your Message"
+ },
+ {
+ "name": "start_ability",
+ "value": "startAbility"
+ },
+ {
+ "name": "start_ability_for_result",
+ "value": "startAbilityForResult"
+ },
+ {
+ "name": "set_result",
+ "value": "setResult"
+ },
+ {
+ "name": "first_text",
+ "value": "This is FirstAbilitySlice"
+ },
+ {
+ "name": "second_text",
+ "value": "This is SecondAbilitySlice"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_first.xml b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_first.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be1ba89ff3bad27ff85d87e66940e89a64a8192a
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_first.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_main.xml b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1018ca3426c32c9d7ba832131e1ae9bd4f7ac2c6
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_second.xml b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..be1ba89ff3bad27ff85d87e66940e89a64a8192a
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/graphic/background_ability_second.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/graphic/capsule_button_element.xml b/ability/Delegator/entry/src/main/resources/base/graphic/capsule_button_element.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6ab9d774ce6788352dbc6cf640822f5561bb663f
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/graphic/capsule_button_element.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/layout/ability_first.xml b/ability/Delegator/entry/src/main/resources/base/layout/ability_first.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d449fbb307b729ba8d53548208040e64ef9b6402
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/layout/ability_first.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/layout/ability_main.xml b/ability/Delegator/entry/src/main/resources/base/layout/ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d232c4b176860f240d9b7773b8863a5324c3d592
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/layout/ability_main.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/layout/ability_second.xml b/ability/Delegator/entry/src/main/resources/base/layout/ability_second.xml
new file mode 100644
index 0000000000000000000000000000000000000000..59cfe6de56250c49dbb7a4c9da2d83a222d721f7
--- /dev/null
+++ b/ability/Delegator/entry/src/main/resources/base/layout/ability_second.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/main/resources/base/media/icon.png b/ability/Delegator/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/ability/Delegator/entry/src/main/resources/base/media/icon.png differ
diff --git a/ability/Delegator/entry/src/ohosTest/config.json b/ability/Delegator/entry/src/ohosTest/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..962df08b5fe52fb4a918cc2268819c7e1789eb86
--- /dev/null
+++ b/ability/Delegator/entry/src/ohosTest/config.json
@@ -0,0 +1,34 @@
+{
+ "app": {
+ "bundleName": "ohos.samples.delegator",
+ "version": {
+ "code": 1000000,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "ohos.samples.delegator",
+ "name": "testModule",
+ "deviceType": [
+ "default"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry_test",
+ "moduleType": "feature"
+ },
+ "abilities": [
+ {
+ "name": "decc.testkit.runner.EntryAbility",
+ "description": "Test Entry Ability",
+ "icon": "$media:icon",
+ "label": "$string:app_name",
+ "launchType": "standard",
+ "orientation": "landscape",
+ "visible": true,
+ "type": "page"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ability/Delegator/entry/src/ohosTest/java/ohos/samples/delegator/slice/MainAbilitySliceTest.java b/ability/Delegator/entry/src/ohosTest/java/ohos/samples/delegator/slice/MainAbilitySliceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1c9a8ba3a0bbefa1fd64b7aa828efd7f67051a3
--- /dev/null
+++ b/ability/Delegator/entry/src/ohosTest/java/ohos/samples/delegator/slice/MainAbilitySliceTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.delegator.slice;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
+import ohos.aafwk.ability.delegation.IAbilityDelegator;
+import ohos.aafwk.content.Intent;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.agp.components.Text;
+import ohos.agp.components.TextField;
+import ohos.bundle.ElementName;
+import ohos.samples.delegator.FirstAbility;
+import ohos.samples.delegator.MainAbility;
+import ohos.samples.delegator.ResourceTable;
+import ohos.samples.delegator.SecondAbility;
+
+/**
+ * MainAbilitySliceTest
+ *
+ * @since 2021-05-17
+ */
+public class MainAbilitySliceTest {
+ private static final String BUNDLE_NAME = "ohos.samples.delegator";
+
+ private static final String SEND_MESSAGE_MAIN = "I am from MainAbility.";
+
+ private static final String SEND_MESSAGE_SECOND = "I am from SecondAbility.";
+
+ private static IAbilityDelegator abilityDelegator;
+
+ private static Intent intentMainAbility = new Intent();
+
+ /**
+ * Global Variable Initialization
+ */
+ @BeforeClass
+ public static void setUp() {
+ abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
+ ElementName elementNameMain = new ElementName();
+ elementNameMain.setBundleName(BUNDLE_NAME);
+ elementNameMain.setAbilityName("MainAbility");
+ intentMainAbility.setElement(elementNameMain);
+ }
+
+ /**
+ * Initialization State
+ */
+ @Before
+ public void jumpBack() {
+ abilityDelegator.startAbilitySync(intentMainAbility);
+ }
+
+ /**
+ * MainAbility StartAbility Test
+ */
+ @Test
+ public void startAbility() {
+ Ability mainAbility = abilityDelegator.getCurrentTopAbility();
+ String mainAbilityName = mainAbility.getAbilityName();
+ Assert.assertEquals(MainAbility.class.getSimpleName(), mainAbilityName);
+ Component editMainTextComponent = mainAbility.findComponentById(ResourceTable.Id_text_editMain);
+ if ( editMainTextComponent instanceof TextField) {
+ TextField editMainText = (TextField) editMainTextComponent;
+ Assert.assertNotNull("editMainText Text is null", editMainText);
+ abilityDelegator.runOnUIThreadSync(() -> {
+ editMainText.setText(SEND_MESSAGE_MAIN);
+ });
+ }
+ Component startAbilityComment = mainAbility.findComponentById(ResourceTable.Id_button_startAbility);
+ if (startAbilityComment instanceof Button) {
+ Button startAbility = (Button) startAbilityComment;
+ Assert.assertNotNull("startAbility button is null", startAbility);
+ boolean okStartAbility = abilityDelegator.triggerClickEvent(mainAbility, startAbility);
+ Assert.assertTrue("startAbility FirstAbility failed", okStartAbility);
+ }
+ // Wait Until The FirstAbility Startup Is Complete
+ synchronized (abilityDelegator) {
+ try {
+ abilityDelegator.wait(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ toFirstAbility();
+ }
+
+ private void toFirstAbility() {
+ Ability firstAbility = abilityDelegator.getCurrentTopAbility();
+ String firstAbilityName = firstAbility.getAbilityName();
+ Assert.assertEquals(FirstAbility.class.getSimpleName(), firstAbilityName);
+ Component firstTextComponent = firstAbility.findComponentById(ResourceTable.Id_text_main_to_first);
+ if (firstTextComponent instanceof Text) {
+ Text firstText = (Text) firstTextComponent;
+ Assert.assertNotNull("toFirstText Text is null", firstText);
+ Assert.assertEquals(SEND_MESSAGE_MAIN, firstText.getText());
+ }
+ Component setResultComponent = firstAbility.findComponentById(ResourceTable.Id_button_first_to_main);
+ if (setResultComponent instanceof Button) {
+ Button setResult = (Button) setResultComponent;
+ Assert.assertNotNull("setResult button is null", setResult);
+ boolean okReturnAbility = abilityDelegator.triggerClickEvent(firstAbility, setResult);
+ Assert.assertTrue("returnAbility MainAbility failed", okReturnAbility);
+ }
+ // Waiting For FirstAbility To Return Completion
+ synchronized (abilityDelegator) {
+ try {
+ abilityDelegator.wait(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ Ability mainAbility = abilityDelegator.getCurrentTopAbility();
+ String mainAbilityName = mainAbility.getAbilityName();
+ Assert.assertEquals(MainAbility.class.getSimpleName(), mainAbilityName);
+ }
+
+ /**
+ * MainAbility StartAbilityForResult Test
+ */
+ @Test
+ public void startAbilityForResult() {
+ Ability mainAbility = abilityDelegator.getCurrentTopAbility();
+ String mainAbilityName = mainAbility.getAbilityName();
+ Assert.assertEquals(MainAbility.class.getSimpleName(), mainAbilityName);
+ Component editMainTextComponent = mainAbility.findComponentById(ResourceTable.Id_text_editMain);
+ if ( editMainTextComponent instanceof TextField) {
+ TextField editMainText = (TextField) editMainTextComponent;
+ Assert.assertNotNull("editMainText Text is null", editMainText);
+ abilityDelegator.runOnUIThreadSync(() -> {
+ editMainText.setText(SEND_MESSAGE_MAIN);
+ });
+ }
+ Component startAbilityForResultComment =
+ mainAbility.findComponentById(ResourceTable.Id_button_startAbilityForResult);
+ if (startAbilityForResultComment instanceof Button) {
+ Button startAbilityForResult = (Button) startAbilityForResultComment;
+ Assert.assertNotNull("startAbilityForResult button is null", startAbilityForResult);
+ boolean okStartAbilityForResult = abilityDelegator.triggerClickEvent(mainAbility, startAbilityForResult);
+ Assert.assertTrue("startAbilityForResult SecondAbility failed", okStartAbilityForResult);
+ }
+ // Wait Until The SecondAbility Startup Is Complete
+ synchronized (abilityDelegator) {
+ try {
+ abilityDelegator.wait(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ toSecondAbility();
+ }
+
+ private void toSecondAbility() {
+ Ability secondAbility = abilityDelegator.getCurrentTopAbility();
+ String secondAbilityName = secondAbility.getAbilityName();
+ Assert.assertEquals(SecondAbility.class.getSimpleName(), secondAbilityName);
+ Component secondTextComponent = secondAbility.findComponentById(ResourceTable.Id_text_main_to_second);
+ if (secondTextComponent instanceof Text) {
+ Text secondText = (Text) secondTextComponent;
+ Assert.assertNotNull("toSecondText Text is null", secondText);
+ Assert.assertEquals(SEND_MESSAGE_MAIN, secondText.getText());
+ }
+ Component editSecondTextComponent = secondAbility.findComponentById(ResourceTable.Id_text_editSecond);
+ if (editSecondTextComponent instanceof TextField) {
+ TextField editSecondText = (TextField) editSecondTextComponent;
+ Assert.assertNotNull("editSecondText Text is null", editSecondText);
+ abilityDelegator.runOnUIThreadSync(() -> {
+ editSecondText.setText(SEND_MESSAGE_SECOND);
+ });
+ }
+ Component setResultComponent = secondAbility.findComponentById(ResourceTable.Id_button_second_to_main);
+ if (setResultComponent instanceof Button) {
+ Button setResult = (Button) setResultComponent;
+ Assert.assertNotNull("setResult button is null", setResult);
+ boolean okReturnAbility = abilityDelegator.triggerClickEvent(secondAbility, setResult);
+ Assert.assertTrue("returnAbility MainAbility failed", okReturnAbility);
+ }
+ // Waiting For SecondAbility To Return Completion
+ synchronized (abilityDelegator) {
+ try {
+ abilityDelegator.wait(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ Ability mainAbility = abilityDelegator.getCurrentTopAbility();
+ String mainAbilityName = mainAbility.getAbilityName();
+ Assert.assertEquals(MainAbility.class.getSimpleName(), mainAbilityName);
+ Component mainTextComponent = mainAbility.findComponentById(ResourceTable.Id_text_displayText);
+ if (mainTextComponent instanceof Text) {
+ Text mainText = (Text) mainTextComponent;
+ Assert.assertNotNull("mainText Text is null", mainText);
+ Assert.assertEquals(SEND_MESSAGE_SECOND, mainText.getText());
+ }
+ }
+}
\ No newline at end of file
diff --git a/ability/Delegator/screenshots/device/MainAbility.png b/ability/Delegator/screenshots/device/MainAbility.png
new file mode 100644
index 0000000000000000000000000000000000000000..382233e7a087a5dd1f4f459013d5e49ddc0e3249
Binary files /dev/null and b/ability/Delegator/screenshots/device/MainAbility.png differ
diff --git a/ability/Delegator/settings.gradle b/ability/Delegator/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7dc3285c045cc590e49d231a4280ef52ba646d91
--- /dev/null
+++ b/ability/Delegator/settings.gradle
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
+include ':entry'
diff --git a/ability/ForegroundService/README_en.md b/ability/ForegroundService/README_en.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ad21064bf478d8b25f3314a9e6aab54f5f90add
--- /dev/null
+++ b/ability/ForegroundService/README_en.md
@@ -0,0 +1,24 @@
+# Foreground Service
+
+
+
+### Introduction
+
+This sample describes how to use a foreground Service ability for a music player.
+
+In certain scenarios, a foreground Service ability is required, for example, when the user expects to keep a music player app running. When a foreground Service ability is running for an app, the status bar shows an icon indicating that the app is running.
+
+### Usage Guidelines
+
+In this sample, there are three buttons on the home screen:
+
+**Start Play**: starts the foreground Service ability and plays music.
+
+**Pause Play**: pauses music playback, while the foreground Service ability continues to run.
+
+**Stop Play**: stops music playback and closes the foreground Service ability.
+
+### Constraints
+
+This sample can be run only on the standard system.
+
diff --git a/ability/ForegroundService/README_zh.md b/ability/ForegroundService/README_zh.md
new file mode 100644
index 0000000000000000000000000000000000000000..45550d6f82d485f0c1e452b6cdfd2f8d10258085
--- /dev/null
+++ b/ability/ForegroundService/README_zh.md
@@ -0,0 +1,23 @@
+# 前台服务
+
+
+
+### 简介
+
+本示例通过音乐播放器,展示了前台Service的使用方法。
+
+一般情况下Service都是在后台运行的,后台Service优先级都是比较低的,当资源不足时,系统有可能回收
+
+正在运行的后台Service。一些场景下(如:播放音乐),用户希望应用一直运行,此时就需要用到前台
+
+Service。前台Service会使用保持正在运行的图标在系统状态栏显示。
+
+### 使用说明
+
+本示例主界面分为三个按钮,点击Start Play按钮会启动前台服务并播放音乐,点击Pause Play按钮会暂停
+
+播放音乐,前台服务继续运行,点击Stop Play按钮会停止播放音乐并关闭前台服务。
+
+### 约束与限制
+
+本示例仅支持在标准系统上运行。
\ No newline at end of file
diff --git a/ability/ForegroundService/build.gradle b/ability/ForegroundService/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..9985d7a1fb40679434cae5e9787ab1565b0c9699
--- /dev/null
+++ b/ability/ForegroundService/build.gradle
@@ -0,0 +1,35 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+apply plugin: 'com.huawei.ohos.app'
+
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+}
+
+buildscript {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.huawei.ohos:hap:2.4.4.2'
+ }
+}
+allprojects {
+ repositories {
+ maven {
+ url 'https://repo.huaweicloud.com/repository/maven/'
+ }
+ maven {
+ url 'https://developer.huawei.com/repo/'
+ }
+ jcenter()
+ }
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/build.gradle b/ability/ForegroundService/entry/build.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..83f59debbd68242b503a22270f4378d7843ca204
--- /dev/null
+++ b/ability/ForegroundService/entry/build.gradle
@@ -0,0 +1,19 @@
+apply plugin: 'com.huawei.ohos.hap'
+ohos {
+ compileSdkVersion 5
+ defaultConfig {
+ compatibleSdkVersion 4
+ }
+ buildTypes {
+ release {
+ proguardOpt {
+ proguardEnabled false
+ rulesFiles 'proguard-rules.pro'
+ }
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/config.json b/ability/ForegroundService/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..72b0352d21dd462204fb2b7f3683e280a82aae7c
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/config.json
@@ -0,0 +1,66 @@
+{
+ "app": {
+ "bundleName": "ohos.samples.foregroundservice",
+ "version": {
+ "code": 1000000,
+ "name": "1.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "ohos.samples.foregroundservice",
+ "name": ".MyApplication",
+ "deviceType": [
+ "default"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry",
+ "moduleType": "entry"
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "portrait",
+ "name": "ohos.samples.foregroundservice.MainAbility",
+ "icon": "$media:icon",
+ "description": "$string:mainability_description",
+ "label": "$string:app_name",
+ "type": "page",
+ "launchType": "standard"
+ },
+ {
+ "name": "ohos.samples.foregroundservice.ServiceAbility",
+ "icon": "$media:icon",
+ "description": "$string:serviceability_description",
+ "type": "service",
+ "visible": true,
+ "backgroundModes": [
+ "dataTransfer",
+ "location"
+ ]
+ }
+ ],
+ "reqPermissions": [
+ {
+ "name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
+ "reason": "get right",
+ "usedScene": {
+ "ability": [
+ ".ServiceAbility"
+ ],
+ "when": "inuse"
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MainAbility.java b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MainAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..eefe2d007fbae073ae8072c997c1ab0a81c5ee52
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MainAbility.java
@@ -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.
+ */
+
+package ohos.samples.foregroundservice;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.content.Intent;
+import ohos.samples.foregroundservice.slice.MainAbilitySlice;
+
+/**
+ * MainAbility
+ *
+ * @since 2021-05-08
+ */
+public class MainAbility extends Ability {
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setMainRoute(MainAbilitySlice.class.getName());
+ }
+
+}
diff --git a/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MyApplication.java b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MyApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..0408c8010bb334856d5332f11ace3ea3c638ecd5
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/MyApplication.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.foregroundservice;
+
+import ohos.aafwk.ability.AbilityPackage;
+
+/**
+ * MyApplication
+ *
+ * @since 2021-05-08
+ */
+public class MyApplication extends AbilityPackage {
+ @Override
+ public void onInitialize() {
+ super.onInitialize();
+ }
+}
diff --git a/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/ServiceAbility.java b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/ServiceAbility.java
new file mode 100644
index 0000000000000000000000000000000000000000..993a09319e7759cf0aba2de1952db499157fd8f0
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/ServiceAbility.java
@@ -0,0 +1,244 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.foregroundservice;
+
+import static ohos.samples.foregroundservice.slice.MainAbilitySlice.EVENT_ACTION;
+
+import ohos.aafwk.ability.Ability;
+import ohos.aafwk.ability.LocalRemoteObject;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.utils.Color;
+import ohos.event.commonevent.CommonEventData;
+import ohos.event.commonevent.CommonEventManager;
+import ohos.event.notification.NotificationHelper;
+import ohos.event.notification.NotificationRequest;
+import ohos.event.notification.NotificationSlot;
+import ohos.global.resource.RawFileDescriptor;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.media.common.Source;
+import ohos.media.player.Player;
+import ohos.rpc.IRemoteObject;
+import ohos.rpc.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * Music Play Service
+ *
+ * @since 2021-05-08
+ */
+public class ServiceAbility extends Ability {
+ /**
+ * Music PlayState
+ */
+ public static final int PLAY_STATE = 0;
+
+ /**
+ * Music PauseState
+ */
+ public static final int PAUSE_STATE = 1;
+
+ /**
+ * Music StopState
+ */
+ public static final int STOP_STATE = 2;
+
+ private static final String TAG = ServiceAbility.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private int state = STOP_STATE;
+
+ private Player player;
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ }
+
+ @Override
+ public void onCommand(Intent intent, boolean isRestart, int startId) {
+ super.onCommand(intent, isRestart, startId);
+ sendEvent();
+ }
+
+ @Override
+ public IRemoteObject onConnect(Intent intent) {
+ return new MusicRemoteObject(this);
+ }
+
+ @Override
+ public void onDisconnect(Intent intent) {
+ super.onDisconnect(intent);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ cancelNotification();
+ if (player != null) {
+ player.release();
+ player = null;
+ }
+ }
+
+ private void sendEvent() {
+ try {
+ Intent intent = new Intent();
+ Operation operation = new Intent.OperationBuilder()
+ .withAction(EVENT_ACTION)
+ .build();
+ intent.setOperation(operation);
+ intent.setParam("state", state);
+ CommonEventData eventData = new CommonEventData(intent);
+ CommonEventManager.publishCommonEvent(eventData);
+ } catch (RemoteException e) {
+ HiLog.error(LABEL_LOG, "Exception occurred during publishCommonEvent invocation.");
+ }
+ }
+
+ private void sendNotification(String str) {
+ String slotId = "foregroundServiceId";
+ String slotName = "foregroundServiceName";
+ NotificationSlot slot = new NotificationSlot(slotId, slotName, NotificationSlot.LEVEL_MIN);
+ slot.setDescription("NotificationSlot Description");
+ slot.setEnableVibration(true);
+ slot.setLockscreenVisibleness(NotificationRequest.VISIBLENESS_TYPE_PUBLIC);
+ slot.setEnableLight(true);
+ slot.setLedLightColor(Color.RED.getValue());
+ try {
+ NotificationHelper.addNotificationSlot(slot);
+ } catch (RemoteException ex) {
+ HiLog.error(LABEL_LOG, "Exception occurred during addNotificationSlot invocation.");
+ }
+ int notificationId = 1;
+ NotificationRequest request = new NotificationRequest(notificationId);
+ request.setSlotId(slot.getId());
+ String title = "Music Player";
+ String text = "The Music Service is in " + str;
+ NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
+ content.setTitle(title)
+ .setText(text);
+ NotificationRequest.NotificationContent notificationContent =
+ new NotificationRequest.NotificationContent(content);
+ request.setContent(notificationContent);
+ keepBackgroundRunning(notificationId, request);
+ }
+
+ private void cancelNotification() {
+ cancelBackgroundRunning();
+ }
+
+ /**
+ * Start Play Music
+ */
+ public void startMusic() {
+ if (state != STOP_STATE) {
+ return;
+ }
+ player = new Player(getContext());
+ RawFileDescriptor filDescriptor;
+ try {
+ filDescriptor = getResourceManager().getRawFileEntry("resources/rawfile/Homey.mp3").openRawFileDescriptor();
+ Source source = new Source(filDescriptor.getFileDescriptor(), filDescriptor.getStartPosition(),
+ filDescriptor.getFileSize());
+ player.setSource(source);
+ player.prepare();
+ player.play();
+ player.enableSingleLooping(true);
+ state = PLAY_STATE;
+ sendNotification("Playing");
+ sendEvent();
+ } catch (IOException e) {
+ HiLog.error(LABEL_LOG, "Exception occurred during openRawFileDescriptor invocation.");
+ }
+ }
+
+ /**
+ * Stop Play Music
+ */
+ public void stopMusic() {
+ if (state == STOP_STATE) {
+ return;
+ }
+ player.stop();
+ player.release();
+ player = null;
+ state = STOP_STATE;
+ cancelNotification();
+ sendEvent();
+ }
+
+ /**
+ * Pause Play Music
+ */
+ public void pauseMusic() {
+ switch (state) {
+ case PAUSE_STATE: {
+ player.play();
+ state = PLAY_STATE;
+ sendNotification("Playing");
+ sendEvent();
+ break;
+ }
+ case PLAY_STATE: {
+ player.pause();
+ state = PAUSE_STATE;
+ sendNotification("Pausing");
+ sendEvent();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ /**
+ * LocalRemoteObject Implementation
+ *
+ * @since 2021-05-08
+ */
+ public static class MusicRemoteObject extends LocalRemoteObject {
+ private final ServiceAbility musicService;
+
+ MusicRemoteObject(ServiceAbility musicService) {
+ this.musicService = musicService;
+ }
+
+ /**
+ * startPlay Music
+ */
+ public void startPlay() {
+ musicService.startMusic();
+ }
+
+ /**
+ * pausePlay Music
+ */
+ public void pausePlay() {
+ musicService.pauseMusic();
+ }
+
+ /**
+ * stopPlay Music
+ */
+ public void stopPlay() {
+ musicService.stopMusic();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/slice/MainAbilitySlice.java b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/slice/MainAbilitySlice.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f20372c306f4b481f54e5caa401a3f7bee85ba2
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/java/ohos/samples/foregroundservice/slice/MainAbilitySlice.java
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+package ohos.samples.foregroundservice.slice;
+
+import static ohos.samples.foregroundservice.ServiceAbility.PAUSE_STATE;
+import static ohos.samples.foregroundservice.ServiceAbility.PLAY_STATE;
+import static ohos.samples.foregroundservice.ServiceAbility.STOP_STATE;
+
+import ohos.aafwk.ability.AbilitySlice;
+import ohos.aafwk.ability.IAbilityConnection;
+import ohos.aafwk.content.Intent;
+import ohos.aafwk.content.Operation;
+import ohos.agp.components.Button;
+import ohos.agp.components.Component;
+import ohos.bundle.ElementName;
+import ohos.event.commonevent.CommonEventData;
+import ohos.event.commonevent.CommonEventManager;
+import ohos.event.commonevent.CommonEventSubscribeInfo;
+import ohos.event.commonevent.CommonEventSubscriber;
+import ohos.event.commonevent.MatchingSkills;
+import ohos.hiviewdfx.HiLog;
+import ohos.hiviewdfx.HiLogLabel;
+import ohos.rpc.IRemoteObject;
+import ohos.rpc.RemoteException;
+import ohos.samples.foregroundservice.ResourceTable;
+import ohos.samples.foregroundservice.ServiceAbility;
+
+/**
+ * MainAbilitySlice
+ *
+ * @since 2021-05-08
+ */
+public class MainAbilitySlice extends AbilitySlice {
+ /**
+ * Event Action Name
+ */
+ public static final String EVENT_ACTION = "ohos.samples.forgroundservice";
+
+ private static final String BUNDLE_NAME = "ohos.samples.foregroundservice";
+
+ private static final String ABILITY_NAME = "ohos.samples.foregroundservice.ServiceAbility";
+
+ private static final String TAG = MainAbilitySlice.class.getName();
+
+ private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
+
+ private static final int DEFAULT_STATE = -1;
+
+ private Button startPlay;
+
+ private Button pausePlay;
+
+ private Button stopPlay;
+
+ private ServiceAbility.MusicRemoteObject musicRemoteObject;
+
+ private MyCommonEventSubscriber subscriber;
+
+ private int lastState = DEFAULT_STATE;
+
+ private final IAbilityConnection connection = new IAbilityConnection() {
+ @Override
+ public void onAbilityConnectDone(ElementName elementName, IRemoteObject remoteObject, int i) {
+ if (remoteObject instanceof ServiceAbility.MusicRemoteObject) {
+ musicRemoteObject = (ServiceAbility.MusicRemoteObject) remoteObject;
+ }
+ }
+
+ @Override
+ public void onAbilityDisconnectDone(ElementName elementName, int i) {
+ HiLog.info(LABEL_LOG, "onAbilityDisconnectDone.");
+ }
+ };
+
+ @Override
+ public void onStart(Intent intent) {
+ super.onStart(intent);
+ super.setUIContent(ResourceTable.Layout_main_ability_slice);
+ initView();
+ initEventListener();
+ initSubscribeEvent();
+ startService();
+ }
+
+ private void startService() {
+ Intent intent = new Intent();
+ Operation operation = new Intent.OperationBuilder()
+ .withDeviceId("")
+ .withBundleName(BUNDLE_NAME)
+ .withAbilityName(ABILITY_NAME)
+ .build();
+ intent.setOperation(operation);
+ startAbility(intent);
+ connectAbility(intent, connection);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ try {
+ CommonEventManager.unsubscribeCommonEvent(subscriber);
+ } catch (RemoteException e) {
+ HiLog.error(LABEL_LOG, "Exception occurred during unsubscribeCommonEvent invocation.");
+ }
+ disconnectAbility(connection);
+ }
+
+ private void initEventListener() {
+ startPlay.setClickedListener(component -> musicRemoteObject.startPlay());
+ pausePlay.setClickedListener(component -> musicRemoteObject.pausePlay());
+ stopPlay.setClickedListener(component -> musicRemoteObject.stopPlay());
+ }
+
+ private void initView() {
+ Component startPlayComponent = findComponentById(ResourceTable.Id_start);
+ if (startPlayComponent instanceof Button) {
+ startPlay = (Button) startPlayComponent;
+ }
+ Component pausePlayComponent = findComponentById(ResourceTable.Id_pause);
+ if (pausePlayComponent instanceof Button) {
+ pausePlay = (Button) pausePlayComponent;
+ }
+ Component stopPlayComponent = findComponentById(ResourceTable.Id_stop);
+ if (stopPlayComponent instanceof Button) {
+ stopPlay = (Button) stopPlayComponent;
+ }
+ }
+
+ private void initSubscribeEvent() {
+ MatchingSkills matchingSkills = new MatchingSkills();
+ matchingSkills.addEvent(EVENT_ACTION);
+ CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
+ subscriber = new MyCommonEventSubscriber(subscribeInfo);
+ try {
+ CommonEventManager.subscribeCommonEvent(subscriber);
+ } catch (RemoteException e) {
+ HiLog.error(LABEL_LOG, "Exception occurred during subscribeCommonEvent invocation.");
+ }
+ }
+
+ private void setState(int state) {
+ switch (state) {
+ case PAUSE_STATE: {
+ handleButtonState();
+ pausePlay.setText(ResourceTable.String_resume_play);
+ break;
+ }
+ case PLAY_STATE: {
+ handleButtonState();
+ break;
+ }
+ case STOP_STATE: {
+ startPlay.setEnabled(true);
+ pausePlay.setEnabled(false);
+ stopPlay.setEnabled(false);
+ pausePlay.setText(ResourceTable.String_pause_play);
+ break;
+ }
+ default:
+ }
+ if (state == PLAY_STATE && lastState == PAUSE_STATE) {
+ pausePlay.setText(ResourceTable.String_pause_play);
+ }
+ lastState = state;
+ }
+
+ private void handleButtonState() {
+ startPlay.setEnabled(false);
+ pausePlay.setEnabled(true);
+ stopPlay.setEnabled(true);
+ }
+
+ /**
+ * CommonEventSubscriber Implementation
+ *
+ * @since 2021-05-08
+ */
+ class MyCommonEventSubscriber extends CommonEventSubscriber {
+ MyCommonEventSubscriber(CommonEventSubscribeInfo info) {
+ super(info);
+ }
+
+ @Override
+ public void onReceiveEvent(CommonEventData commonEventData) {
+ Intent intent = commonEventData.getIntent();
+ int state = intent.getIntParam("state", DEFAULT_STATE);
+ if (state != DEFAULT_STATE) {
+ setState(state);
+ }
+ }
+ }
+}
diff --git a/ability/ForegroundService/entry/src/main/resources/base/element/color.json b/ability/ForegroundService/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..5089608bcc6d1b017367f2370911a4743c972723
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "text_color",
+ "value": "#ffffff"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/resources/base/element/float.json b/ability/ForegroundService/entry/src/main/resources/base/element/float.json
new file mode 100644
index 0000000000000000000000000000000000000000..053fa9aa596f6f4e3cd86c753d0ee27a6b94200b
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/element/float.json
@@ -0,0 +1,33 @@
+{
+ "float":[
+ {
+ "name":"text_size",
+ "value":"20fp"
+ },
+ {
+ "name":"left_margin",
+ "value":"20vp"
+ },
+ {
+ "name":"right_margin",
+ "value":"20vp"
+ },
+ {
+ "name":"bottom_margin",
+ "value":"15vp"
+ },
+ {
+ "name":"top_margin",
+ "value":"20vp"
+ },
+ {
+ "name":"left_padding",
+ "value":"15vp"
+ },
+ {
+ "name":"right_padding",
+ "value":"15vp"
+ }
+ ]
+}
+
diff --git a/ability/ForegroundService/entry/src/main/resources/base/element/string.json b/ability/ForegroundService/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..a0f9ac29d9fb3e77673c375089ab7eadb1e99463
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,32 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "ForegroundService"
+ },
+ {
+ "name": "mainability_description",
+ "value": "Java_Phone_Empty Feature Ability"
+ },
+ {
+ "name": "serviceability_description",
+ "value": "hap sample empty service"
+ },
+ {
+ "name": "start_play",
+ "value": "Start Play"
+ },
+ {
+ "name": "pause_play",
+ "value": "Pause Play"
+ },
+ {
+ "name": "stop_play",
+ "value": "Stop Play"
+ },
+ {
+ "name": "resume_play",
+ "value": "Resume Play"
+ }
+ ]
+}
diff --git a/ability/ForegroundService/entry/src/main/resources/base/graphic/background_ability_main.xml b/ability/ForegroundService/entry/src/main/resources/base/graphic/background_ability_main.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1018ca3426c32c9d7ba832131e1ae9bd4f7ac2c6
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/graphic/background_ability_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_disenable.xml b/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_disenable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..16848b2c1e5db664076349a9d6916b0d5f8d3871
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_disenable.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_enable.xml b/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_enable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e19311fb4c4124ebfd23e35b5bd1a75eef49228
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/graphic/circle_enable.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/ability/ForegroundService/entry/src/main/resources/base/graphic/select_button.xml b/ability/ForegroundService/entry/src/main/resources/base/graphic/select_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1b3a5d26166380ea2787a1d9933dfae3e9488dad
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/graphic/select_button.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/ability/ForegroundService/entry/src/main/resources/base/layout/main_ability_slice.xml b/ability/ForegroundService/entry/src/main/resources/base/layout/main_ability_slice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c5f6585f350f9691ad8228023a61784cde44294
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/base/layout/main_ability_slice.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ability/ForegroundService/entry/src/main/resources/base/media/icon.png b/ability/ForegroundService/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/ability/ForegroundService/entry/src/main/resources/base/media/icon.png differ
diff --git a/ability/ForegroundService/entry/src/main/resources/rawfile/Homey.mp3 b/ability/ForegroundService/entry/src/main/resources/rawfile/Homey.mp3
new file mode 100644
index 0000000000000000000000000000000000000000..b4e53978f0080d6532574ba9ea313ee306be1465
Binary files /dev/null and b/ability/ForegroundService/entry/src/main/resources/rawfile/Homey.mp3 differ
diff --git a/ability/ForegroundService/entry/src/main/resources/zh_CN/element/string.json b/ability/ForegroundService/entry/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..02ff877c422e5ba2a633cce7db500186b9620860
--- /dev/null
+++ b/ability/ForegroundService/entry/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,24 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "前台服务"
+ },
+ {
+ "name": "start_play",
+ "value": "开始播放"
+ },
+ {
+ "name": "pause_play",
+ "value": "暂停播放"
+ },
+ {
+ "name": "stop_play",
+ "value": "停止播放"
+ },
+ {
+ "name": "resume_play",
+ "value": "恢复播放"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ability/ForegroundService/screenshots/device/foregroundService_normal.png b/ability/ForegroundService/screenshots/device/foregroundService_normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf92562fe36ed110ff73dd23b7246285cb45fd5b
Binary files /dev/null and b/ability/ForegroundService/screenshots/device/foregroundService_normal.png differ
diff --git a/ability/ForegroundService/screenshots/device/foregroundservice_play.png b/ability/ForegroundService/screenshots/device/foregroundservice_play.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc48a7010a13b92ef790b9ef4786f7777380f8d3
Binary files /dev/null and b/ability/ForegroundService/screenshots/device/foregroundservice_play.png differ
diff --git a/ability/ForegroundService/settings.gradle b/ability/ForegroundService/settings.gradle
new file mode 100644
index 0000000000000000000000000000000000000000..7dc3285c045cc590e49d231a4280ef52ba646d91
--- /dev/null
+++ b/ability/ForegroundService/settings.gradle
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
+include ':entry'