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