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