• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2023 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 { backBar } from '../common/components/backBar';
17import { alphabetIndexerComponent } from '../common/components/alphabeticalIndex';
18import { textInput } from '../common/components/search';
19import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
20import display from '@ohos.display';
21import common from '@ohos.app.ability.common';
22import { groups, globalGroup, showSubPermissionsGroup } from '../common/model/permissionGroup';
23import {
24  Log,
25  indexValue,
26  addLocalTag,
27  sortByName,
28  supportPermission,
29  getPermissionGroup,
30  getGroupIdByPermission,
31  getPermissionGroupByName
32} from '../common/utils/utils';
33import { AppInfo, PermissionApplications, GroupPermission, GroupInfo } from '../common/model/typedef';
34import { GlobalContext } from '../common/utils/globalContext';
35import { Permission, PermissionGroup } from '../common/model/definition';
36import { GlobalDialogModel } from '../GlobalExtAbility/GlobalDialogModel';
37import Constants from '../common/utils/constant';
38import bundleManager from '@ohos.bundle.bundleManager';
39
40@Extend(Image)function customizeImage(width: number, height: number) {
41  .objectFit(ImageFit.Contain)
42  .width(width)
43  .height(height)
44  .draggable(false)
45};
46
47@Entry({ useSharedStorage: true })
48@Component
49struct authorityManagementPage {
50  @Builder ListItemLayout(item: GroupPermission) {
51    ListItem() {
52      Row() {
53        Column() {
54          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
55            Row() {
56              Image(item.icon)
57                .fillColor($r('sys.color.icon_secondary'))
58                .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
59                .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
60              Text(item.groupName)
61                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
62                .fontWeight(FontWeight.Medium)
63                .fontColor($r('sys.color.font_primary'))
64                .flexGrow(Constants.FLEX_GROW)
65              SymbolGlyph($r('sys.symbol.chevron_forward'))
66                .width(Constants.IMAGE_WIDTH)
67                .height(Constants.IMAGE_HEIGHT)
68                .fontSize(Constants.FONT_SIZE_18_vp)
69                .fontColor([$r('sys.color.icon_tertiary')])
70                .fontWeight(FontWeight.Medium)
71            }
72            .width(Constants.FULL_WIDTH)
73            .height(Constants.MANAGEMENT_ROW_HEIGHT)
74          }
75        }.onClick(() => {
76          if (item.group === 'OTHER' || showSubPermissionsGroup.indexOf(item.group) !== -1) {
77            this.getUIContext().getRouter().pushUrl({
78              url: 'pages/authority-secondary',
79              params: { list: this.allPermissionApplications, backTitle: item.groupName, group: item.group }
80            })
81          } else {
82            let dataList = this.allPermissionApplications.filter((ele) => {
83              return ele.groupName === item.group;
84            })
85
86            GlobalContext.store('currentPermissionGroup', item.group);
87            if (globalGroup.indexOf(item.group) == -1) {
88              this.getUIContext().getRouter().pushUrl({
89                url: 'pages/authority-tertiary-groups',
90                params: { list: dataList, backTitle: item.groupName }
91              })
92            } else {
93              GlobalDialogModel.getInstance().getMuteStateAndGoto(
94                this.getUIContext(), item.group, item.groupName, dataList
95              );
96            }
97          }
98        })
99      }
100    }.padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') })
101    .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
102    .linearGradient((this.isTouch === item.group) ? {
103        angle: 90,
104        direction: GradientDirection.Right,
105        colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
106      } : {
107        angle: 90,
108        direction: GradientDirection.Right,
109        colors: [[$r('sys.color.comp_background_list_card'), 1], [$r('sys.color.comp_background_list_card'), 1]]
110      })
111    .onTouch(event => {
112      if (event === undefined) {
113        return;
114      }
115      if (event.type === TouchType.Down) {
116        this.isTouch = item.group;
117      }
118      if (event.type === TouchType.Up) {
119        this.isTouch = '';
120      }
121    })
122  }
123
124  private context = this.getUIContext().getHostContext() as common.UIAbilityContext;
125  @LocalStorageLink('initialGroups') initialGroups: bundleManager.BundleInfo[] = [];
126  @State allPermissionApplications: PermissionApplications [] = []; // All app permissions
127  @State allGroupPermission: GroupPermission[] = []; // All group permissions
128  @State allUserPermissions: Permission[] = [];
129  @State allBundleInfo: AppInfo[] = [];
130  @State allGroups: PermissionGroup[] = [];
131  @State currentIndex: number = 0;
132  @State isTouch: string = '';
133  @State isVertical: boolean = true;
134  @Builder TabBuilder(index: number) {
135    Flex({
136      alignItems: index ? ItemAlign.Start : ItemAlign.End,
137      justifyContent: FlexAlign.Center, direction: FlexDirection.Column
138    }) {
139      Text(index ? $r('app.string.application') : $r('app.string.permission'))
140        .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
141        .fontColor(
142          this.currentIndex == index ?
143          $r('sys.color.ohos_id_color_subtab_text_on') :
144          $r('sys.color.icon_secondary')
145        )
146        .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular)
147        .lineHeight(Constants.TEXT_LINE_HEIGHT)
148        .baselineOffset(Constants.TAB_DECORATION_POSITION_Y)
149      if (this.currentIndex == index) {
150        Text(index ? $r('app.string.application') : $r('app.string.permission'))
151          .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
152          .fontWeight(FontWeight.Bold)
153          .lineHeight(Constants.TAB_LINE_HEIGHT)
154          .height(Constants.TAB_DECORATION_HEIGHT)
155          .fontColor($r('sys.color.ohos_id_color_subtab_text_on'))
156          .backgroundColor($r('sys.color.ohos_id_color_subtab_text_on'))
157      }
158    }.height(Constants.TAB_HEIGHT)
159    .width(Constants.FULL_WIDTH)
160    .padding({ left: this.isVertical ? Constants.TAB_INNER_PADDING : Constants.DEFAULT_PADDING_START,
161      right: this.isVertical ? Constants.TAB_INNER_PADDING : Constants.DEFAULT_PADDING_END })
162  }
163
164  /**
165   * Get all app permission information
166   */
167  async getAllBundlePermissions() {
168    for (let i = 0; i < this.initialGroups.length; i++) {
169      await this.deduplicationPermissions(this.initialGroups[i]);
170    }
171    this.getAllGroupPermission();
172    this.getAllPermissionApplications();
173    this.getLabelAndIcon();
174    GlobalContext.store('allBundleInfo', this.allBundleInfo);
175  }
176
177  /**
178   * Get all permission label
179   */
180  getLabelAndIcon() {
181    this.allBundleInfo.forEach((bundleInfo: AppInfo) => {
182      this.updateAppLabel(bundleInfo);
183      this.updateAppIcon(bundleInfo);
184    })
185  }
186
187  /**
188   * Get all app permission information
189   */
190  getAllPermissionApplications() {
191    for (let i = 0; i < this.allUserPermissions.length; i++) {
192      let permission: Permission = this.allUserPermissions[i];
193      let permissionGroup: GroupInfo = getPermissionGroup(permission);
194      let icon: ResourceStr = permissionGroup.icon;
195      let bundleNames: string[] = [];
196      for (let j = 0; j < this.allBundleInfo.length; j++) {
197        if (this.allBundleInfo[j].permissions.indexOf(permission) != -1) {
198          bundleNames.push(this.allBundleInfo[j].bundleName);
199        }
200      }
201      let pa: PermissionApplications = new PermissionApplications(permission, permissionGroup.name, bundleNames, icon);
202      this.allPermissionApplications.push(pa);
203    }
204  }
205
206  /**
207   * Get permission group information
208   */
209  getAllGroupPermission() {
210    groups.forEach((item) => {
211      if (item.isShow) {
212        this.allGroups.push(item.name);
213      }
214    })
215    this.allUserPermissions.forEach((userPermission: Permission) => {
216      let groupId = getGroupIdByPermission(userPermission);
217      if (this.allGroups.indexOf(groups[groupId].name) == -1) {
218        this.allGroups.push(groups[groupId].name);
219      }
220    })
221    // Permission layout
222    for (let i = 0; i < this.allGroups.length; i++) {
223      let group = getPermissionGroupByName(this.allGroups[i]);
224      let gp: GroupPermission = new GroupPermission(
225        this.allGroups[i], group.permissions, group.groupName, group.icon, group.isShow
226      );
227      this.allGroupPermission.push(gp);
228    }
229  }
230
231  /**
232   * Deduplicate permission information and permission group information
233   * @param {Object} info bundleInfos Application Information
234   */
235  async deduplicationPermissions(info: bundleManager.BundleInfo) {
236    Log.info('allBundleInfo start: ' + info.name);
237    let reqPermissions: Permission[] = [];
238    info.reqPermissionDetails.forEach(item => {
239      reqPermissions.push(item.name as Permission);
240    })
241    let reqPermissionsLen = reqPermissions.length;
242    let reqUserPermissions: Permission[] = [];
243    let acManager = abilityAccessCtrl.createAtManager()
244    if (reqPermissionsLen > 0) {
245      for (let j = 0; j < reqPermissions.length; j++) {
246        let permission = reqPermissions[j];
247        if ((permission == Permission.LOCATION) && !reqPermissions.includes(Permission.APPROXIMATELY_LOCATION)) {
248          continue;
249        }
250        try {
251          let flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission);
252          if (flag == Constants.PERMISSION_SYSTEM_FIXED) {
253            continue;
254          }
255        } catch (err) {
256          Log.error('getPermissionFlags error: ' + JSON.stringify(err));
257        }
258        let supportPermissions = supportPermission();
259        if (supportPermissions.indexOf(permission) != -1) {
260          reqUserPermissions.push(permission);
261          if (this.allUserPermissions.indexOf(permission) == -1) {
262            this.allUserPermissions.push(permission);
263          }
264        }
265      }
266    }
267    this.getAllBundleInfo(info, reqUserPermissions);
268  }
269
270  getAllBundleInfo(info: bundleManager.BundleInfo, reqUserPermissions: Permission[]) {
271    let groupIds: number[] = [];
272    for (let i = 0; i < reqUserPermissions.length; i++) {
273      let groupId = getGroupIdByPermission(reqUserPermissions[i])
274      if (groupIds.indexOf(groupId) == -1) {
275        groupIds.push(groupId);
276      }
277    }
278
279    let ap: AppInfo = new AppInfo(
280      info.name,
281      info.targetVersion,
282      info.appInfo.accessTokenId,
283      '',
284      info.appInfo.iconId,
285      info.appInfo.iconResource,
286      info.appInfo.label,
287      info.appInfo.labelId,
288      info.appInfo.labelResource,
289      reqUserPermissions,
290      groupIds,
291      '',
292      '',
293      ''
294    );
295    Log.info('allBundleInfo.push: ' + info.name);
296    this.allBundleInfo.push(ap);
297  }
298
299  /**
300   * Get app name resource
301   * @param {Number} index index of all app permissions array
302   * @param {String} bundleName Package names
303   * @param {String} labelName Application Name
304   */
305  async updateAppLabel(info: AppInfo) {
306    Log.info(
307      'bundleName: ' + info.bundleName +
308      ` labelResource: ` + JSON.stringify(info.labelResource) +
309      ' labelId: ' + info.labelId
310    );
311
312    try {
313      if (info.labelResource.id !== 0) {
314        info.label = await this.context.resourceManager.getStringValue(info.labelResource);
315      } else {
316        let resourceManager = this.context.createBundleContext(info.bundleName).resourceManager;
317        info.label = await resourceManager.getStringValue(info.labelId);
318      }
319    } catch (error) {
320      Log.error('getStringValue promise error is ' + error);
321    }
322    addLocalTag(info);
323  }
324
325  /**
326   * Get app icon resources
327   * @param {Number} index index of all app permissions array
328   * @param {String} bundleName Package names
329   */
330  async updateAppIcon(info: AppInfo) {
331    Log.info(
332      'bundleName: ' + info.bundleName +
333      ` iconResource: ` + JSON.stringify(info.iconResource) +
334      ' iconId: ' + info.iconId
335    );
336
337    try {
338      if (info.iconResource.id !== 0) {
339        let iconDescriptor = this.context.resourceManager.getDrawableDescriptor(info.iconResource);
340        info.icon = iconDescriptor?.getPixelMap();
341      } else {
342        let resourceManager = this.context.createBundleContext(info.bundleName).resourceManager;
343        let iconDescriptor = resourceManager.getDrawableDescriptor(info.iconId);
344        info.icon = iconDescriptor?.getPixelMap();
345      }
346    } catch (error) {
347      Log.error(`getDrawableDescriptor failed, error code: ${error.code}, message: ${error.message}.`);
348    }
349
350    if (!info.icon) {
351      info.icon = $r('app.media.icon');
352    }
353  }
354
355  /**
356   * Lifecycle function, executed when the page is initialized
357   */
358  aboutToAppear() {
359    this.getAllBundlePermissions();
360    try {
361      let dis = display.getDefaultDisplaySync();
362      this.isVertical = dis.height > dis.width ? true : false;
363      GlobalContext.store('isVertical', dis.height > dis.width ? true : false);
364    } catch (error) {
365      Log.error(`getDefaultDisplaySync failed. ${JSON.stringify(error)}`);
366    }
367  }
368
369  getPermissionGroup(allGroup: GroupPermission[], order: number): GroupPermission[] {
370    let fixedName: string[] = ['LOCATION', 'CAMERA', 'MICROPHONE'];
371    let extraName: string[] = ['ADS'];
372    let fixedGroup: GroupPermission[] = [];
373    let extraGroup: GroupPermission[] = [];
374    let changeGroup: GroupPermission[] = [];
375    let otherGroup: GroupPermission[] = [];
376
377    allGroup.forEach(group => {
378      if (fixedName.indexOf(group.group) !== -1) {
379        fixedGroup.push(group);
380      } else if (extraName.includes(group.group)) {
381        extraGroup.push(group);
382      } else if (group.group == 'OTHER') {
383        otherGroup.push(group);
384      } else {
385        changeGroup.push(group);
386      }
387    })
388
389    if (order == Constants.FIXED_GROUP) {
390      return fixedGroup;
391    } else if (order == Constants.CHANGE_GROUP) {
392      return changeGroup;
393    } else if (order == Constants.OTHER_GROUP) {
394      return otherGroup;
395    } else if (order == Constants.EXTRA_GROUP) {
396      return extraGroup;
397    }
398    return [];
399  }
400
401  build() {
402    GridRow({ gutter: Constants.GUTTER, columns: {
403      xs: Constants.XS_COLUMNS, sm: Constants.SM_COLUMNS, md: Constants.MD_COLUMNS, lg: Constants.LG_COLUMNS } }) {
404      GridCol({
405        span: { xs: Constants.XS_SPAN, sm: Constants.SM_SPAN, md: Constants.MD_SPAN, lg: Constants.LG_SPAN },
406        offset: { xs: Constants.XS_OFFSET, sm: Constants.SM_OFFSET, md: Constants.MD_OFFSET, lg: Constants.LG_OFFSET }
407      }) {
408        Row() {
409          Column() {
410            Row() {
411              backBar( { title: JSON.stringify($r('app.string.permission_manager')), recordable: true })
412            }
413            Row() {
414              Column() {
415                Column() {
416                  Stack() {
417                    if (this.allGroupPermission.length) {
418                      Tabs() {
419                        TabContent() {
420                          Row() {
421                            Column() {
422                              Scroll() {
423                                Column() {
424                                  List() {
425                                    ListItem() {
426                                      List() {
427                                        ForEach(
428                                          this.getPermissionGroup(this.allGroupPermission, Constants.FIXED_GROUP),
429                                          (item: GroupPermission) => { this.ListItemLayout(item) },
430                                          (item: GroupPermission) => JSON.stringify(item)
431                                        )
432                                      }.backgroundColor($r('sys.color.comp_background_list_card'))
433                                      .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
434                                      .padding(Constants.LIST_PADDING_TOP)
435                                      .margin({ bottom: Constants.LIST_MARGIN_BOTTOM })
436                                      .divider({
437                                        strokeWidth: Constants.DIVIDER,
438                                        color: $r('sys.color.comp_divider'),
439                                        startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION,
440                                        endMargin: Constants.DEFAULT_MARGIN_END
441                                      })
442                                    }
443
444                                    ListItem() {
445                                      List() {
446                                        ForEach(
447                                          this.getPermissionGroup(this.allGroupPermission, Constants.CHANGE_GROUP),
448                                          (item: GroupPermission) => { this.ListItemLayout(item) },
449                                          (item: GroupPermission) => JSON.stringify(item)
450                                        )
451                                      }.backgroundColor($r('sys.color.comp_background_list_card'))
452                                      .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
453                                      .padding(Constants.LIST_PADDING_TOP)
454                                      .margin({ bottom: Constants.LIST_MARGIN_BOTTOM })
455                                      .divider({
456                                        strokeWidth: Constants.DIVIDER,
457                                        color: $r('sys.color.comp_divider'),
458                                        startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION,
459                                        endMargin: Constants.DEFAULT_MARGIN_END
460                                      })
461                                    }
462
463                                    if (
464                                      this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP).length
465                                    ) {
466                                      ListItem() {
467                                        List() {
468                                          ForEach(
469                                            this.getPermissionGroup(this.allGroupPermission, Constants.EXTRA_GROUP),
470                                            (item: GroupPermission) => { this.ListItemLayout(item) },
471                                            (item: GroupPermission) => JSON.stringify(item)
472                                          )
473                                        }.backgroundColor($r('sys.color.comp_background_list_card'))
474                                        .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
475                                        .padding(Constants.LIST_PADDING_TOP)
476                                        .margin({ bottom: Constants.LIST_MARGIN_BOTTOM })
477                                        .divider({
478                                          strokeWidth: Constants.DIVIDER,
479                                          color: $r('sys.color.comp_divider'),
480                                          startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION,
481                                          endMargin: Constants.DEFAULT_MARGIN_END
482                                        })
483                                      }
484                                    }
485
486                                    ListItem() {
487                                      List() {
488                                        ForEach(
489                                          this.getPermissionGroup(this.allGroupPermission, Constants.OTHER_GROUP),
490                                          (item: GroupPermission) => { this.ListItemLayout(item) },
491                                          (item: GroupPermission) => JSON.stringify(item)
492                                        )
493                                      }.backgroundColor($r('sys.color.comp_background_list_card'))
494                                      .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
495                                      .padding(Constants.LIST_PADDING_TOP)
496                                      .divider({
497                                        strokeWidth: Constants.DIVIDER,
498                                        color: $r('sys.color.comp_divider'),
499                                        startMargin: Constants.DIVIDER_MARGIN_RIGHT_PERMISSION,
500                                        endMargin: Constants.DEFAULT_MARGIN_END
501                                      })
502                                    }.margin({ bottom: Constants.AUTHORITY_ROW_MARGIN_BOTTOM })
503                                  }.height(Constants.FULL_HEIGHT)
504                                  .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
505                                  .clip(true)
506                                }.padding({
507                                  left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
508                                  right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
509                                })
510                              }.scrollBar(BarState.Off)
511                              .margin({ top: Constants.MANAGEMENT_ROW_PADDING_TOP })
512                            }.width(Constants.FULL_WIDTH)
513                          }
514                        }.tabBar(this.TabBuilder(0))
515                        TabContent() {
516                          applicationItem()
517                        }.tabBar(this.TabBuilder(1))
518                      }
519                      .barMode(BarMode.Fixed)
520                      .barWidth(Constants.BAR_WIDTH)
521                      .onChange((index) => {
522                        this.currentIndex = index
523                      })
524                    } else {
525                      LoadingProgress().width(Constants.LOADING_WIDTH)
526                    }
527                  }.height(Constants.FULL_HEIGHT)
528                }
529              }
530            }
531            .layoutWeight(Constants.LAYOUT_WEIGHT)
532          }
533        }
534        .height(Constants.FULL_HEIGHT)
535        .width(Constants.FULL_WIDTH)
536        .backgroundColor($r('sys.color.background_secondary'))
537      }
538    }.backgroundColor($r('sys.color.background_secondary'))
539  }
540}
541
542@Component
543struct applicationItem {
544  @State applicationItem: AppInfo[] = GlobalContext.load('allBundleInfo'); // application info array
545  @State searchResult: boolean = true; // search results
546  @State selectedIndex: number = 0;
547  @State isTouch: string = '';
548  scroller: Scroller = new Scroller();
549
550  @Builder ListItemLayout(item: AppInfo) {
551    ListItem() {
552      Row() {
553        Column() {
554          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
555            Row() {
556              Image(item.icon)
557                .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
558                .margin({ right: Constants.APPLICATION_IMAGE_MARGIN_RIGHT })
559              Text(item.label)
560                .width(Constants.OFFSET)
561                .maxLines(Constants.MAXIMUM_HEADER_LINES)
562                .textOverflow({ overflow: TextOverflow.Ellipsis })
563                .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
564                .fontWeight(FontWeight.Medium)
565                .fontColor($r('sys.color.font_primary'))
566                .flexGrow(Constants.FLEX_GROW)
567              Text(String(item.groupId.length))
568                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
569                .fontColor($r('sys.color.font_secondary'))
570              Text($r('app.string.right'))
571                .fontSize(Constants.TEXT_SMALL_FONT_SIZE)
572                .fontColor($r('sys.color.font_secondary'))
573                .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT })
574              SymbolGlyph($r('sys.symbol.chevron_forward'))
575                .width(Constants.IMAGE_WIDTH)
576                .height(Constants.IMAGE_HEIGHT)
577                .fontSize(Constants.FONT_SIZE_18_vp)
578                .fontColor([$r('sys.color.icon_tertiary')])
579                .fontWeight(FontWeight.Medium)
580            }
581            .width(Constants.FULL_WIDTH)
582            .height(Constants.AUTHORITY_ROW_HEIGHT)
583            .constraintSize({ minHeight: Constants.AUTHORITY_CONSTRAINTSIZE_MINHEIGHT })
584          }
585        }.onClick(() => {
586          GlobalContext.store('applicationInfo', item);
587          this.getUIContext().getRouter().pushUrl({ url: 'pages/application-secondary' });
588        })
589      }
590    }.padding({ left: $r('sys.float.ohos_id_card_margin_start'), right: $r('sys.float.ohos_id_card_margin_end') })
591    .borderRadius($r('sys.float.ohos_id_corner_radius_default_l'))
592    .linearGradient((this.isTouch === item.bundleName) ? {
593         angle: 90,
594         direction: GradientDirection.Right,
595         colors: [['#DCEAF9', 0.0], ['#FAFAFA', 1.0]]
596       } : {
597         angle: 90,
598         direction: GradientDirection.Right,
599         colors: [[$r('sys.color.comp_background_list_card'), 1], [$r('sys.color.comp_background_list_card'), 1]]
600       })
601    .onTouch(event => {
602      if (event === undefined) {
603        return;
604      }
605      if (event.type === TouchType.Down) {
606        this.isTouch = item.bundleName;
607      }
608      if (event.type === TouchType.Up) {
609        this.isTouch = '';
610      }
611    })
612  }
613
614  build() {
615    Column() {
616      Row() {
617        textInput({
618          applicationItem: $applicationItem,
619          searchResult: $searchResult
620        })
621      }.padding({
622        left: Constants.APPLICATION_TEXTINPUT_PADDING_LEFT,
623        top: Constants.APPLICATION_TEXTINPUT_PADDING_TOP,
624        right: Constants.APPLICATION_TEXTINPUT_PADDING_RIGHT
625      })
626      Row() {
627        Flex({ alignItems: ItemAlign.Start }) {
628          Column() {
629            Column() {
630              if (!this.applicationItem.length) {
631                Row() {
632                  Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
633                    Image($r('app.media.searchnoresult'))
634                      .customizeImage(Constants.SEARCHNORESULT_IMAGE_WIDTH, Constants.SEARCHNORESULT_IMAGE_HEIGHT)
635                  }
636                }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP })
637                .padding({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT })
638              } else {
639                Row() {
640                  List({ scroller: this.scroller }) {
641                    ForEach(sortByName(this.applicationItem), (item: AppInfo) => {
642                      this.ListItemLayout(item)
643                    }, (item: AppInfo) => JSON.stringify(item))
644                  }.backgroundColor($r('sys.color.comp_background_list_card'))
645                  .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
646                  .padding(Constants.LIST_PADDING_TOP)
647                  .divider({
648                    strokeWidth: Constants.DIVIDER,
649                    color: $r('sys.color.comp_divider'),
650                    startMargin: Constants.DIVIDER_MARGIN_RIGHT_APPLICATION,
651                    endMargin: Constants.DEFAULT_MARGIN_END
652                  })
653                  .onScrollIndex((start, end) => {
654                    GlobalContext.getContext().set('scroller', this.scroller);
655                    if (this.applicationItem.length > 0) {
656                      let alphabeticalIndex = sortByName(this.applicationItem)[start].indexTag;
657                      let index = indexValue.indexOf(alphabeticalIndex);
658                      this.selectedIndex = index >= 0 ? index : 0;
659                    }
660                  })
661                }.margin({ left: Constants.MANAGEMENT_ROW_PADDING_LEFT })
662                .borderRadius($r('sys.float.ohos_id_corner_radius_card'))
663                .clip(true)
664              }
665            }.height(Constants.FULL_HEIGHT)
666          }.margin({ top: Constants.MANAGEMENT_ROW_MARGIN_TOP, bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM })
667          Column() {
668            alphabetIndexerComponent({ applicationItem: $applicationItem, index: $selectedIndex })
669          }
670          .margin({
671            top: Constants.APPLICATION_ALPHABETINDEX_MARGIN_TOP,
672            bottom: Constants.APPLICATION_LIST_MARGIN_BOTTOM
673          })
674          .width(Constants.APPLICATION_ALPHABETINDEX_WIDTH)
675        }
676      }
677    }
678  }
679}