• 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    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
126    if ([...this.mSessionList].pop() === 'RELEASE') {
127      await this.close()
128    }
129    if (data && data?.zoomRatio && data.zoomRatio !== 1) {
130      await this.mCameraService.setZoomRatio(data.zoomRatio)
131    }
132    this.mSessionList = []
133    this.enableUi()
134    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
135    this.mWorkerManager.postMessage(Action.updateCameraStatus())
136    Log.end(`${this.TAG} startPreview`)
137  }
138
139  private async reStartPreview(data) {
140    Log.start(`${this.TAG} reStartPreview`)
141    if (!this.mSurfaceId) {
142      Log.info(`${this.TAG} reStartPreview error mSurfaceId is null`)
143      this.enableUi()
144      return
145    }
146    this.mCameraService.setCameraId(this.mCameraId)
147    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASING
148    await this.mCameraService.releaseCamera()
149    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASE_FINISHED
150    globalThis.cameraStatus = CameraStatus.CAMERA_BEGIN_PREVIEW
151    await this.mCameraService.createCameraInput(this.mCameraId)
152    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
153    if (await this.isVideoMode()) {
154      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
155    } else {
156      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
157    }
158    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
159    if ([...this.mSessionList].pop() === 'RELEASE') {
160      await this.close()
161    }
162    if (data && data?.zoomRatio && data.zoomRatio !== 1) {
163      await this.mCameraService.setZoomRatio(data.zoomRatio)
164    }
165    this.mSessionList = []
166    this.enableUi()
167    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
168    this.mWorkerManager.postMessage(Action.updateCameraStatus())
169    Log.end(`${this.TAG} reStartPreview`)
170  }
171
172  private async changeMode(data) {
173    Log.start(`${this.TAG} changeMode`)
174    EventLog.write(EventLog.SWITCH_MODE)
175    this.mCurrentMode = data.mode
176    this.mCameraId = this.mCameraId.split('_').pop()
177    Log.info(`${this.TAG} this.mCurrentMode = ${this.mCurrentMode}`)
178    await this.mCameraService.releaseCamera()
179    await this.mCameraService.createCameraInput(this.mCameraId, 'modeChange')
180    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
181    if (await this.isVideoMode()) {
182      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
183    } else {
184      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
185    }
186    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
187    this.mWorkerManager.postMessage(Action.onModeChanged(this.mCurrentMode))
188    this.mWorkerManager.postMessage(Action.swipeModeChangeDone(false))
189    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
190    this.mWorkerManager.postMessage(Action.updateCameraStatus())
191    this.enableUi()
192    Log.end(`${this.TAG} changeMode`)
193  }
194
195  private async switchCamera(data) {
196    Log.start(`${this.TAG} switchCamera`)
197    EventLog.write(EventLog.SWITCH_CAMERA)
198    this.mCameraId = data.cameraId
199    this.mCameraService.setCameraId(this.mCameraId)
200    await this.mCameraService.releaseCamera()
201    await this.mCameraService.createCameraInput(this.mCameraId)
202    if (data?.curMode && data.curMode !== undefined && data.curMode !== this.mCurrentMode){
203      this.mCurrentMode = data.curMode
204    }
205    await this.mCameraService.createPreviewOutput(this.mSurfaceId, this.mCurrentMode)
206    if (await this.isVideoMode()) {
207      //      await this.mCameraService.createVideoOutput(this.functionBackImpl)
208    } else {
209      await this.mCameraService.createPhotoOutput(this.functionBackImpl)
210    }
211    await this.mCameraService.createSession(this.mSurfaceId, await this.isVideoMode())
212    globalThis.cameraStatus = CameraStatus.CAMERA_PREVIEW_FINISHED
213    this.mWorkerManager.postMessage(Action.updateCameraStatus())
214    if (new Date().getTime() - globalThis.switchCameraTime > 2000) {
215      EventLog.write(EventLog.SWITCH_TIMEOUT)
216    }
217    this.enableUi()
218    Log.end(`${this.TAG} switchCamera`)
219  }
220
221  private async close() {
222    Log.start(`${this.TAG} close`)
223    this.mSessionList.push('RELEASE')
224    if (globalThis.isSessionCreating || this.isSessionReleasing) {
225      Log.info(`${this.TAG} isSessionCreating or isSessionReleasing return`)
226      return
227    }
228    this.isSessionReleasing = true
229    await this.mCameraService.releaseCamera()
230    globalThis.cameraStatus = CameraStatus.CAMERA_RELEASE_FINISHED
231    this.mWorkerManager.postMessage(Action.updateCameraStatus())
232    this.startIdentification = false
233    this.isSessionReleasing = false
234    if ([...this.mSessionList].pop() === 'CREATE') {
235      await this.initCamera(this.initDataCache)
236      globalThis.cameraStatus = CameraStatus.CAMERA_INIT_FINISHED
237      this.mWorkerManager.postMessage(Action.updateCameraStatus())
238    }
239    this.mSessionList = []
240    Log.end(`${this.TAG} close`)
241  }
242
243  private async isVideoMode(): Promise<boolean> {
244    Log.info(`${this.TAG} isVideoMode ${this.mCurrentMode} ${this.mCurrentMode === 'VIDEO'}`)
245    return this.mCurrentMode === 'VIDEO'
246  }
247
248  private async reloadThumbnail(data) {
249    Log.info(`${this.TAG} loadThumbnail E`)
250    this.mCameraService.getThumbnail(this.functionBackImpl)
251    Log.info(`${this.TAG} loadThumbnail X`)
252  }
253
254  static getInstance() {
255    if (!globalThis?.cameraBasicMethod) {
256      globalThis.cameraBasicMethod = new CameraBasicFunction()
257    }
258    return globalThis.cameraBasicMethod
259  }
260
261  load(): void {
262    Log.info(`${this.TAG} load E`)
263    this.mEventBus.on(Action.ACTION_INIT, this.initCamera.bind(this))
264    this.mEventBus.on(Action.ACTION_CHANGE_IMAGE_SIZE, this.imageSize.bind(this))
265    this.mEventBus.on(Action.ACTION_CHANGE_VIDEO_SIZE, this.videoSize.bind(this))
266    this.mEventBus.on(Action.ACTION_PREPARE_SURFACE, this.onSurfacePrepare.bind(this))
267    this.mEventBus.on(Action.ACTION_START_PREVIEW, this.startPreview.bind(this))
268    this.mEventBus.on(Action.ACTION_RESTART_PREVIEW, this.reStartPreview.bind(this))
269    this.mEventBus.on(Action.ACTION_CHANGE_MODE, this.changeMode.bind(this))
270    this.mEventBus.on(Action.ACTION_SWITCH_CAMERA, this.switchCamera.bind(this))
271    this.mEventBus.on(Action.ACTION_CLOSE_CAMERA, this.close.bind(this))
272    this.mEventBus.on(Action.ACTION_RELOAD_THUMBNAIL, this.reloadThumbnail.bind(this))
273    Log.info(`${this.TAG} load X`)
274  }
275
276  unload(): void {
277    Log.info(`${this.TAG} unload E`)
278    this.mEventBus.off(Action.ACTION_INIT, this.initCamera.bind(this))
279    this.mEventBus.off(Action.ACTION_CHANGE_IMAGE_SIZE, this.imageSize.bind(this))
280    this.mEventBus.off(Action.ACTION_CHANGE_VIDEO_SIZE, this.videoSize.bind(this))
281    this.mEventBus.off(Action.ACTION_PREPARE_SURFACE, this.onSurfacePrepare.bind(this))
282    this.mEventBus.off(Action.ACTION_START_PREVIEW, this.startPreview.bind(this))
283    this.mEventBus.off(Action.ACTION_RESTART_PREVIEW, this.reStartPreview.bind(this))
284    this.mEventBus.off(Action.ACTION_CHANGE_MODE, this.changeMode.bind(this))
285    this.mEventBus.off(Action.ACTION_SWITCH_CAMERA, this.switchCamera.bind(this))
286    this.mEventBus.off(Action.ACTION_CLOSE_CAMERA, this.close.bind(this))
287    this.mEventBus.off(Action.ACTION_RELOAD_THUMBNAIL, this.reloadThumbnail.bind(this))
288    Log.info(`${this.TAG} unload X`)
289  }
290}