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