* Copyright (c) Huawei Device Co., Ltd. 2024-2025. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import lazy { HiLog } from '../../utils/HiLog';
import lazy { Action, UiStateMode } from '../../redux/actions/Action';
import type { EventBus } from '../../worker/eventbus/EventBus';
import lazy { EventBusManager } from '../../worker/eventbus/EventBusManager';
import lazy { ActionType } from '../../redux/actions/ActionType';
import lazy { CaptureAction } from './CaptureAction';
import lazy { StoreManager } from '../../worker/StoreManager';
import lazy { BaseComponent } from '../../worker/BaseComponent';
import lazy { systemDateTime } from '../../utils/LazyImportUtil';
import lazy { UIOperationType } from '../../component/uicomponent/UIOperationType';
import lazy { CaptureActionType } from '../../redux/actions/CaptureActionType';
import lazy { CameraActionType } from '../../redux/actions/CameraActionType';
import lazy { getStates } from '../../redux';
import lazy { RecordingState } from '../recordcontrol/RecordAction';
import lazy { FeatureManager } from '../core/FeatureManager';
import lazy { FunctionId } from '../core/functionproperty/FunctionId';
import lazy { SettingFuncDialogItemIndex } from '../../component/settingview/SettingFuncDialogItemIndex';
import lazy { ModeType } from '../../mode/ModeType';
import lazy { OutputOperation } from '../outputswitcher/OutputOperation';
import lazy { CameraAppCapability } from '../../camera/CameraAppCapability';
const TAG: string = 'CaptureService';
const CAPTURE_QUEUE_SIZE: number = 1;
export class CaptureService {
private mBase: BaseComponent = new BaseComponent();
private static sInstanceCapability: CaptureService;
private mStoreManager: StoreManager = StoreManager.getInstance();
private mEventBus: EventBus = EventBusManager.getInstance().getEventBus();
private mCaptureEnableCount: number = 0;
private mLastCaptureTime: number = 0;
private mLastCaptureReadyTime: number = 0;
private mRichCaptureNext: number = 0;
public static getInstance(): CaptureService {
if (!CaptureService.sInstanceCapability) {
CaptureService.sInstanceCapability = new CaptureService();
}
return CaptureService.sInstanceCapability;
}
constructor() {
this.mEventBus.on(CaptureActionType.CAPTURE, this.onCapture.bind(this), this.mBase.hashCode());
this.mEventBus.on(ActionType.ACTION_NIGHT_CAPTURE_START, this.onNightProcessCapture.bind(this), this.mBase.hashCode());
this.mEventBus.on([CameraActionType.CHANGE_MODE, CameraActionType.SWITCH_CAMERA, CameraActionType.SWITCH_CAMERA_CHANGE_MODE,
CameraActionType.STARTED],
this.resetCaptureEnableCount.bind(this), this.mBase.hashCode());
}
private async onCapture(): Promise<void> {
this.mCaptureEnableCount++;
this.mLastCaptureTime = await systemDateTime.getRealTime(false);
HiLog.i(TAG, `SHOT2SEE onCapture captureEnableCount: ${this.mCaptureEnableCount}.`);
}
private async onNightProcessCapture(): Promise<void> {
if (this.mCaptureEnableCount > 0) {
return;
}
this.onCapture();
}
public photoSaved(uri: string): void {
HiLog.i(TAG, `SHOT2SEE photoSaved captureEnableCount: ${this.mCaptureEnableCount}.`);
this.mStoreManager.postMessage(CaptureAction.photoOnSave(uri));
}
public onCaptureAborted(): void {
StoreManager.getInstance()
.postMessage(Action.uiStateWithMode(true, UiStateMode.EXCLUDE_COMPONENT, UIOperationType.CAPTURE_BUTTON));
this.mCaptureEnableCount = this.mCaptureEnableCount > 0 ? this.mCaptureEnableCount - 1 : 0;
HiLog.i(TAG, `onCaptureAborted mCaptureEnableCount: ${this.mCaptureEnableCount}.`);
}
public async onCaptureReady(): Promise<void> {
this.mCaptureEnableCount = this.mCaptureEnableCount > 0 ? this.mCaptureEnableCount - 1 : 0;
HiLog.i(TAG, `enableCaptureCount: ${this.mCaptureEnableCount}.`);
this.mLastCaptureReadyTime = await systemDateTime.getRealTime(false);
let captureTime: number = this.mLastCaptureReadyTime - this.mLastCaptureTime;
if (CameraAppCapability.getInstance().getIsSupportedIntervalPhotoCapture()) {
const mode: ModeType = getStates().get<ModeType>('modeReducer', 'mode');
const timeLapseValue: number =
FeatureManager.getInstance().getFunction(FunctionId.TIME_LAPSE)?.getValue() as number;
if (OutputOperation.isPanPhotoOutput(mode) && timeLapseValue === SettingFuncDialogItemIndex.INDEX_FIF) {
StoreManager.getInstance().postMessage(CaptureAction.isReadyForNextAutoCapture());
}
}
HiLog.i(TAG, `capture cost time: ${captureTime}`);
}
private resetCaptureEnableCount(): void {
this.mRichCaptureNext = 0;
this.mCaptureEnableCount = 0;
}
public isEnableCapture(report: boolean = false): boolean {
HiLog.i(TAG, `check capture, mCaptureEnableCount: ${this.mCaptureEnableCount}.`);
return true;
}
public cacheRichCaptureNext(): void {
HiLog.d(TAG, `cache capture next, mRichCaptureNext: ${this.mRichCaptureNext}.`);
this.mRichCaptureNext++;
}
public queryIsEnableRichCaptureNext(): boolean {
return this.mRichCaptureNext > 0;
}
public clearRichCaptureNext(): void {
this.mRichCaptureNext = 0;
}
public isCancelClickDownCapture(): boolean {
return getStates().get<boolean>('leftRightSwipeReducer', 'isCancelClickDown') ||
getStates().get<boolean>('leftRightSwipeReducer', 'longClicked') ||
getStates().get<RecordingState>('recordReducer', 'recordingState') !== RecordingState.READY;
}
}