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