• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15import hilog from '@ohos.hilog';
16import abilityManager from '@ohos.app.ability.abilityManager';
17import common from '@ohos.app.ability.common';
18import { ErrorCallback, Callback } from '@ohos.base';
19import AtomicServiceOptions from '@ohos.app.ability.AtomicServiceOptions';
20import commonEventManager from '@ohos.commonEventManager';
21import Base from '@ohos.base';
22
23const EMBEDDED_HALF_MODE = 2;
24@Component
25export struct HalfScreenLaunchComponent {
26  @BuilderParam content: Callback<void> = this.doNothingBuilder;
27  context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
28  appId: string = '';
29  options?: AtomicServiceOptions;
30  @State private isShow: boolean = false;
31  private subscriber: commonEventManager.CommonEventSubscriber | null = null;
32  onError?: ErrorCallback;
33  onTerminated?: Callback<TerminationInfo>;
34
35  aboutToAppear(): void {
36    let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
37      events: [commonEventManager.Support.COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT],
38    };
39
40    commonEventManager.createSubscriber(subscribeInfo,
41      (err: Base.BusinessError, data: commonEventManager.CommonEventSubscriber) => {
42        if (err) {
43          hilog.error(0x3900, 'HalfScreenLaunchComponent',
44            'Failed to create subscriber, err: %{public}s.', JSON.stringify(err));
45          return;
46        }
47
48        if (data === null || data === undefined) {
49          hilog.error(0x3900, 'HalfScreenLaunchComponent', 'Failed to create subscriber, data is null.');
50          return;
51        }
52
53        this.subscriber = data;
54        commonEventManager.subscribe(this.subscriber,
55          (err: Base.BusinessError, data: commonEventManager.CommonEventData) => {
56            if (err) {
57              hilog.error(0x3900, 'HalfScreenLaunchComponent',
58                'Failed to subscribe common event, err: %{public}s.', JSON.stringify(err));
59              return;
60            }
61            this.isShow = false;
62          })
63      })
64  }
65
66  aboutToDisappear(): void {
67    if (this.subscriber !== null) {
68      commonEventManager.unsubscribe(this.subscriber, (err) => {
69        if (err) {
70          hilog.error(0x3900, 'HalfScreenLaunchComponent',
71            'UnsubscribeCallBack, err: %{public}s.', JSON.stringify(err));
72        } else {
73          hilog.info(0x3900, 'HalfScreenLaunchComponent', 'Unsubscribe.');
74          this.subscriber = null;
75        }
76      })
77    }
78  }
79
80  @Builder
81  doNothingBuilder() {
82  };
83
84  resetOptions(): void {
85    if (this.options?.parameters) {
86      this.options.parameters['ohos.extra.param.key.showMode'] = EMBEDDED_HALF_MODE;
87      this.options.parameters['ability.want.params.IsNotifyOccupiedAreaChange'] = true;
88      this.options.parameters['ability.want.params.IsModal'] = true;
89      hilog.info(0x3900, 'HalfScreenLaunchComponent', 'replaced options is %{public}s !', JSON.stringify(this.options));
90    } else {
91      this.options = {
92        parameters: {
93          'ohos.extra.param.key.showMode': EMBEDDED_HALF_MODE,
94          'ability.want.params.IsNotifyOccupiedAreaChange': true,
95          'ability.want.params.IsModal': true
96        }
97      }
98    }
99  }
100
101  async checkAbility(): void {
102    this.resetOptions();
103    try {
104      const res: boolean = await abilityManager.isEmbeddedOpenAllowed(this.context, this.appId);
105      if (res) {
106        if (this.isShow) {
107          this.isShow = false;
108          hilog.error(0x3900, 'HalfScreenLaunchComponent', ' EmbeddedOpen is already show!');
109          return;
110        }
111        this.isShow = true;
112        hilog.info(0x3900, 'HalfScreenLaunchComponent', ' EmbeddedOpen is Allowed!');
113      } else {
114        this.popUp();
115      }
116    } catch (e) {
117      hilog.error(0x3900, 'HalfScreenLaunchComponent', 'isEmbeddedOpenAllowed called error!%{public}s', e.message);
118    }
119  }
120
121  async popUp(): void {
122    this.isShow = false;
123    try {
124      const ability = await this.context.openAtomicService(this.appId, this.options);
125      hilog.info(0x3900, 'HalfScreenLaunchComponent', '%{public}s open service success!', ability.want);
126    } catch (e) {
127      hilog.error(0x3900, 'HalfScreenLaunchComponent', '%{public}s open service error!', e.message);
128    }
129  }
130
131  build() {
132    Row() {
133      this.content();
134    }.justifyContent(FlexAlign.Center)
135    .onClick(
136      () => {
137        hilog.info(0x3900, 'HalfScreenLaunchComponent', 'on start atomicservice');
138        this.checkAbility();
139      }
140    ).bindContentCover($$this.isShow, this.uiExtensionBuilder(), { modalTransition: ModalTransition.NONE });
141
142  }
143
144  @Builder
145  uiExtensionBuilder() {
146    UIExtensionComponent({
147      bundleName: `com.atomicservice.${this.appId}`,
148      flags: this.options?.flags,
149      parameters: this.options?.parameters
150    },
151    {
152      windowModeFollowStrategy: WindowModeFollowStrategy.FOLLOW_UI_EXTENSION_ABILITY_WINDOW_MODE
153    })
154      .height('100%')
155      .width('100%')
156      .backgroundColor(Color.Transparent)
157      .onError(
158        err => {
159          if (this.onError) {
160            this.onError(err);
161          }
162          this.isShow = false;
163          hilog.error(0x3900, 'HalfScreenLaunchComponent', 'call up UIExtension error!%{public}s', err.message);
164          this.getUIContext().showAlertDialog({
165            message: err.message
166          });
167        }
168      )
169      .onTerminated(info => {
170        this.isShow = false;
171        if (this.onTerminated) {
172          this.onTerminated(info);
173        }
174      })
175  }
176}