• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2024-2024 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 { WidthPercent } from '../../common/util/ConfigData';
17import { CertificateComponent } from '../certManagerFa';
18import { NavEntryKey } from '../../common/NavEntryKey';
19import { CaCertPage } from './CaCertPage';
20import { CredListPage } from './CredListPage';
21import { InstallPage } from './InstallPage';
22import { CaSystemDetailPage } from '../detail/CaSystemDetailPage';
23import { CaUserDetailPage } from '../detail/CaUserDetailPage';
24import { CredSystemDetailPage } from '../detail/CredSystemDetailPage';
25import { CredUserDetailPage } from '../detail/CredUserDetailPage';
26import { AuthorizedAppManagementPage } from '../detail/AuthorizedAppManagementPage';
27import { CredPwdInputPage } from '../detail/CredPwdInputPage';
28import Want from '@ohos.app.ability.Want';
29import deviceInfo from '@ohos.deviceInfo';
30import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
31import { TrustedEvidence } from '../trustedCa';
32import { evidenceList } from '../cerEvidenceFa';
33import { CertInstallFromStorage } from '../certInstallFromStorage';
34import window from '@ohos.window';
35import { SheetParam } from '../../common/util/SheetParam';
36import uiExtensionHost from '@ohos.uiExtensionHost';
37import { BusinessError } from '@ohos.base';
38import PreventScreenshotsPresenter from '../../model/PreventScreenshotsModel';
39
40const TAG: string = 'CertManagerSheetFa:';
41
42let storage = LocalStorage.getShared();
43
44const PAGE_MAIN: number = 1;
45const PAGE_CA_CERTIFICATE: number = 2;
46const PAGE_CREDENTIAL: number = 3;
47const PAGE_INSTALL_CERTIFICATE: number = 4;
48const PAGE_TYPE: string = 'pageType';
49
50const BOTTOM_SHEET_MIN_PERCENT = 0.6;
51const CENTER_SHEET_MAX_PERCENT = 0.9;
52const CENTER_SHEET_MIN_HEIGHT = 560;
53
54interface AvoidAreaParam {
55  type: window.AvoidAreaType;
56  area: window.AvoidArea;
57}
58
59@Entry(storage)
60@Component
61export struct CertManagerSheetFa {
62  private sheetSession: UIExtensionContentSession =
63    storage.get<UIExtensionContentSession>('session') as UIExtensionContentSession;
64  private want: Want = storage.get<Want>('want') as Want;
65  private preventScreenshotsPresenter: PreventScreenshotsPresenter = PreventScreenshotsPresenter.getInstance();
66
67  @State @Watch('onSheetPageChanged') private stack: NavPathStack = new NavPathStack();
68  @State private sheetParam: SheetParam = new SheetParam();
69  @State private pageType: number = PAGE_MAIN;
70  @State private maxSheetPageHeight: number = 0;
71  @State private rootWidth: number = 0;
72  @State private rootHeight: number = 0;
73  @State private statusBarHeight: number = 0;
74  @State private aiBarHeight: number = 0;
75
76  private avoidAreaChangedCallback: Callback<AvoidAreaParam> = (avoidArea) => {
77    if (avoidArea.type === window.AvoidAreaType.TYPE_SYSTEM) {
78      this.statusBarHeight = px2vp(avoidArea.area.topRect.height);
79      this.updateSheetHeightLimit();
80    } else if (avoidArea.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
81      this.aiBarHeight = px2vp(avoidArea.area.bottomRect.height);
82      this.updateSheetHeightLimit();
83    } else {
84      console.warn(TAG + 'avoidAreaChangedCallback, sheet type is invalid:' + this.sheetParam.sheetType);
85    }
86  }
87
88  onSheetPageChanged(): void {
89    let allPageArray = this.stack.getAllPathName();
90    if (allPageArray === undefined || allPageArray.length === 0) {
91      this.preventScreenshotsPresenter.PreventScreenshots(false, this.sheetSession);
92      this.sheetParam.lastSheetPage = '';
93      return;
94    }
95    let lastPage = allPageArray[allPageArray.length - 1];
96    this.sheetParam.lastSheetPage = lastPage;
97    if (lastPage !== NavEntryKey.CRED_PWD_INPUT_ENTRY) {
98      this.preventScreenshotsPresenter.PreventScreenshots(false, this.sheetSession);
99      return;
100    }
101    this.preventScreenshotsPresenter.PreventScreenshots(true, this.sheetSession);
102  }
103
104  aboutToAppear(): void {
105    this.registerAvoidChangedListener();
106    const parameters = this.want?.parameters;
107    if (parameters === undefined || parameters[PAGE_TYPE] === undefined) {
108      console.warn(TAG + 'page type param is undefined');
109      return;
110    }
111    this.pageType = parameters[PAGE_TYPE] as number;
112    console.log(TAG + 'page type = ' + this.pageType);
113  }
114
115  aboutToDisappear(): void {
116    this.unregisterAvoidChangedListener();
117  }
118
119  initStatusBarHeight(extWindow: uiExtensionHost.UIExtensionHostWindowProxy): void {
120    try {
121      let avoidArea: window.AvoidArea = extWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
122      if (avoidArea === undefined) {
123        console.warn(TAG + 'initStatusBarHeight, avoid area is undefined');
124      }
125      this.statusBarHeight = px2vp(avoidArea.topRect.height);
126    } catch (err) {
127      let error = err as BusinessError;
128      console.error(TAG + 'initStatusBarHeight, occur error:' + error?.code + ', msg:' + error?.message);
129    }
130  }
131
132  initAiBarHeight(extWindow: uiExtensionHost.UIExtensionHostWindowProxy): void {
133    try {
134      let avoidArea: window.AvoidArea = extWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
135      if (avoidArea === undefined) {
136        console.warn(TAG + 'initAiBarHeight, avoid area is undefined');
137      }
138      this.aiBarHeight = px2vp(avoidArea.bottomRect.height);
139    } catch (err) {
140      let error = err as BusinessError;
141      console.error(TAG + 'initAiBarHeight, occur error:' + error?.code + ', msg:' + error?.message);
142    }
143  }
144
145  registerAvoidChangedListener(): void {
146    try {
147      let extWindow: uiExtensionHost.UIExtensionHostWindowProxy = this.sheetSession?.getUIExtensionHostWindowProxy();
148      if (extWindow === undefined) {
149        console.error(TAG + 'registerAvoidChangedListener, get extra window is undefined');
150        return;
151      }
152      this.initStatusBarHeight(extWindow);
153      this.initAiBarHeight(extWindow);
154      extWindow.on('avoidAreaChange', this.avoidAreaChangedCallback);
155    } catch (err) {
156      let error = err as BusinessError;
157      console.error(TAG + 'registerAvoidChangedListener, occur error:' + error?.code + ', msg:' + error?.message);
158    }
159  }
160
161  unregisterAvoidChangedListener(): void {
162    try {
163      let extWindow: uiExtensionHost.UIExtensionHostWindowProxy = this.sheetSession?.getUIExtensionHostWindowProxy();
164      if (extWindow === undefined) {
165        console.error(TAG + 'unregisterAvoidChangedListener, get extra window is undefined');
166        return;
167      }
168      extWindow.off('avoidAreaChange', this.avoidAreaChangedCallback);
169    } catch (err) {
170      let error = err as BusinessError;
171      console.error(TAG + 'unregisterAvoidChangedListener, occur error:' + error?.code + ', msg:' + error?.message);
172    }
173  }
174
175  private updateSheetHeightLimit(): void {
176    if (this.rootHeight === 0) {
177      return;
178    }
179    if (this.sheetParam.sheetType === SheetType.BOTTOM) {
180      this.maxSheetPageHeight = this.rootHeight - this.statusBarHeight - 8;
181      this.sheetParam.sheetMinHeight = this.rootHeight * BOTTOM_SHEET_MIN_PERCENT;
182    } else if (this.sheetParam.sheetType === SheetType.CENTER) {
183      let shortSide = Math.min(this.rootWidth, (this.rootHeight - this.statusBarHeight - this.aiBarHeight));
184      this.maxSheetPageHeight = shortSide * CENTER_SHEET_MAX_PERCENT;
185      this.sheetParam.sheetMinHeight = CENTER_SHEET_MIN_HEIGHT;
186    } else {
187      console.warn(TAG + 'updateSheetHeightLimit, sheet type is invalid:' + this.sheetParam.sheetType);
188    }
189  }
190
191  @Builder
192  private routerMap(name: string, param?: Object) {
193    if (name === NavEntryKey.CA_CERTIFICATE_ENTRY) {
194      CaCertPage({
195        sheetParam: this.sheetParam
196      })
197    } else if (name === NavEntryKey.CREDENTIAL_LIST_ENTRY) {
198      CredListPage({
199        sheetParam: this.sheetParam
200      })
201    } else if (name === NavEntryKey.INSTALL_ENTRY) {
202      InstallPage({
203        sheetParam: this.sheetParam
204      })
205    } else if (name === NavEntryKey.CA_SYSTEM_DETAIL_ENTRY) {
206      CaSystemDetailPage({
207        sheetParam: this.sheetParam
208      })
209    } else if (name === NavEntryKey.CA_USER_DETAIL_ENTRY) {
210      CaUserDetailPage({
211        sheetParam: this.sheetParam
212      })
213    } else if (name === NavEntryKey.CRED_SYSTEM_DETAIL_ENTRY) {
214      CredSystemDetailPage({
215        sheetParam: this.sheetParam
216      })
217    } else if (name === NavEntryKey.CRED_USER_DETAIL_ENTRY) {
218      CredUserDetailPage({
219        sheetParam: this.sheetParam
220      })
221    } else if (name === NavEntryKey.AUTHORIZED_APP_ENTRY) {
222      AuthorizedAppManagementPage({
223        sheetParam: this.sheetParam
224      })
225    } else if (name === NavEntryKey.CRED_PWD_INPUT_ENTRY) {
226      CredPwdInputPage({
227        sheetParam: this.sheetParam
228      })
229    }
230  }
231
232  build() {
233    Column() {
234      Column() {
235      }.bindSheet(true, this.buildContent(), {
236        height: SheetSize.FIT_CONTENT,
237        preferType: ['2in1', 'tablet'].includes(deviceInfo.deviceType) ? SheetType.CENTER : null,
238        showClose: true,
239        onTypeDidChange: (type) => {
240          this.sheetParam.sheetType = type;
241          console.log(TAG + 'sheet type:' + this.sheetParam.sheetType);
242          if (this.rootHeight === 0) {
243            return;
244          }
245          this.updateSheetHeightLimit();
246        },
247        onDisappear: () => {
248          console.debug(TAG + 'Sheet page disappear, session is undefined?' + (this.sheetSession === undefined));
249          this.sheetSession?.sendData({'action': 'exit'})
250        }
251      })
252    }
253    .width(WidthPercent.WH_100_100)
254    .height(WidthPercent.WH_100_100)
255    .onAreaChange((oldArea, newArea) => {
256      this.rootWidth = newArea.width as number;
257      this.rootHeight = newArea.height as number;
258      this.updateSheetHeightLimit();
259    })
260  }
261
262  @Builder
263  private buildContent() {
264    Navigation(this.stack) {
265      if (this.pageType === PAGE_CA_CERTIFICATE) {
266        this.buildCaCertPage()
267      } else if (this.pageType === PAGE_CREDENTIAL) {
268        this.buildCredListPage()
269      } else if (this.pageType === PAGE_INSTALL_CERTIFICATE) {
270        this.buildInstallPage()
271      } else {
272        this.buildHomePage()
273      }
274    }
275    .hideTitleBar(true)
276    .titleMode(NavigationTitleMode.Mini)
277    .mode(NavigationMode.Stack)
278    .navDestination(this.routerMap)
279    .width(WidthPercent.WH_100_100)
280    .height(WidthPercent.WH_AUTO)
281    .constraintSize({
282      maxHeight: this.maxSheetPageHeight
283    })
284    .backgroundColor($r('sys.color.background_secondary'))
285  }
286
287  @Builder
288  private buildHomePage() {
289    Column() {
290      CertificateComponent({
291        isStartBySheet: true,
292        sheetParam: this.sheetParam,
293        selected: (path) => {
294          if (path === undefined || path === null || path.length === 0) {
295            console.warn(TAG + 'buildHomePage, empty path');
296            return;
297          }
298          this.stack.pushPath(new NavPathInfo(path, ''));
299        }
300      })
301    }
302    .width(WidthPercent.WH_100_100)
303    .height(WidthPercent.WH_AUTO)
304  }
305
306  @Builder
307  private buildCaCertPage() {
308    Column() {
309      TrustedEvidence({
310        isStartBySheetFirst: true,
311        isStartBySheet: true,
312        sheetParam: this.sheetParam,
313        selected: (path, param) => {
314          if (path === undefined || path === null || path.length === 0) {
315            console.warn(TAG + 'buildCaCertPage, empty path');
316            return;
317          }
318          if (path === NavEntryKey.POP) {
319            this.stack?.pop();
320          } else {
321            this.stack?.pushPath(new NavPathInfo(path, param));
322          }
323        }
324      })
325    }
326    .width(WidthPercent.WH_100_100)
327    .height(WidthPercent.WH_AUTO)
328  }
329
330  @Builder
331  private buildCredListPage() {
332    Column() {
333      evidenceList({
334        isStartBySheetFirst: true,
335        isStartBySheet: true,
336        sheetParam: this.sheetParam,
337        selected: (path, param) => {
338          if (path === undefined || path === null || path.length === 0) {
339            console.warn(TAG + 'buildCredListPage, empty path');
340            return;
341          }
342          if (path === NavEntryKey.POP) {
343            this.stack?.pop();
344          } else {
345            this.stack?.pushPath(new NavPathInfo(path, param));
346          }
347        }
348      })
349    }
350    .width(WidthPercent.WH_100_100)
351    .height(WidthPercent.WH_AUTO)
352  }
353
354  @Builder
355  private buildInstallPage() {
356    Column() {
357      CertInstallFromStorage({
358        isStartBySheetFirst: true,
359        isStartBySheet: true,
360        sheetParam: this.sheetParam,
361        selected: (path, param) => {
362          if (path === undefined || path === null || path.length === 0) {
363            console.warn(TAG + 'buildInstallPage, empty path');
364            return;
365          }
366          if (path === NavEntryKey.POP) {
367            this.stack?.pop();
368          } else {
369            this.stack?.pushPath(new NavPathInfo(path, param));
370          }
371        }
372      })
373    }
374    .width(WidthPercent.WH_100_100)
375    .height(WidthPercent.WH_AUTO)
376  }
377}