• 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 { Action } from '../redux/actions/Action'
17import { CameraId } from '../setting/settingitem/CameraId'
18import { CameraPlatformCapability } from '../camera/CameraPlatformCapability'
19import { Log } from '../utils/Log'
20import { CameraStatus } from '../utils/Constants'
21import { BaseFunction } from './BaseFunction'
22import { FunctionCallBack } from '../camera/CameraService'
23import EventLog from '../utils/EventLog'
24
25export class CameraBasicFunction extends BaseFunction {
26  private TAG = '[CameraBasicFunction]:'
27
28  private mCameraId: string = CameraId.BACK
29  private mSurfaceId = ''
30  private mCurrentMode = ''
31  private mSessionList = []
32  private isSessionReleasing: boolean = false
33  private initDataCache: any = null
34  public startIdentification: boolean = false
35
36  private functionBackImpl: FunctionCallBack = {
37    onCapturePhotoOutput: (): void => {
38      Log.info(`${this.TAG} functionBackImpl onCapturePhotoOutput`)
39      this.mWorkerManager.postMessage(Action.capturePhotoOutput())
40    },
41    onCaptureSuccess: (thumbnail: any, resourceUri: any): void => {
42      Log.info(`${this.TAG} functionBackImpl onCaptureSuccess ${thumbnail}`)
43      this.mWorkerManager.postMessage(Action.updateThumbnail(thumbnail, resourceUri))
44    },
45    onCaptureFailure: (): void => {
46      Log.info(`${this.TAG} functionBackImpl onCaptureFailure`)
47      this.mWorkerManager.postMessage(Action.captureError())
48    },
49    onRecordSuccess: (thumbnail: any): void => {
50      Log.info(`${this.TAG} functionBackImpl onRecordSuccess ${thumbnail}`)
51      this.mWorkerManager.postMessage(Action.recordDone(thumbnail))
52    },
53    onRecordFailure: (): void => {
54      Log.info(`${this.TAG} functionBackImpl onRecordFailure`)
55      this.mWorkerManager.postMessage(Action.recordError())
56    },
57    thumbnail: (thumbnail: any): void => {
58      Log.info(`${this.TAG} functionBackImpl thumbnail ${thumbnail}`)
59      this.mWorkerManager.postMessage(Action.loadThumbnail(thumbnail))
60    }
61  }
62
63  public async initCamera(data, callType?: string) {
64    globalThis.cameraStatus = CameraStatus.CAMERA_BEGIN_INIT
65    if (this.startIdentification) return;
66    if (callType) this.startIdentification = true
67    Log.start(`${this.TAG} initCamera`)
68    this.mSessionList.push('CREATE')
69    let curStorageCameraId = AppStorage.Get<string>('storageCameraId')
70    if (curStorageCameraId) {
71      data.cameraId = curStorageCameraId
72    }
73    Log.info(`${this.TAG} initData:${JSON.stringify(data)} `)
74    this.initDataCache = data
75    if (globalThis.isSessionCreating || this.isSessionReleasing) {
76      Log.info(`${this.TAG} initCamera isSessionCreating or isSessionReleasing return`)
77      return
78    }
79    this.mCameraId = data.cameraId
80    this.mCurrentMode = data.mode
81    let mCameraCount = await this.mCameraService.initCamera(this.mCameraId)
82    const platformCapability = CameraPlatformCapability.getInstance()
83    await platformCapability.init(mCameraCount)
84    this.mWorkerManager.postMessage(Action.initCameraDone(platformCapability))
85    this.mCameraService.getThumbnail(this.functionBackImpl)
86    globalThis.cameraStatus = CameraStatus.CAMERA_INIT_FINISHED
87    this.mWorkerManager.postMessage(Action.updateCameraStatus())
88    Log.end(`${this.TAG} initCamera`)
89  }
90
91  private async imageSize(data) {
92    Log.info(`${this.TAG} imageSize ${JSON.stringify(data)}  E`)
93    this.mCameraService.mImageSize.imageWidth = data.imageSize.width
94    this.mCameraService.mImageSize.imageHeight = data.imageSize.height
95    Log.info(`${this.TAG} imageSize X`)
96  }
97
98  private async videoSize(data) {
99    Log.info(`${this.TAG} videoSize ${JSON.stringify(data)}  E`)
100    this.mCameraService.mVideoFrameSize.frameWidth = data.videoSize.width
101    this.mCameraService.mVideoFrameSize.frameHeight = data.videoSize.height
102    Log.info(`${this.TAG} videoSize X`)
103  }
104
105  private async onSurfacePrepare(data) {
106    Log.info(`${this.TAG} onSurfacePrepare ${JSON.stringify(data)}  E`)
107    this.mSurfaceId = data.surfaceId
108    Log.info(`${this.TAG} onSurfacePrepare X`)
109  }
110
111  private async startPreview(data?) {
112    Log.start(`${this.TAG} startPreview`)
113    globalThis.cameraStatus = CameraStatus.CAMERA_BEGIN_PREVIEW
114    if (!this.mSurfaceId) {
115      Log.info(`${this.TAG} startPreview error mSurfaceId is null`)
116      this.enableUi()
117      return
118    }
119    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
120    if (await this.isVideoMode()) {
121      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
122    } else {
123      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
124    }
125    this.disableUi()
126    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
127    if ([...this.mSessionList].pop() === 'RELEASE') {
128      await this.close()
129    }
130    if (data && data?.zoomRatio && data.zoomRatio !== 1) {
131      await this.mCameraService.setZoomRatio(data.zoomRatio)
132    }
133    this.mSessionList = []
134    this.enableUi()
135    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
136    this.mWorkerManager.postMessage(Action.updateCameraStatus())
137    Log.end(`${this.TAG} startPreview`)
138  }
139
140  private async reStartPreview(data) {
141    Log.start(`${this.TAG} reStartPreview`)
142    if (!this.mSurfaceId) {
143      Log.info(`${this.TAG} reStartPreview error mSurfaceId is null`)
144      this.enableUi()
145      return
146    }
147    this.mCameraService.setCameraId(this.mCameraId)
148    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASING
149    await this.mCameraService.releaseCamera()
150    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASE_FINISHED
151    globalThis.cameraStatus = CameraStatus.CAMERA_BEGIN_PREVIEW
152    await this.mCameraService.createCameraInput(this.mCameraId)
153    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
154    if (await this.isVideoMode()) {
155      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
156    } else {
157      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
158    }
159    this.disableUi()
160    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
161    if ([...this.mSessionList].pop() === 'RELEASE') {
162      await this.close()
163    }
164    if (data && data?.zoomRatio && data.zoomRatio !== 1) {
165      await this.mCameraService.setZoomRatio(data.zoomRatio)
166    }
167    this.mSessionList = []
168    this.enableUi()
169    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
170    this.mWorkerManager.postMessage(Action.updateCameraStatus())
171    Log.end(`${this.TAG} reStartPreview`)
172  }
173
174  private async changeMode(data) {
175    Log.start(`${this.TAG} changeMode`)
176    EventLog.write(EventLog.SWITCH_MODE)
177    this.mCurrentMode = data.mode
178    this.mCameraId = this.mCameraId.split('_').pop()
179    Log.info(`${this.TAG} this.mCurrentMode = ${this.mCurrentMode}`)
180    await this.mCameraService.releaseCamera()
181    await this.mCameraService.createCameraInput(this.mCameraId, 'modeChange')
182    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
183    if (await this.isVideoMode()) {
184      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
185    } else {
186      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
187    }
188    this.disableUi()
189    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
190    this.mWorkerManager.postMessage(Action.onModeChanged(this.mCurrentMode))
191    this.mWorkerManager.postMessage(Action.swipeModeChangeDone(false))
192    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
193    this.mWorkerManager.postMessage(Action.updateCameraStatus())
194    this.enableUi()
195    Log.end(`${this.TAG} changeMode`)
196  }
197
198  private async switchCamera(data) {
199    Log.start(`${this.TAG} switchCamera`)
200    EventLog.write(EventLog.SWITCH_CAMERA)
201    this.mCameraId = data.cameraId
202    this.mCameraService.setCameraId(this.mCameraId)
203    await this.mCameraService.releaseCamera()
204    await this.mCameraService.createCameraInput(this.mCameraId)
205    if (data?.curMode && data.curMode !== undefined && data.curMode !== this.mCurrentMode){
206      this.mCurrentMode = data.curMode
207    }
208    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
209    if (await this.isVideoMode()) {
210      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
211    } else {
212      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
213    }
214    this.disableUi()
215    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
216    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
217    this.mWorkerManager.postMessage(Action.updateCameraStatus())
218    if (new Date().getTime() - globalThis.switchCameraTime > 2000) {
219      EventLog.write(EventLog.SWITCH_TIMEOUT)
220    }
221    this.enableUi()
222    Log.end(`${this.TAG} switchCamera`)
223  }
224
225  private async close() {
226    Log.start(`${this.TAG} close`)
227    this.mSessionList.push('RELEASE')
228    if (globalThis.isSessionCreating || this.isSessionReleasing) {
229      Log.info(`${this.TAG} isSessionCreating or isSessionReleasing return`)
230      return
231    }
232    this.isSessionReleasing = true
233    await this.mCameraService.releaseCamera()
234    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASE_FINISHED
235    this.mWorkerManager.postMessage(Action.updateCameraStatus())
236    this.startIdentification = false
237    this.isSessionReleasing = false
238    if ([...this.mSessionList].pop() === 'CREATE') {
239      await this.initCamera(this.initDataCache)
240      globalThis.cameraStatus = CameraStatus.CAMERA_INIT_FINISHED
241      this.mWorkerManager.postMessage(Action.updateCameraStatus())
242    }
243    this.mSessionList = []
244    Log.end(`${this.TAG} close`)
245  }
246
247  private async isVideoMode(): Promise<boolean> {
248    Log.info(`${this.TAG} isVideoMode ${this.mCurrentMode} ${this.mCurrentMode === 'VIDEO'}`)
249    return this.mCurrentMode === 'VIDEO'
250  }
251
252  private async reloadThumbnail(data) {
253    Log.info(`${this.TAG} loadThumbnail E`)
254    this.mCameraService.getThumbnail(this.functionBackImpl)
255    Log.info(`${this.TAG} loadThumbnail X`)
256  }
257
258  static getInstance() {
259    if (!globalThis?.cameraBasicMethod) {
260      globalThis.cameraBasicMethod = new CameraBasicFunction()
261    }
262    return globalThis.cameraBasicMethod
263  }
264
265  load(): void {
266    Log.info(`${this.TAG} load E`)
267    this.mEventBus.on(Action.ACTION_INIT, this.initCamera.bind(this))
268    this.mEventBus.on(Action.ACTION_CHANGE_IMAGE_SIZE, this.imageSize.bind(this))
269    this.mEventBus.on(Action.ACTION_CHANGE_VIDEO_SIZE, this.videoSize.bind(this))
270    this.mEventBus.on(Action.ACTION_PREPARE_SURFACE, this.onSurfacePrepare.bind(this))
271    this.mEventBus.on(Action.ACTION_START_PREVIEW, this.startPreview.bind(this))
272    this.mEventBus.on(Action.ACTION_RESTART_PREVIEW, this.reStartPreview.bind(this))
273    this.mEventBus.on(Action.ACTION_CHANGE_MODE, this.changeMode.bind(this))
274    this.mEventBus.on(Action.ACTION_SWITCH_CAMERA, this.switchCamera.bind(this))
275    this.mEventBus.on(Action.ACTION_CLOSE_CAMERA, this.close.bind(this))
276    this.mEventBus.on(Action.ACTION_RELOAD_THUMBNAIL, this.reloadThumbnail.bind(this))
277    Log.info(`${this.TAG} load X`)
278  }
279
280  unload(): void {
281    Log.info(`${this.TAG} unload E`)
282    this.mEventBus.off(Action.ACTION_INIT, this.initCamera.bind(this))
283    this.mEventBus.off(Action.ACTION_CHANGE_IMAGE_SIZE, this.imageSize.bind(this))
284    this.mEventBus.off(Action.ACTION_CHANGE_VIDEO_SIZE, this.videoSize.bind(this))
285    this.mEventBus.off(Action.ACTION_PREPARE_SURFACE, this.onSurfacePrepare.bind(this))
286    this.mEventBus.off(Action.ACTION_START_PREVIEW, this.startPreview.bind(this))
287    this.mEventBus.off(Action.ACTION_RESTART_PREVIEW, this.reStartPreview.bind(this))
288    this.mEventBus.off(Action.ACTION_CHANGE_MODE, this.changeMode.bind(this))
289    this.mEventBus.off(Action.ACTION_SWITCH_CAMERA, this.switchCamera.bind(this))
290    this.mEventBus.off(Action.ACTION_CLOSE_CAMERA, this.close.bind(this))
291    this.mEventBus.off(Action.ACTION_RELOAD_THUMBNAIL, this.reloadThumbnail.bind(this))
292    Log.info(`${this.TAG} unload X`)
293  }
294}