1/*
2 * Copyright (c) 2022-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 { AlbumDefine, BigDataConstants, Constants, Log, ReportToBigDataUtil } from '@ohos/common';
17import wantConstant from '@ohos.ability.wantConstant';
18import { SelectParams } from '../utils/ThirdSelectConstants';
19import ability from '@ohos.ability.ability';
20import common from '@ohos.app.ability.common';
21import Want from '@ohos.app.ability.Want';
22import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
23import fileShare from '@ohos.fileshare';
24import { BusinessError } from '@ohos.base';
25
26const TAG: string = 'thiSel_CameraGridItemComponent';
27
28@Component
29export struct CameraGridItemComponent {
30  selectParams: SelectParams = SelectParams.defaultParam();
31  resultUri: string = '';
32  @Consume @Watch('onShow') isShow: boolean;
33  updateDataFunc: Function = (): void => {};
34
35  aboutToAppear(): void {
36    Log.info(TAG, `aboutToAppear`);
37  }
38
39  aboutToDisappear(): void {
40    Log.info(TAG, `aboutToDisappear`);
41  }
42
43  build() {
44    Stack() {
45      Column() {
46      }
47      .width('100%')
48      .height('100%')
49      .backgroundColor($r('sys.color.ohos_id_color_primary'))
50      .opacity($r('sys.float.ohos_id_alpha_inapptip_bg'))
51      .onClick((event?: ClickEvent) => {
52        this.jumpCameraTakePhoto().then((result) => {
53          Log.info(TAG, `resourceUri = ${JSON.stringify(result)}`);
54          let want: Want | null = result.want as Want;
55          if (want == null || want.parameters == null) {
56            return;
57          };
58          this.resultUri = want.parameters['resourceUri'] as string;
59        }).catch((err: Error) => {
60          Log.error(TAG, `jumpCameraTakephoto err: ${err}`);
61        });
62      })
63
64      Column() {
65        Image($r('app.media.ic_public_camera_grid_item'))
66          .fillColor($r('sys.color.ohos_id_color_secondary'))
67          .width($r('app.float.camera_icon_size'))
68          .height($r('app.float.camera_icon_size'))
69          .objectFit(ImageFit.Contain)
70        Text(this.selectParams.filterMediaType == AlbumDefine.FILTER_MEDIA_TYPE_VIDEO
71          ? $r('app.string.camera_btn_text_shooting')
72          : $r('app.string.camera_btn_text_photo')
73        )
74          .fontSize($r('sys.float.ohos_id_text_size_body3'))
75          .fontFamily($r('app.string.id_text_font_family_regular'))
76          .fontColor($r('sys.color.ohos_id_color_text_secondary'))
77          .fontWeight(FontWeight.Regular)
78          .margin({
79            top: $r('app.float.photo_grid_gap')
80          })
81      }
82      .key('PickerCamera')
83      .justifyContent(FlexAlign.Center)
84      .alignItems(HorizontalAlign.Center)
85      .hitTestBehavior(HitTestMode.Transparent)
86    }
87    .width('100%')
88    .aspectRatio(1)
89  }
90
91  private onShow(): void {
92    Log.info(TAG, `onShow: isShow=${this.isShow}, uri=${this.resultUri}`);
93    if (this.isShow && this.resultUri?.length > 0) {
94      if (this.selectParams.isMultiPick) {
95        this.updateDataFunc && this.updateDataFunc(this.resultUri);
96      } else {
97        this.setPickResult(this.resultUri);
98      }
99    }
100  }
101
102  private async jumpCameraTakePhoto(): Promise<ability.AbilityResult> {
103    let action = this.selectParams.filterMediaType == AlbumDefine.FILTER_MEDIA_TYPE_VIDEO
104      ? wantConstant.Action.ACTION_VIDEO_CAPTURE
105      : wantConstant.Action.ACTION_IMAGE_CAPTURE;
106    let uri = this.selectParams.filterMediaType == AlbumDefine.FILTER_MEDIA_TYPE_VIDEO
107      ? Constants.CAMERA_TYPE_VIDEO
108      : Constants.CAMERA_TYPE_CAPTURE;
109    interface Msg {
110      action: wantConstant.Action
111    }
112    let msg: Msg = {
113      action: action
114    }
115    ReportToBigDataUtil.report(BigDataConstants.SELECT_PICKER_CLICK_CAMERA_ID, msg);
116
117    let supportMultiMode: boolean = (this.selectParams.filterMediaType == AlbumDefine.FILTER_MEDIA_TYPE_ALL);
118    let want: Want = {
119      action: action,
120      bundleName: Constants.CAMERA_BUNDLE_NAME,
121      parameters: {
122        uri: uri,
123        supportMultiMode: supportMultiMode,
124        callBundleName: this.selectParams.bundleName
125      }
126    };
127
128    Log.debug(TAG, `jump camera want: ${JSON.stringify(want)}`);
129    let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext;
130    let result = await context.startAbilityForResult(want);
131    return result;
132  }
133
134  private setPickResult(uri: string): void {
135    if (uri == null || uri == undefined) {
136      Log.error(TAG, `no valid uri!`);
137      return;
138    }
139    let abilityResult: ability.AbilityResult = {
140      resultCode: (uri == null || uri.length <= 0) ? -1 : 0,
141      want: {
142        parameters: {
143          'select-item-list': [uri],
144        }
145      }
146    };
147    let storage = LocalStorage.getShared();
148    if (storage?.has(Constants.PHOTO_PICKER_SESSION_KEY)) {
149      let session = storage?.get<UIExtensionContentSession>(Constants.PHOTO_PICKER_SESSION_KEY);
150      let param = storage?.get<SelectParams>(Constants.PHOTO_PICKER_PARAMS_KEY);
151      try {
152        if (param?.bundleName) {
153          Log.debug(TAG, `grantUriPermission to ${param?.bundleName}`);
154          fileShare.grantUriPermission(uri,
155            param?.bundleName,
156            wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION,
157            (err: BusinessError):void => {
158              Log.error(TAG, `failed to grantUriPermission to ${param?.bundleName}`);
159              session?.terminateSelfWithResult(abilityResult).then((result: void) => {
160                Log.info(TAG, `session terminateSelfWithResult abilityResult: ${abilityResult} result: ${result}`);
161              });
162          });
163        }
164      } catch (err) {
165        Log.error(TAG, `err: ${JSON.stringify(err)}`);
166        session?.terminateSelfWithResult(abilityResult).then((result: void) => {
167          Log.info(TAG, `session terminateSelfWithResult abilityResult: ${abilityResult} result: ${result}`);
168        });
169      }
170    } else {
171      let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext;
172      context.terminateSelfWithResult(abilityResult as ability.AbilityResult).then((result: void) => {
173        Log.info(TAG, `terminateSelfWithResult abilityResult: ${abilityResult} result: ${result}`);
174      });
175    }
176  }
177}
178