• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 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 display from '@ohos.display';
17import deviceInfo from '@ohos.deviceInfo';
18import { ModeMap } from '../common/ModeMap';
19import { Action } from '@ohos/common/src/main/ets/default/redux/actions/Action';
20import { CameraWorker } from '@ohos/common/src/main/ets/default/worker/CameraWorker';
21import { EventBus } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBus';
22import { EventBusManager } from '@ohos/common/src/main/ets/default/worker/eventbus/EventBusManager';
23import { Dispatch, OhCombinedState } from '@ohos/common/src/main/ets/default/redux/store';
24import { getStore } from '@ohos/common/src/main/ets/default/redux/store';
25import { Log } from '@ohos/common/src/main/ets/default/utils/Log';
26import { MoreList } from '@ohos/common/src/main/ets/default/featurecommon/moreList/moreList';
27import {
28  PersistType,
29  PreferencesService
30} from '@ohos/common/src/main/ets/default/featurecommon/preferences/PreferencesService';
31import { RdbStoreManager } from '@ohos/common/src/main/ets/default/setting/storage/RdbStoreManager';
32import { TabBar } from '@ohos/common/src/main/ets/default/featurecommon/tabbar/TabBar';
33import { ZoomView } from '@ohos/common/src/main/ets/default/featurecommon/zoomview/ZoomView';
34import { Control } from './Control';
35import { FootBar } from './FootBar';
36import { PreviewArea } from './PreviewArea';
37import { SettingView } from './SettingView';
38import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
39import { CameraId } from '@ohos/common/src/main/ets/default/setting/settingitem/CameraId';
40import { BusinessError } from '@ohos.base';
41import ability from '@ohos.ability.ability';
42import { GlobalContext } from '@ohos/common/src/main/ets/default/utils/GlobalContext';
43
44CameraWorker.getInstance(new ModeMap());
45
46PersistentStorage.PersistProp("storageCameraId", "");
47
48class StateStruct {
49  footBarHeight: number = 0;
50  permissionFlag: boolean = false;
51  mode: string = '';
52  curMode: string = '';
53  isShowtimeLapse: boolean = false;
54  videoState: string = '';
55  isShowMoreList: boolean = false;
56  isThirdPartyCall: boolean = false;
57  showZoomLabelValue: boolean = true;
58  isShowPinch: boolean = false;
59  isShowPageView: boolean = false;
60  isInitiated: boolean = false;
61  curCameraPosition: CameraId = CameraId.BACK
62}
63
64class IndexDispatcher {
65  private mDispatch: Dispatch = (data) => data;
66
67  public setDispatch(dispatch: Dispatch) {
68    this.mDispatch = dispatch;
69  }
70
71  public initFootBarHeight(footBarHeight: number): void {
72    this.mDispatch(Action.initFootBarHeight(footBarHeight));
73  }
74
75  public setPermissionFlag(permissionFlag: boolean): void {
76    Log.info(`CameraApp setPermissionFlag: ${permissionFlag}`);
77    this.mDispatch(Action.setPermissionFlag(permissionFlag));
78  }
79
80  public initAction(action: string): void {
81    this.mDispatch(Action.initAction(action));
82  }
83
84  public initCameraPosition(cameraPosition: string): void {
85    this.mDispatch(Action.setCameraPosition(cameraPosition));
86  }
87
88  public initMode(mode: string): void {
89    this.mDispatch(Action.initMode(mode));
90  }
91
92  public changeTimeLapse(isShowtimeLapse: boolean): void {
93    this.mDispatch(Action.changeTimeLapse(isShowtimeLapse));
94  }
95
96  public stopRecording(): void {
97    this.mDispatch(Action.stopRecording());
98    this.mDispatch(Action.updateVideoState('beforeTakeVideo'));
99    this.mDispatch(Action.updateBigVideoTimerVisible(false));
100    this.mDispatch(Action.updateSmallVideoTimerVisible(false));
101  }
102
103  public resetRecordingTime(): void {
104    this.mDispatch(Action.updateRecordingTime(0));
105    this.mDispatch(Action.updateRecordingTimeDisplay('00:00'));
106  }
107
108  public hideSettingView(): void {
109    this.mDispatch(Action.showSettingView(false));
110  }
111
112  public updateModeIndex(index: number): void {
113    this.mDispatch(Action.updateModeIndex(index));
114  }
115
116  public faCall(isFaCall: boolean): void {
117    this.mDispatch(Action.faCall(isFaCall));
118  }
119
120  public thirdPartyCall(isThirdPartyCall: boolean, action: string): void {
121    this.mDispatch(Action.thirdPartyCall(isThirdPartyCall, action));
122  }
123}
124
125
126@Entry
127@Component
128struct Index {
129  appEventBus: EventBus = EventBusManager.getInstance().getEventBus();
130  @State state: StateStruct = new StateStruct();
131  protected mPreferencesService: PreferencesService = PreferencesService.getInstance();
132  private TAG: string = '[Index]:';
133  private modeArray: Array<string> = ['MULTI', 'PHOTO', 'VIDEO'];
134  private mAction: IndexDispatcher = new IndexDispatcher();
135
136  aboutToAppear(): void {
137    Log.info(`${this.TAG} aboutToAppear E`);
138    let dbStore: RdbStoreManager = RdbStoreManager.getInstance();
139    dbStore.initRdbConfig();
140    getStore().subscribe((state: OhCombinedState) => {
141      this.state = {
142        footBarHeight: state.contextReducer.footBarHeight,
143        permissionFlag: state.contextReducer.permissionFlag,
144        mode: state.modeReducer.mode,
145        curMode: state.modeReducer.curMode,
146        isShowtimeLapse: state.settingReducer.isShowtimeLapse,
147        videoState: state.recordReducer.videoState,
148        isShowMoreList: state.modeReducer.isShowMoreList,
149        isThirdPartyCall: state.contextReducer.isThirdPartyCall,
150        showZoomLabelValue: state.zoomReducer.showZoomLabelValue,
151        isShowPinch: state.zoomReducer.isShowPinch,
152        isShowPageView: state.settingReducer.isShowSettingView,
153        isInitiated: state.modeReducer.isInitiated,
154        curCameraPosition: state.cameraReducer.curCameraPosition,
155      };
156    }, (dispatch: Dispatch) => {
157      this.mAction.setDispatch(dispatch);
158    })
159    display.getDefaultDisplay().then((dis) => {
160      Log.info(`${this.TAG} dis data = ${JSON.stringify(dis)}`);
161      let footBarHeight: number = 0;
162      if (deviceInfo.deviceType === "default") {
163        footBarHeight = px2vp(dis.width) * (4 / 3) - 160;
164      } else {
165        footBarHeight = px2vp(dis.width) * (4 / 3) - 82;
166      }
167      this.mAction.initFootBarHeight(footBarHeight);
168    })
169
170    if (!this.state.permissionFlag) {
171      let permissionList: Array<Permissions> = [
172        "ohos.permission.MEDIA_LOCATION",
173        "ohos.permission.READ_IMAGEVIDEO",
174        "ohos.permission.WRITE_IMAGEVIDEO",
175        "ohos.permission.CAMERA",
176        "ohos.permission.MICROPHONE",
177        "ohos.permission.DISTRIBUTED_DATASYNC",
178        "ohos.permission.LOCATION",
179        "ohos.permission.LOCATION_IN_BACKGROUND",
180        "ohos.permission.APPROXIMATELY_LOCATION"
181      ];
182      Log.info(`${this.TAG} permissions need to require from user: ${JSON.stringify(permissionList)}`);
183      let atManager = abilityAccessCtrl.createAtManager();
184      try {
185        atManager.requestPermissionsFromUser(GlobalContext.get().getCameraAbilityContext(), permissionList).then((data) => {
186          Log.info(`${this.TAG} data permissions: ${JSON.stringify(data.permissions)}`);
187          Log.info(`${this.TAG} data authResult: ${JSON.stringify(data.authResults)}`);
188          let sum = 0
189          for (let i = 0; i < data.authResults.length; i++) {
190            sum += data.authResults[i];
191          }
192          if (sum >= 0) {
193            GlobalContext.get().setObject('permissionFlag', true);
194            this.mAction.setPermissionFlag(true);
195          } else {
196            GlobalContext.get().setObject('permissionFlag', false);
197            this.mAction.setPermissionFlag(false);
198          }
199          Log.info(`${this.TAG} request permissions result: ${GlobalContext.get().getT<boolean>('permissionFlag')}`);
200        }, (err: BusinessError) => {
201          Log.error(`${this.TAG} Failed to start ability err code: ${err.code}`);
202        })
203      } catch (error) {
204        Log.info(`${this.TAG} catch error: ${JSON.stringify(error)}`);
205      }
206    }
207
208    if (GlobalContext.get().getCameraFormParam() != undefined) {
209      this.mAction.initAction(GlobalContext.get().getCameraFormParam().action);
210      this.mAction.initMode(GlobalContext.get().getCameraFormParam().mode);
211      GlobalContext.get().setCameraFormParam(undefined);
212    }
213
214    GlobalContext.get().setObject('stopCameraRecording', () => {
215      this.stopCameraRecording();
216    })
217
218    if (!this.state.isInitiated) {
219      let initIndex: number = this.mPreferencesService.getModeValue(PersistType.FOR_AWHILE, 1);
220      Log.info(`${this.TAG} initModeIndex: ${initIndex}`);
221      this.mAction.initMode(this.modeArray[initIndex]);
222      this.mAction.updateModeIndex(initIndex);
223    }
224
225    Log.info(`${this.TAG} aboutToAppear X`);
226  }
227
228  onPageShow(): void {
229    Log.info(`${this.TAG} onPageShow this.permissionFlag: ${this.state.permissionFlag} permissionFlag: ${GlobalContext.get().getT<boolean>('permissionFlag')}`);
230    this.mAction.setPermissionFlag(GlobalContext.get().getT<boolean>('permissionFlag'));
231    let curCameraId = AppStorage.Get<string>('storageCameraId');
232    if (curCameraId) this.mAction.initCameraPosition(curCameraId);
233    this.mAction.resetRecordingTime();
234    Log.info(`${this.TAG} onPageShow X`);
235  }
236
237  aboutToDisappear(): void {
238    Log.info(`${this.TAG} aboutToDisappear E`);
239  }
240
241  onBackPress(): boolean {
242    Log.info(`${this.TAG} onBackPress E`);
243    if (this.state.isShowPageView) {
244      this.mAction.hideSettingView();
245      return true;
246    } else if (this.state.isShowtimeLapse) {
247      this.mAction.changeTimeLapse(false);
248      return true
249    } else if (this.state.isThirdPartyCall) {
250      this.terminateSelfWithResult();
251    } else {
252      if (this.state.videoState === 'startTakeVideo' || this.state.videoState === 'pauseTakeVideo') {
253        this.mAction.stopRecording();
254        return true;
255      }
256      Log.info(`${this.TAG} onBackPress X`);
257      return false;
258    }
259    return false;
260  }
261
262  onPageHide(): void {
263    Log.info(`${this.TAG} onPageHide E`);
264    this.stopCameraRecording();
265    Log.info(`${this.TAG} onPageHide X`);
266  }
267
268  public stopCameraRecording() {
269    Log.info(`${this.TAG} stopCameraRecording E`);
270    if (this.state.isShowtimeLapse) {
271      this.mAction.changeTimeLapse(false);
272    }
273    if (this.state.videoState === 'startTakeVideo' || this.state.videoState === 'pauseTakeVideo') {
274      this.mAction.stopRecording();
275    }
276    Log.info(`${this.TAG} stopCameraRecording X`);
277  }
278
279  terminateSelfWithResult() {
280    Log.info(`${this.TAG} terminateSelfWithResult start`);
281    let abilityResult: ability.AbilityResult = {
282      "resultCode": 200,
283      "want": {
284        "parameters": {
285          "resourceUri": "",
286          "width": "",
287          "height": ""
288        },
289        "bundleName": "com.ohos.camera",
290        "abilityName": "com.ohos.camera.MainAbility"
291      }
292    };
293
294    GlobalContext.get().getCameraAbilityContext().terminateSelfWithResult(abilityResult, (error:BusinessError) => {
295      if (error) {
296        Log.error(`${this.TAG} Operation failed. Cause: ${error}`);
297        return;
298      }
299      Log.info(`${this.TAG} Operation succeeded`);
300    })
301  }
302
303  build() {
304    Stack({ alignContent: Alignment.Top }) {
305      Stack() {
306        PreviewArea()
307      }.width('100%').position({ y: 48 })
308
309      Stack() {
310        if (deviceInfo.deviceType !== "default" && this.state.videoState === "beforeTakeVideo" && !this.state.isShowtimeLapse && this.state.showZoomLabelValue) {
311          TabBar({ onBackClicked: () => this.onBackClicked() });
312        }
313      }.width('100%').height(48).position({ x: '0', y: '0' })
314
315      if (this.state.isShowMoreList && this.state.showZoomLabelValue) {
316        MoreList()
317      }
318      Stack({ alignContent: Alignment.Bottom }) {
319        Column() {
320          if (this.state.mode === "PHOTO" || this.state.mode === "VIDEO") {
321            if (deviceInfo.deviceType !== "default" && this.state.curCameraPosition !== 'FRONT') {
322              Column() {
323                ZoomView()
324              }
325              .visibility(!this.state.isShowtimeLapse && !this.state.isShowPinch ? Visibility.Visible : Visibility.Hidden)
326            }
327          }
328          if (this.state.videoState === "beforeTakeVideo" && this.state.showZoomLabelValue) {
329            Column() {
330              Control()
331            }
332            .visibility((!this.state.isShowtimeLapse && this.state.showZoomLabelValue) ? Visibility.Visible : Visibility.Hidden)
333            .width('100%')
334          }
335          Column() {
336            FootBar()
337          }
338          .visibility((!this.state.isShowtimeLapse && this.state.showZoomLabelValue) ? Visibility.Visible : Visibility.Hidden)
339        }
340      }.width('100%').height(302).position({ y: this.state.footBarHeight })
341      .visibility(!this.state.isShowtimeLapse ? Visibility.Visible : Visibility.Hidden)
342
343      if (this.state.isShowPageView) {
344        SettingView().width('100%').height('100%')
345      }
346    }.width('100%').height('100%').backgroundColor('#000')
347  }
348
349  private onBackClicked(): void {
350    Log.info(`${this.TAG} onBackClicked E`);
351    this.terminateSelfWithResult();
352  }
353}