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