• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-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 */
15
16import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
17import commonEventManager from '@ohos.commonEventManager';
18import common from '@ohos.app.ability.common';
19import router from '@ohos.router';
20import resourceManager from '@ohos.resourceManager';
21import { BusinessError } from '@ohos.base';
22
23let TAG = '[Location-Privacy]==>';
24const LOCATION_PRIVACY_ACCEPT_EVENT: string = 'usual.event.LOCATION_PRIVACY_ACCEPT';
25const LOCATION_PRIVACY_REJECT_EVENT: string = 'usual.event.LOCATION_PRIVACY_REJECT';
26const BODY_L = getNumberByResourceId(125830970, 16);
27const TITLE_S = getNumberByResourceId(125830966, 20);
28const BUTTON_HORIZONTAL_SPACE: number = getNumberByResourceId(125831051, 8);
29const BUTTON_LAYOUT_WEIGHT: number = 1;
30const FLAG_BEGIN: string = '<a';
31const FLAG_BEGIN_END: string = '>';
32const FLAG_END: string = '</a>';
33
34@CustomDialog
35struct LocationCustomDialog {
36  controller?: CustomDialogController
37  cancel: () => void = () => {}
38  accept: () => void = () => {}
39  private context = getContext(this) as common.UIAbilityContext;
40
41  build() {
42    Column() {
43      Column() {
44        Row() {
45          Text($r('app.string.location_target_statement_title'))
46            .fontSize(`${TITLE_S}fp`)
47            .fontWeight(FontWeight.Bold)
48            .textAlign(TextAlign.Start)
49            .width("100%")
50            .padding(this.getTitleAreaPadding())
51        }
52      }
53      Column() {
54        Row() {
55          Text() {
56            Span(this.getStatementContent()[0])
57            Span(this.getStatementContent()[1])
58              .fontColor($r('sys.color.ohos_id_color_text_hyperlink'))
59              .fontWeight(FontWeight.Bold)
60              .onClick(() => {
61                console.info(TAG, 'click privacy page');
62                this.routePage();
63              })
64            Span(this.getStatementContent()[2])
65          }
66          .focusable(true)
67          .fontSize(`${BODY_L}fp`)
68          .padding(this.getContentPadding())
69        }
70      }
71      Row() {
72        Button($r('app.string.cancel_button'))
73          .onClick(() => {
74            this.cancel();
75            if (this.controller) {
76              this.controller.close();
77            }
78          })
79          .layoutWeight(BUTTON_LAYOUT_WEIGHT)
80          .buttonStyle(ButtonStyleMode.TEXTUAL)
81          .labelStyle({
82            maxLines: 1,
83            maxFontSize: `${BODY_L}fp`,
84            minFontSize: 9
85          })
86        Row() {
87          Divider()
88            .width($r('sys.float.alert_divider_width'))
89            .height($r('sys.float.alert_divider_height'))
90            .color($r('sys.color.alert_divider_color'))
91            .vertical(true)
92        }
93        .width(BUTTON_HORIZONTAL_SPACE * 2)
94        .justifyContent(FlexAlign.Center)
95        Button($r('app.string.confirm_button'))
96          .onClick(() => {
97            this.accept();
98            if (this.controller) {
99              this.controller.close();
100            }
101          })
102          .layoutWeight(BUTTON_LAYOUT_WEIGHT)
103          .type(ButtonType.ROUNDED_RECTANGLE)
104          .labelStyle({
105            maxLines: 1,
106            maxFontSize: `${BODY_L}fp`,
107            minFontSize: 9
108          })
109      }
110      .padding(this.getButtonPadding())
111    }
112  }
113
114  async routePage() {
115    let options: router.RouterOptions = {
116      url: 'pages/PrivacyLoadPage',
117    }
118    try {
119      await router.pushUrl(options);
120    } catch (err) {
121      console.info(TAG, `fail callback, code: ${(err as BusinessError).code}`);
122    }
123  }
124
125  private getStatementContent(): Array<string> {
126    let result: Array<string> = ['', '', ''];
127    let text = this.context.resourceManager.getStringByNameSync("location_target_statement_content");
128    let beginIndex = text.indexOf(FLAG_BEGIN);
129    if (beginIndex !== 0 && beginIndex !== -1) {
130      result[0] = text.substr(0, beginIndex);
131      text = text.substr(beginIndex, text.length);
132    }
133    let beginEndIndex = text.indexOf(FLAG_BEGIN_END);
134    let endIndex = text.indexOf(FLAG_END);
135    if (beginEndIndex !== -1 && endIndex !== -1) {
136      result[1] = text.substr(beginEndIndex + 1, endIndex - FLAG_END.length + 1);
137      result[2] = text.substr(endIndex + FLAG_END.length, text.length);
138    }
139
140    return result;
141  }
142
143  /**
144   * get title area padding
145   *
146   * @returns padding
147   */
148  private getTitleAreaPadding(): Padding {
149    return {
150      top: $r('sys.float.alert_title_padding_top'),
151      right: $r('sys.float.alert_title_padding_right'),
152      left: $r('sys.float.alert_title_padding_left'),
153      bottom: 0,
154    };
155  }
156
157  /**
158   * get content padding
159   *
160   * @returns padding
161   */
162  private getContentPadding(): Padding {
163    return {
164      top: $r('sys.float.alert_content_default_padding'),
165      right: $r('sys.float.alert_content_default_padding'),
166      left: $r('sys.float.alert_content_default_padding'),
167      bottom: $r('sys.float.alert_content_default_padding'),
168    };
169  }
170
171  /**
172   * get button padding
173   *
174   * @returns padding
175   */
176  private getButtonPadding(): Padding {
177    return {
178      top: 0,
179      right: $r('sys.float.alert_content_default_padding'),
180      left: $r('sys.float.alert_content_default_padding'),
181      bottom: $r('sys.float.alert_content_default_padding'),
182    };
183  }
184}
185
186@Entry
187@Component
188struct dialogPlusPage {
189  dialogController: CustomDialogController = new CustomDialogController({
190    builder: LocationCustomDialog({
191      cancel: this.onCancel,
192      accept: this.onAccept,
193    }),
194    cancel: this.existApp,
195    autoCancel: false,
196    alignment: DialogAlignment.Bottom,
197    customStyle: false
198  })
199
200  aboutToAppear() {
201    console.info(TAG, 'aboutToAppear execute LocationPrivacyDialog')
202  }
203
204  aboutToDisappear() {
205    let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession');
206    if (session) {
207      session.terminateSelf();
208    }
209  }
210
211  onCancel() {
212    console.info(TAG, 'Callback when the first button is clicked')
213
214    const options: commonEventManager.CommonEventPublishData = {
215      code: 0,
216      data: 'message',
217      isSticky: false,
218      parameters: { 'message': 'reject' }
219    }
220
221    commonEventManager.publish(LOCATION_PRIVACY_REJECT_EVENT, options, (err) => {
222      if (err) {
223        console.info(TAG, '[CommonEvent] PublishCallBack err=' + JSON.stringify(err));
224      } else {
225        console.info(TAG, '[CommonEvent] Publish success')
226      }
227    })
228
229    let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession');
230    if (session) {
231      session.terminateSelf();
232    }
233  }
234
235  onAccept() {
236    console.info(TAG, 'Callback when the second button is clicked')
237
238    const options: commonEventManager.CommonEventPublishData = {
239      code: 0,
240      data: 'message',
241      isSticky: false,
242      parameters: { 'message': 'accept' }
243    }
244
245    commonEventManager.publish(LOCATION_PRIVACY_ACCEPT_EVENT, options, (err) => {
246      if (err) {
247        console.info(TAG, '[CommonEvent] PublishCallBack err=' + JSON.stringify(err));
248      } else {
249        console.info(TAG, '[CommonEvent] Publish success')
250      }
251    })
252
253    let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession');
254    if (session) {
255      session.terminateSelf();
256    }
257  }
258
259  existApp() {
260    console.info(TAG, 'Click the callback in the blank area')
261    let session = AppStorage.get<UIExtensionContentSession>('ConfirmSession');
262    if (session) {
263      session.terminateSelf();
264    }
265  }
266
267  build() {
268    Column(this.dialogController.open()) {}
269  }
270}
271
272/**
273  * get resource size
274  *
275  * @param resourceId resource id
276  * @param defaultValue default value
277  * @returns resource size
278  */
279function getNumberByResourceId(resourceId: number, defaultValue: number, allowZero?: boolean): number {
280  try {
281    let sourceValue: number = resourceManager.getSystemResourceManager().getNumber(resourceId);
282    if (sourceValue > 0 || allowZero) {
283      return sourceValue;
284    } else {
285      return defaultValue;
286    }
287  } catch (error) {
288    return defaultValue;
289  }
290}