* 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 camera from '@ohos.multimedia.camera';
import type PhotoOutputWrap from '../PhotoOutputWrap';
import type PreviewOutputWrap from '../PreviewOutputWrap';
import type MetadataOutputWrap from '../MetadataOutputWrap';
import type CameraInputWrap from '../CameraInputWrap';
import type CameraContext from '../CameraContext';
import lazy { App2CameraModeMessage, LightStatus, TagMessage } from '../../../DataType';
import lazy { ModeType } from '../../../../mode/ModeType';
import lazy { DeviceInfo } from '../../../../component/deviceinfo/DeviceInfo';
import colorSpaceManager from '@ohos.graphics.colorSpaceManager';
import lazy { BaseSession } from './BaseSession';
import lazy { OutputOperation } from '../../../../function/outputswitcher/OutputOperation';
import lazy { AsyncCallback, ErrorCallback } from '@ohos.base';
import lazy { ZoomPointInfo } from '../../../../function/zoombar/ZoomParam';
import lazy { workerCallback } from '../../WorkerCallback';
import lazy { simpleStringify } from '../../../../utils/SimpleStringify';
import lazy { TripodStatus } from '../../../../function/enumbase/TripodStatus';
import lazy { display, window } from '@kit.ArkUI';
import VideoModule from '../video/VideoModule';
import lazy { WorkerDataCache } from '../../WorkerDataCache';
import lazy { DisplayService } from '../../../../service/UIAdaptive/DisplayService';
import image from '@ohos.multimedia.image';
import lazy { LogStyleMode } from '../../../../function/enumbase/LogStyleMode';
import lazy { geoLocationManager } from '@kit.LocationKit';
import lazy { LOCATION_MESSAGE } from '../../CameraTaskHandler';
import lazy { OutputType } from '../../../../function/outputswitcher/OutputType';
import lazy { ExposureData } from '../../../../component/focusExposure/FocusExposureHelper';
import lazy { BusinessError } from '@kit.BasicServicesKit';
import lazy { audio } from '@kit.AudioKit';
const TAG: string = 'SessionWrap';
const EXPOSURE_VALUE: number = 1000;
const TIME_LAPSE_MIN_INTERVAL: number = 500;
const SKIN_TONE_OFFSET: number = 5;
const TIME_OPEN = 200;
export default class SessionWrap {
private mCameraContext!: CameraContext;
private mMode: ModeType = ModeType.NONE;
private mSession!: BaseSession;
private timeLapseTimerId: number = Number.MIN_VALUE;
private mMetadataOutput!: MetadataOutputWrap;
private mPhotoOutput!: PhotoOutputWrap;
private mCollaborateOutput?: PreviewOutputWrap;
private mCollaborateControlOutput?: PreviewOutputWrap;
private mPreviewOutput: PreviewOutputWrap;
private mPreviewOutputForTimeLapse!: PreviewOutputWrap;
private mPanoramaMaxPreviewOutput!: PreviewOutputWrap;
private mPanoramaMinPreviewOutput!: PreviewOutputWrap;
private mCameraInput: CameraInputWrap;
private hasOtherOutput: boolean = false;
private mCanAddOutput: boolean = true;
private mZoomRatioRange: number[] | undefined;
private mHasFlash: boolean | undefined = true;
private mIsMacroSupported: boolean = false;
private mIsEffectSuggestionSupported: boolean = false;
private mIsSceneFeatureSupported: boolean = false;
private mZoomPointInfo: ZoomPointInfo | undefined;
private mIsDeferPhoto: boolean = false;
private mIsDeferVideo: boolean = false;
private mIsCompositionSuggestionSupported: boolean = false;
private mTryAeInfo: camera.TryAEInfo | undefined;
private mIsInTryAe: boolean = false;
private mIsTimeLapseSpeedAuto: boolean = false;
private mTimeLapseUserInterval: number = TIME_LAPSE_MIN_INTERVAL;
private mTimeLapseHalInterval: number = TIME_LAPSE_MIN_INTERVAL;
private mTimeLapseStopCapture: boolean = false;
private prevLcdFlashStatus: boolean = false;
private mIsColorStyleSupport: boolean = false;
private isCollaborationPreviewOutputStop: boolean = false;
private isoValue: number = 0;
private proShutterEffectValue: number = 0;
private mSmoothZoomInfoCallback: AsyncCallback<camera.SmoothZoomInfo> = (err, zoomInfo: camera.SmoothZoomInfo) => {
if (err) {
HiLog.e(TAG, `SmoothZoomInfo error: ${err?.code}.`);
return;
}
HiLog.i(TAG, `smoothZoomInfoAvailable zoomInfo: ${zoomInfo.duration}.`);
};
private captureTimelapseFun: Function = () => {
if (this.mPhotoOutput.isInCapture()) {
HiLog.w(TAG, 'timeLapseVideo capture failed');
return;
}
if (this.mTimeLapseStopCapture) {
return;
}
HiLog.i(TAG, 'timeLapseCapture One');
this.mPhotoOutput.capture({
rotation: 0,
quality: 1
}, {
downCapture: false,
isBackCapture: this.mCameraContext.getCameraPosition() === camera.CameraPosition.CAMERA_POSITION_BACK,
});
};
private mSceneFeatureCallBack: AsyncCallback<camera.TripodDetectionResult> =
(err, detectionResult: camera.TripodDetectionResult) => {
let result: camera.TripodDetectionResult = detectionResult;
if (err) {
HiLog.e(TAG, `SceneFeatureDetectionResult error: ${err?.code}.`);
result = {
featureType: -1,
detected: false,
tripodStatus: TripodStatus.INVALID
};
}
HiLog.i(TAG,
`mSceneFeatureCallBack detected: ${detectionResult.detected}, featureType: ${detectionResult.featureType}, tripodStatus: ${detectionResult.tripodStatus}.`);
workerCallback.onSceneFeatureDetectionResult(result);
};
private mIsoInfoCallback: AsyncCallback<camera.IsoInfo> = (err, IsoInfo: camera.IsoInfo) => {
if (err) {
HiLog.e(TAG, `IsoInfo error: ${err?.code}.`);
return;
}
if (IsoInfo.iso !== this.isoValue) {
this.isoValue = IsoInfo.iso;
workerCallback.onUpdateIsoDuration(IsoInfo.iso);
}
};
private mExposureInfoCallback: AsyncCallback<camera.ExposureInfo> = (err, exposureInfo: camera.ExposureInfo) => {
if (err) {
HiLog.e(TAG, `exposureInfo error: ${err?.code}.`);
return;
}
if (exposureInfo.exposureTimeValue !== this.proShutterEffectValue) {
this.proShutterEffectValue = exposureInfo.exposureTimeValue;
workerCallback.onUpdateExposureDuration(exposureInfo.exposureTimeValue);
}
};
private mApertureInfoCallback: AsyncCallback<camera.ApertureInfo> = (err, apertureInfo: camera.ApertureInfo) => {
if (err) {
HiLog.e(TAG, `apertureInfo error: ${err?.code}.`);
return;
}
HiLog.i(TAG, `apertureInfo success ApertureInfo: ${apertureInfo.aperture}.`);
if (this.getSupportedPhysicalApertures().length !== 0) {
workerCallback.onUpdatePhysicalApertureDuration(apertureInfo.aperture);
}
};
private mLuminationCallback: AsyncCallback<camera.LuminationInfo> = (err, luminationInfo: camera.LuminationInfo) => {
if (err) {
HiLog.e(TAG, `luminationInfo error: ${err?.code}.`);
return;
}
workerCallback.onUpdateExposureRecoveryFlag(luminationInfo.lumination);
};
private mTryAeCallback: AsyncCallback<camera.TryAEInfo> = (error, tryAeInfo: camera.TryAEInfo) => {
if (error) {
HiLog.e(TAG, `try ae callback error: ${error}.`);
return;
}
if (!this.mIsInTryAe) {
return;
}
this.mTryAeInfo = tryAeInfo;
HiLog.i(TAG, `timeLapseVideo try ae done: ${this.mTryAeInfo.isTryAEDone}, needed: ${
this.mTryAeInfo.isTryAEHintNeeded}, previewType: ${this.mTryAeInfo.previewType}, interval: ${
this.mTryAeInfo.captureInterval}`);
if (this.mTryAeInfo?.isTryAEHintNeeded) {
}
if (this.mTryAeInfo?.captureInterval) {
HiLog.i(TAG,
`timeLapseVideo interval by hal: ${this.mTryAeInfo?.captureInterval}, by user: ${this.mTimeLapseUserInterval}}`);
this.mSession.setTimeLapseInterval(this.mTimeLapseUserInterval);
if (this.mTryAeInfo?.captureInterval >= TIME_LAPSE_MIN_INTERVAL) {
this.mTimeLapseHalInterval = this.mTryAeInfo?.captureInterval;
HiLog.i(TAG, `update timeLapse HAL interval: ${this.mTimeLapseHalInterval}`);
}
}
if (this.mTryAeInfo?.isTryAEDone) {
HiLog.i(TAG, 'timeLapseVideo confirm try AE done');
this.mIsInTryAe = false;
this.mSession.stopTryAE();
const finalInterval: number =
this.mIsTimeLapseSpeedAuto ? this.mTimeLapseHalInterval : this.mTimeLapseUserInterval;
HiLog.i(TAG, `timeLapseVideo final interval: ${finalInterval}, isSpeedAuto: ${this.mIsTimeLapseSpeedAuto}`);
workerCallback.onTimeLapseTryAeDone(finalInterval);
this.mSession?.setTimeLapseRecordState(camera.TimeLapseRecordState.RECORDING);
this.startCaptureLoop(finalInterval);
}
};
private mTimeLapseErrorCallback: ErrorCallback = (error) => {
HiLog.e(TAG, `timeLapseVideo error: ${error.code}`);
};
private mAbilityChangeCallback: AsyncCallback<void> = (err) => {
if (err) {
HiLog.e(TAG, `abilityChange error: ${err?.code}.`);
return;
}
HiLog.i(TAG, 'abilityChange success');
if (this.getSupportedPhysicalApertures().length === 0) {
workerCallback.onAbilityChange(this.mSession.getIsoRange(), []);
} else {
workerCallback.onAbilityChange(this.mSession.getIsoRange(), this.mSession.getSupportedPhysicalApertures());
}
};
private mSuperMacroIconVisibleCallback: AsyncCallback<boolean> = (err, isSuperMacroIconVisible: boolean) => {
HiLog.i(TAG, `mSuperMacroIconVisibleCallback isSuperMacroIconVisible: ${isSuperMacroIconVisible}.`);
if (err) {
HiLog.e(TAG, `isSuperMacroIconVisible error: ${err?.code}.`);
}
};
private watchSuperMotionStatusCallback: AsyncCallback<camera.SlowMotionStatus> = (err, status: number) => {
if (err) {
HiLog.e(TAG, `SlowMotionStatus error: ${err?.code}.`);
}
const resultMotionStatus: number = err ? 0 : status;
HiLog.i(TAG, `watch super motion status:${resultMotionStatus}`);
workerCallback.onSuperMotionStatus(resultMotionStatus);
};
private watchSlowZoomRangeCallback: AsyncCallback<camera.ZoomInfo> = (err, slowZoomRange: number[]) => {
if (err) {
HiLog.e(TAG, `SLOWMotionZoomRange error: ${err?.code}.`);
}
HiLog.i(TAG, `watch slow motion zoom range:${JSON.stringify(slowZoomRange)}`);
workerCallback.onSlowMotionZoomRange(slowZoomRange);
};
private mWatchLcdStatusCallback: AsyncCallback<camera.LcdFlashStatus> = (err, lcdStatus: camera.LcdFlashStatus) => {
if (err) {
HiLog.e(TAG, `lcdFlashStatus error: ${err?.code}.`);
}
if (this.prevLcdFlashStatus !== lcdStatus.isLcdFlashNeeded) {
this.prevLcdFlashStatus = lcdStatus.isLcdFlashNeeded;
try {
this.mSession.enableLcdFlash(lcdStatus.isLcdFlashNeeded);
} catch (err) {
HiLog.e(TAG, `enableLcdFlash fail, ${simpleStringify(err)}`);
}
HiLog.limitLog(TAG,
`lcdFlashStatus enable, lcdCompensation: ${lcdStatus.lcdCompensation},${lcdStatus.isLcdFlashNeeded}`,
'workerLcdFlashStatus');
}
workerCallback.onLcdFlashCompensate(lcdStatus);
};
private mConstellationDraw: AsyncCallback<camera.ConstellationDrawing> = (err, info: camera.ConstellationDrawing) => {
if (err) {
HiLog.e(TAG, `constellationDrawing error: ${err?.code}.`);
return;
}
if (!info || !info.starsInfo) {
HiLog.w(TAG, `info is invaliad: ${info}.`);
return;
}
};
constructor(cameraManager: camera.CameraManager, mode: ModeType, cameraModeMessage: App2CameraModeMessage,
cameraContext: CameraContext) {
this.mMode = mode;
this.mCameraContext = cameraContext;
this.mSession = new BaseSession(cameraManager, mode, cameraModeMessage);
this.mSession.on('smoothZoomInfoAvailable', this.mSmoothZoomInfoCallback);
}
public async commitSession(tagMessage: TagMessage, cameraPosition: camera.CameraPosition,
isPicker = false): Promise<void> {
await this.createSessionAndSessionWrap(tagMessage, cameraPosition);
await VideoModule.getInstance().addMaintainDebugMetaData();
HiLog.begin(TAG, 'commitConfig');
await this.mSession.commitConfig().catch(error => {
HiLog.e(TAG, `session commitConfig error: ${simpleStringify(error)}.`);
});
HiLog.end(TAG, 'commitConfig');
this.mZoomRatioRange = this.mSession.getZoomRatioRange();
}
private handlePreviewRotation(tagMessage: TagMessage): void {
if (!tagMessage?.previewRotationInfo?.isNeedSetPreviewRotation) {
HiLog.i(TAG, 'no need to set preview rotation.');
return;
}
try {
let previewRotation = this.mPreviewOutput.getPreviewRotation(tagMessage.previewRotationInfo.previewRotation);
this.mPreviewOutput.setPreviewRotation(previewRotation, tagMessage.previewRotationInfo.isDisplayLocked);
} catch (error) {
HiLog.e(TAG, `handlePreviewRotation error: ${simpleStringify(error)}.`);
}
}
private getCameraInput(tagMessage: TagMessage): camera.CameraInput {
let cameraInput: camera.CameraInput = this.mCameraInput.getInput();
try {
cameraInput.usedAsPosition(tagMessage.usedAsPositionValue);
HiLog.i(TAG, `usedAsposition:${tagMessage.usedAsPositionValue}`);
} catch (error) {
HiLog.e(TAG, `usedAsposition error: ${simpleStringify(error)}.`);
}
return cameraInput;
}
private async createSessionAndSessionWrap(tagMessage: TagMessage,
cameraPosition: camera.CameraPosition): Promise<void> {
const videoModule: VideoModule = VideoModule.getInstance();
if (OutputOperation.isPanVideoOutput(tagMessage.mode, tagMessage.outputType) && !!videoModule.getOutput()) {
await VideoModule.getInstance().setOutputSetting();
HiLog.i(TAG, 'RECORD_TRACK createSession video addOutput.');
this.sessionAddOutputWrap(videoModule.getOutput());
this.mIsDeferVideo = videoModule.enableDeferredVideoEnhance();
}
if (this.mCameraContext.isSupportPhotoOutput() && this.mPhotoOutput) {
HiLog.i(TAG, 'createSession photo addOutput.');
this.sessionAddOutputWrap(this.mPhotoOutput.getOutput());
HiLog.i(TAG, 'createSession photo addOutput done.');
this.mIsDeferPhoto = this.mPhotoOutput.enable(this.mMode, tagMessage.outputType);
}
if (this.mPhotoOutput) {
try {
await this.mPhotoOutput.addCaptureListener();
} catch (e) {
HiLog.end(TAG, `addCaptureListener err, ${e}`);
}
}
this.addPreviewOutput();
HiLog.i(TAG, 'before add dual output, mode: ' + tagMessage.mode);
const targetCamera: camera.CameraDevice = this.mCameraContext.getCamera();
const isFront: boolean = targetCamera.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT ||
targetCamera.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FOLD_INNER;
if (this.mMetadataOutput) {
HiLog.i(TAG, 'createSession metadata addOutput.');
this.mSession.addOutput(this.mMetadataOutput.getOutput());
}
this.featureEnable(tagMessage);
}
public beginConfig(): void {
HiLog.i(TAG, 'SessionWrap beginConfig.');
this.mSession.beginConfig();
HiLog.i(TAG, 'SessionWrap beginConfig done.');
}
public addInput(tagMessage: TagMessage): void {
HiLog.i(TAG, 'createSession addInput.');
this.mSession.addInput(this.getCameraInput(tagMessage));
HiLog.i(TAG, 'createSession addInput done.');
}
private addPreviewOutput(): void {
HiLog.i(TAG, 'createSession preview addOutput.');
if (!!this.mPreviewOutput) {
this.sessionAddOutputWrap(this.mPreviewOutput.getOutput());
}
if (this.mCollaborateOutput) {
HiLog.i(TAG, ' mSession.addOutput: mCollaborateOutput.');
this.mSession.addOutput(this.mCollaborateOutput.getOutput());
this.hasOtherOutput = true;
}
if (this.mCollaborateControlOutput) {
HiLog.i(TAG, ' mSession.addOutput: mCollaborateControlOutput ' + this.mCollaborateControlOutput.getOutput());
this.mSession.addOutput(this.mCollaborateControlOutput.getOutput());
}
}
public setCollaboratePreviewOutput(previewOutput: PreviewOutputWrap): void {
if (!previewOutput) {
return;
}
this.mCollaborateOutput = previewOutput;
}
public clearCollaboratePreviewOutput(): void {
this.mCollaborateOutput = null;
}
public setCollaborateControlPreviewOutput(previewOutput: PreviewOutputWrap): void {
if (!previewOutput) {
return;
}
this.mCollaborateControlOutput = previewOutput;
}
public clearCollaborateControlPreviewOutput(): void {
this.mCollaborateControlOutput = null;
}
private featureEnable(tagMessage: TagMessage): void {
if (!tagMessage) {
return;
}
if (tagMessage.isMirror !== undefined && this.mPhotoOutput) {
this.mPhotoOutput.setMirror(tagMessage.isMirror);
}
this.emotionEnable(tagMessage);
this.mPreviewOutput.enableBandwidthCompression();
this.isSupportStage(tagMessage);
}
private emotionEnable(tagMessage: TagMessage): void {
try {
if (tagMessage.isOperationEmotion !== undefined) {
this.mMetadataOutput.setOperationEmotion(tagMessage.isOperationEmotion);
}
} catch (e) {
HiLog.i(TAG, `metadataOutput set motion error = ${e.code}`);
}
}
private isSupportStage(tagMessage): void {
if (tagMessage.isSupportAudioStage) {
this.setEffectAudioStage(true);
}
if (!this.isStageBoostSupported()) {
return;
}
}
private setLogStyleColorSpaceBeforeCommitConfig(tagMassage: TagMessage): boolean {
return false;
}
private setColorSpaceBeforeCommitConfig(tagMassage: TagMessage): void {
let mColorSpace = colorSpaceManager.ColorSpace.DISPLAY_P3;
let mHighColorSpace = colorSpaceManager.ColorSpace.BT2020_HLG;
let traditionalColorSpace = colorSpaceManager.ColorSpace.SRGB;
HiLog.i(TAG, `setColorSpaceBeforeCommitConfig ColorSpace: ${mColorSpace}, traditional: ${traditionalColorSpace}.`);
if (tagMassage?.isP3Flag !== undefined) {
traditionalColorSpace = colorSpaceManager.ColorSpace.SRGB;
HiLog.i(TAG, `setColorSpaceBeforeCommitConfig isP3Flag: ${tagMassage?.isP3Flag}, mColorSpace: ${mColorSpace}.`);
}
if (this.setLogStyleColorSpaceBeforeCommitConfig(tagMassage)) {
return;
}
try {
let colorSpaceArr: colorSpaceManager.ColorSpace[] = this.getColorSpaceArr(tagMassage);
colorSpaceArr.forEach((colorSpace) => {
HiLog.i(TAG, `setColorSpace colorSpaceArr: ${colorSpace}.`);
});
const isSupportUseColorSpace = colorSpaceArr.indexOf(mColorSpace) >= 0;
const isSupportHighColorSpace = colorSpaceArr.indexOf(mHighColorSpace) >= 0;
HiLog.i(TAG,
`setColorSpace isSupportUseColorSpace: ${isSupportUseColorSpace}, index: ${colorSpaceArr.indexOf(mColorSpace)}.`);
HiLog.i(TAG,
`setColorSpace isSupportHighColorSpace: ${isSupportHighColorSpace}, index: ${colorSpaceArr.indexOf(mHighColorSpace)}.`);
if (isSupportUseColorSpace) {
this.mSession.setColorSpace(mColorSpace);
} else {
this.mSession.setColorSpace(traditionalColorSpace);
}
} catch (err) {
HiLog.e(TAG, `setColorSpace err: ${simpleStringify(err)}.`);
}
}
private getColorSpaceArr(tagMassage: TagMessage) {
let colorSpaceArr: colorSpaceManager.ColorSpace[] = [];
colorSpaceArr = this.mSession.getSupportedColorSpaces();
return colorSpaceArr;
}
public async swapVideoOutput(oldOutput: camera.CameraOutput, output: camera.CameraOutput,
outputType: OutputType): Promise<void> {
this.mSession.beginConfig();
if (!!oldOutput && !!output) {
try {
this.mSession.removeOutput(oldOutput);
HiLog.i(TAG, 'old videoOutput has been removed.');
} catch (err) {
HiLog.e(TAG, `remove video output fail, err: ${err}.`);
}
try {
await oldOutput.release();
} catch (err) {
HiLog.e(TAG, `release old video output fail, err: ${err}.`);
}
try {
this.mSession.addOutput(output);
} catch (err) {
HiLog.e(TAG, `addOutput video output fail, err: ${err}.`);
}
}
this.mIsDeferPhoto = this.mPhotoOutput.enable(this.mMode, outputType);
HiLog.i(TAG, 'startRecording addOutput finished.');
HiLog.begin(TAG, 'commitConfig');
await this.mSession.commitConfig();
HiLog.end(TAG, 'commitConfig');
this.mHasFlash = this.mSession.hasFlash();
this.mZoomRatioRange = this.mSession.getZoomRatioRange();
this.mZoomPointInfo = this.mSession.getZoomPointInfo();
}
public timeLapseTryAe(captureInterval: number, isSpeedAuto: boolean): void {
HiLog.i(TAG, `timeLapseVideo start try ae, interval: ${captureInterval}`);
this.mSession.setTimeLapseInterval(captureInterval);
this.mTimeLapseUserInterval = captureInterval;
this.mIsInTryAe = true;
this.mIsTimeLapseSpeedAuto = isSpeedAuto;
this.mSession.startTryAE();
}
public setVideoStabilization(videoStabilizationMode: camera.VideoStabilizationMode): void {
try {
HiLog.i(TAG, `RECORD_TRACK setVideoStabilization videoStabilizationMode: ${videoStabilizationMode} begin.`);
let isSupported = this.mSession.isVideoStabilizationModeSupported(videoStabilizationMode);
HiLog.i(TAG, `RECORD_TRACK setVideoStabilization isSupported: ${isSupported}.`);
if (isSupported) {
this.mSession.setVideoStabilizationMode(videoStabilizationMode);
HiLog.i(TAG, `RECORD_TRACK setVideoStabilization videoStabilizationMode: ${isSupported} success.`);
}
const vsMode = this.mSession.getActiveVideoStabilizationMode();
HiLog.i(TAG, `RECORD_TRACK get videoStabilizationMode: ${vsMode}.`);
} catch (error) {
HiLog.e(TAG, error.code);
}
}
public closeVideoStabilization(): void {
try {
const isSupported = this.mSession.isVideoStabilizationModeSupported(camera.VideoStabilizationMode.OFF);
HiLog.i(TAG, `closeVideoStabilization isSupported: ${isSupported}.`);
if (isSupported) {
this.mSession.setVideoStabilizationMode(camera.VideoStabilizationMode.OFF);
}
const vsMode = this.mSession.getActiveVideoStabilizationMode();
HiLog.i(TAG, `VideoStabilization Mode : ${vsMode}.`);
} catch (error) {
HiLog.e(TAG, `RECORD_TRACK setVideoStabilization error: ${error?.code}.`);
}
}
public async start(tagMessage: TagMessage): Promise<void> {
this.handlePreviewRotation(tagMessage);
HiLog.begin(TAG, 'start');
await this.mSession.start().catch(error => {
HiLog.e(TAG, `session start error: ${simpleStringify(error)}.`);
});
if (this.mMetadataOutput !== undefined) {
await this.mMetadataOutput.start();
}
HiLog.end(TAG, 'start');
}
public async stop(): Promise<void> {
await this.mSession.stop().catch(error => {
HiLog.e(TAG, `session stop error: ${simpleStringify(error)}.`);
});
}
public getSupportedNightSubModeTypes(): camera.NightSubModeType[] {
const modes: camera.NightSubMode[] = this.mSession.getSupportedNightSubModeTypes();
HiLog.i(TAG, `getSupportedNightSubModeTypes: ${modes ? JSON.stringify(modes) : -1}`);
return modes ? modes : [];
}
public setNightSubModeType(subMode: camera.NightSubModeType): void {
this.mSession.setNightSubModeType(subMode);
}
public setLocation(location: geoLocationManager.Location): void {
HiLog.i(TAG, `set night sub mode location: ${LOCATION_MESSAGE.type}`);
this.mSession.setLocation(location);
}
public isNightSubModeHasFlash(flashMode: camera.FlashMode): boolean {
const isHasFlash: boolean = this.mSession.isFlashModeSupported(flashMode);
HiLog.i(TAG, 'isNightSubModeHasFlash: ' + isHasFlash);
return isHasFlash;
}
public async removeInput(): Promise<void> {
HiLog.begin(TAG, 'removeInput');
this.mSession.beginConfig();
HiLog.i(TAG, 'remove input from session, and reuse it next.');
try {
this.mSession.removeInput(this.mCameraInput.getInput());
this.mCameraInput = null;
} catch (e) {
HiLog.i(TAG, `remove input from session, err: ${simpleStringify(e)}.`);
}
HiLog.end(TAG, 'removeInput');
}
public async release(): Promise<void> {
this.hasOtherOutput = false;
this.handleMacroAbilityOff();
this.handleSceneFeatureOff();
this.handleProfessionOff();
this.handleSlowMotionOff();
this.handleLcdFlashStatusOff();
this.handleTimeLapseModeSessionOff();
this.handleNightSubModeOff();
this.handleStitchingModeSessionOff();
this.handleCinemaSessionOff();
this.handleEffectSuggestionChangeOff();
this.handleSmoothZoomInfoAvailableOff();
this.handleCompositionSuggestionOff();
this.handleLightStatusOff();
this.mPreviewOutput = null;
await this.mSession.release().catch(error => {
HiLog.e(TAG, `session release error: ${simpleStringify(error)}.`);
});
this.mSession = null;
}
public hasInput(): boolean {
return !!this.mCameraInput;
}
public setCameraInput(cameraInput: CameraInputWrap): void {
if (!cameraInput) {
HiLog.e(TAG, 'cameraInput is null.');
return;
}
this.mCameraInput = cameraInput;
}
public setPreviewOutput(previewOutput: PreviewOutputWrap): void {
if (!previewOutput) {
HiLog.e(TAG, 'setPreviewOutput previewOutput is null.');
return;
}
this.mPreviewOutput = previewOutput;
}
public setPreviewOutputForTimeLapse(previewOutput: PreviewOutputWrap): void {
if (!previewOutput) {
HiLog.e(TAG, 'setPreviewOutputForTimeLapse previewOutput is null.');
return;
}
this.mPreviewOutputForTimeLapse = previewOutput;
}
public setPanoramaMaxPreviewOutput(previewOutput: PreviewOutputWrap): void {
if (!previewOutput) {
HiLog.e(TAG, 'panoramaMaxPreviewOutput is null.');
return;
}
this.mPanoramaMaxPreviewOutput = previewOutput;
}
public async dynamicAddPreviewOutput(previewOutput: PreviewOutputWrap, tagMessage: TagMessage): Promise<void> {
if (!previewOutput.getOutput()) {
HiLog.e(TAG, 'dynamicAddPreviewOutput is null.');
return;
}
try {
HiLog.begin(TAG, 'dynamicAddPreviewOutput');
this.mSession.beginConfig();
this.mSession.addOutput(previewOutput.getOutput());
await this.mSession.commitConfig().then(() => {
HiLog.i(TAG, 'dynamicAddPreviewOutput session commit successfully');
}).catch(error => {
HiLog.e(TAG, `dynamicAddPreviewOutput session commitConfig error: ${simpleStringify(error)}.`);
});
await this.start(tagMessage);
HiLog.end(TAG, 'dynamicAddPreviewOutput');
this.hasOtherOutput = true;
} catch (err) {
HiLog.e(TAG, `dynamicAddPreviewOutput error: ${simpleStringify(err)}`);
}
}
public async dynamicRemovePreviewOutput(previewOutput: PreviewOutputWrap, tagMessage: TagMessage): Promise<void> {
if (!previewOutput || !previewOutput.getOutput()) {
HiLog.e(TAG, 'dynamicRemovePreviewOutput is null.');
return;
}
HiLog.begin(TAG, 'dynamicRemovePreviewOutput');
try {
this.mSession.beginConfig();
this.mSession.removeOutput(previewOutput.getOutput());
await previewOutput.getOutput().release();
await this.mSession.commitConfig().then(() => {
HiLog.i(TAG, 'dynamicRemovePreviewOutput session commit successfully');
}).catch(error => {
HiLog.e(TAG, `dynamicRemovePreviewOutput session commitConfig error: ${simpleStringify(error)}.`);
});
await this.start(tagMessage);
this.hasOtherOutput = false;
} catch (error) {
HiLog.e(TAG, `dynamicRemovePreviewOutput error: ${simpleStringify(error)}.`);
}
HiLog.end(TAG, 'dynamicRemovePreviewOutput');
}
public setPhotoOutput(photoOutput: PhotoOutputWrap): void {
if (!photoOutput) {
HiLog.w(TAG, 'photoOutput is null.');
return;
}
this.mPhotoOutput = photoOutput;
}
public isHasOtherOutput(): boolean {
return this.hasOtherOutput;
}
public setMetadataOutput(metadataOutput: MetadataOutputWrap): void {
if (!metadataOutput) {
HiLog.w(TAG, 'metadataOutput is null.');
return;
}
this.mMetadataOutput = metadataOutput;
}
public hasFlash(): boolean {
return this.mHasFlash;
}
public setFlashMode(flashMode: camera.FlashMode): void {
HiLog.i(TAG, `setFlashMode: ${flashMode}.`);
try {
this.mSession.setFlashMode(flashMode);
} catch (err) {
HiLog.e(TAG, `setFlashMode err: ${simpleStringify(err)}`);
}
}
public setStitchingType(stitchingType: camera.StitchingType): void {
HiLog.i(TAG, `setStitchingType: ${stitchingType}.`);
try {
this.mSession.setStitchingType(stitchingType);
} catch (err) {
HiLog.e(TAG, `setStitchingType err: ${simpleStringify(err)}`);
}
}
public setStitchingDirection(stitchingDirection: camera.StitchingDirection): void {
HiLog.i(TAG, `setStitchingDirection: ${stitchingDirection}.`);
try {
this.mSession.setStitchingDirection(stitchingDirection);
} catch (err) {
HiLog.e(TAG, `setStitchingDirection err: ${simpleStringify(err)}`);
}
}
public setMovingClockwise(stitchingMove: boolean): void {
HiLog.i(TAG, `setMovingClockwise: ${stitchingMove}.`);
try {
this.mSession.setMovingClockwise(stitchingMove);
} catch (err) {
HiLog.e(TAG, `setMovingClockwise err: ${simpleStringify(err)}`);
}
}
public setZoomRatio(zoomRatio: number): void {
HiLog.d(TAG, `setZoomRatio: ${zoomRatio}.`);
if (!!zoomRatio) {
this.mSession.setZoomRatio(zoomRatio);
this.mMetadataOutput?.setZoomRatio(zoomRatio);
}
}
public getZoomRatio(): number {
const zoomRatio: number = this.mSession.getZoomRatio();
HiLog.i(TAG, `getZoomRatio: ${zoomRatio}.`);
return zoomRatio;
}
public getZoomRatioRange(): number[] | undefined {
HiLog.i(TAG, `getZoomRatioRange: ${JSON.stringify(this.mZoomRatioRange)}.`);
return this.mZoomRatioRange;
}
public isFocusModeSupported(focusMode: number): boolean {
const isSupported: boolean = this.mSession.isFocusModeSupported(focusMode);
HiLog.i(TAG, `focusMode: ${focusMode} is isSupported: ${isSupported}.`);
return isSupported;
}
public setFocusMode(focusMode: number, focusPoint: camera.Point, focusValue?: number): void {
HiLog.i(TAG,
`setFocusMode, focusMode: ${focusMode}, focusPoint: ${simpleStringify(focusPoint)},focusValue: ${focusValue}.`);
if (focusMode !== undefined) {
this.mSession.setFocusMode(focusMode);
}
if (focusPoint) {
this.mSession.setFocusPoint(focusPoint);
}
if (focusMode === camera.FocusMode.FOCUS_MODE_MANUAL) {
this.mSession.setFocusDistance(focusValue);
}
}
public isExposureModeSupported(exposureMode: number): boolean {
const isSupported: boolean = this.mSession.isExposureModeSupported(exposureMode);
HiLog.i(TAG, `focusMode: ${exposureMode} is isSupported: ${isSupported}.`);
return isSupported;
}
public setExposure(data: ExposureData): void {
HiLog.i(TAG,
`setExposure, exposureMode: ${data.exposureMode}, exposurePoint: ${data.exposurePoint},exposureValue: ${data.exposureValue}.`);
if (data.exposureMode !== undefined && this.mSession.isExposureModeSupported(data.exposureMode)) {
this.mSession.setExposureMode(data.exposureMode);
}
if (data.exposurePoint) {
this.mSession.setMeteringPoint(data.exposurePoint);
}
if (data.exposureValue !== undefined) {
this.mSession.setExposureBias(data.exposureValue);
}
}
private handleFocusStateCallback = async (err: any, state: camera.FocusState): Promise<void> => {
if (err) {
HiLog.d(TAG, `handleFocusStateCallback focusStateChange, err: ${err}.`);
} else {
HiLog.limitLog(TAG, `handleFocusStateCallback focusStateChange, state: ${state}.`, 'workerFocusStateLogKey');
workerCallback.updateFocusState(state);
}
}
private handleFocusStateChangeOn(): void {
HiLog.i(TAG, 'handleFocusStateChangeOn E.');
this.mSession.on('focusStateChange', this.handleFocusStateCallback);
}
public setMeteringPoint(focusPoint: camera.Point): void {
HiLog.i(TAG, `setMeteringPoint, focusPoint: ${JSON.stringify(focusPoint)}.`);
this.mSession.setMeteringPoint(focusPoint);
}
public setXmage(value: number): void {
HiLog.i(TAG, `setXmage value: ${value}`);
this.mSession.setColorEffect(value === -1 ? 0 : value);
}
public getXmage(): number {
return this.mSession.getColorEffect();
}
public getSupportedColorEffects(): camera.ColorEffectType[] {
return this.mSession.getSupportedColorEffects();
}
public isNightSupportedColorEffects(): boolean {
return this.mSession.getSupportedColorEffects()?.length > 1;
}
public getSessionFunctions(outputCapability: camera.CameraOutputCapability): camera.NightPhotoFunctions[] {
return this.mSession.getSessionFunctions(outputCapability);
}
public getSessionConflictFunctions(): camera.NightPhotoConflictFunctions[] {
return this.mSession.getSessionConflictFunctions();
}
public hasXmage(): boolean {
return this.mSession.getSupportedColorEffects()?.length > 0;
}
public getSupportedPortraitEffects(): number[] {
return this.mSession.getSupportedPortraitEffects();
}
public getPortraitEffect(): number {
return this.mSession.getPortraitEffect();
}
public setPortraitEffect(value: number): void {
HiLog.i(TAG, `setPortraitEffect value: ${value}.`);
this.mSession.setPortraitEffect(value);
}
public getSupportedBeautyTypes(): camera.BeautyType[] {
return this.mSession.getSupportedBeautyTypes();
}
public getSupportedBeautyRange(beautyType: camera.BeautyType): number[] {
return this.mSession.getSupportedBeautyRange(beautyType);
}
public checkIsCustomFilterSupported(): boolean {
this.mIsColorStyleSupport = this.mSession.isColorStyleSupported();
return this.mIsColorStyleSupport;
}
public getDefaultColorStyleSettings(): camera.ColorStyleSetting[] {
if (!this.mIsColorStyleSupport) {
HiLog.w(TAG, `getDefaultColorStyleSettings in unsupport mode: ${this.mMode}`);
return [];
}
const defaultSettings: camera.ColorStyleSetting[] = this.mSession.getDefaultColorStyleSettings();
HiLog.i(TAG, `getDefaultColorStyleSettings: ${JSON.stringify(defaultSettings)}`)
return defaultSettings ? defaultSettings : [];
}
public setColorStyleSetting(setting: camera.ColorStyleSetting): void {
if (!this.mIsColorStyleSupport) {
HiLog.w(TAG, `setColorStyleSetting in unsupport mode: ${this.mMode}`);
return;
}
this.mSession.setColorStyleSetting(setting);
}
public getColorStyleSetting(): camera.ColorStyleSetting {
if (!this.mIsColorStyleSupport) {
HiLog.w(TAG, `setColorStyleSetting in unsupport mode: ${this.mMode}`);
return null;
}
const currentSetting: camera.ColorStyleSetting = this.mSession.getColorStyleSetting();
HiLog.i(TAG, `getColorStyleSetting: ${JSON.stringify(currentSetting)}`);
return currentSetting;
}
public getBeauty(beautyType: camera.BeautyType): number {
return this.mSession.getBeauty(beautyType);
}
public setBeauty(beautyType: camera.BeautyType, beautyValue: number): void {
HiLog.i(TAG, `setBeauty beautyType: ${beautyType}, beautyValue: ${beautyValue}.`);
this.mSession.setBeauty(beautyType, beautyValue);
}
public setPortraitThemeType(ThemeType: number): void {
HiLog.i(TAG, `setBeauty ThemeType: ${ThemeType}.`);
this.mSession.setPortraitThemeType(ThemeType);
}
public getSupportedLightPaintings(): number[] {
return this.mSession.getSupportedLightPaintings();
}
public getLightPainting(): number {
return this.mSession.getLightPainting();
}
public setLightPainting(value: number): void {
this.mSession.setLightPainting(value);
}
public triggerLighting(): void {
this.mSession.triggerLighting();
}
public getExposureBiasRange(): number[] {
let exposureBiasRange = this.mSession.getExposureBiasRange();
return exposureBiasRange;
}
public getSupportedExposureRange(): number[] {
const exposureRange: number[] = this.mSession.getSupportedExposureRange();
HiLog.i(TAG, `getSupportedExposureRange: ${exposureRange ? JSON.stringify(exposureRange) : -1}`);
return exposureRange ? exposureRange : [];
}
public getExposure(): number {
return this.mSession.getExposure();
}
public getSupportedColorSpaces(): colorSpaceManager.ColorSpace[] {
return this.mSession.getSupportedColorSpaces();
}
public setExposureValue(exposureValue: number): void {
HiLog.i(TAG, `setExposureValue exposureValue: ${exposureValue}, mMode: ${this.mMode}.`);
this.mSession.setExposureDuration(exposureValue);
}
public getExposureMode(): camera.ExposureMode {
let curExposureMode = this.mSession.getExposureMode();
return curExposureMode;
}
private handleTimeLapseModeSessionOff(): void {
this.mTryAeInfo = undefined;
this.mIsInTryAe = false;
try {
this.mSession?.off('isoInfoChange', this.mIsoInfoCallback);
this.mSession?.off('exposureInfoChange', this.mExposureInfoCallback);
this.mSession?.off('luminationInfoChange', this.mLuminationCallback);
this.mSession?.off('error', this.mTimeLapseErrorCallback);
this.mSession?.off('tryAEInfoChange', this.mTryAeCallback);
this.mSession?.off('abilityChange', this.mAbilityChangeCallback);
HiLog.d(TAG, 'handleTimeLapseModeSessionOff');
} catch (e) {
HiLog.e(TAG, `handleTimeLapseModeSessionOff err:${e}`);
}
}
private handleStitchingModeSessionOff(): void {
try {
HiLog.i(TAG, `stitching session off`);
} catch (e) {
HiLog.e(TAG, `handlePassionModeSessionOff err:${e}`);
}
}
private handleTimeLapseModeSessionOn(mode: ModeType): void {
this.mIsInTryAe = false;
this.mTryAeInfo = undefined;
const targetCamera: camera.CameraDevice = this.mCameraContext.getCamera();
const cameraPosition = targetCamera.cameraPosition;
const isBack: boolean = cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK;
HiLog.i(TAG, `timeLapseVideo regester callback mode: ${mode}, isBakcCamera: ${isBack}`);
try {
this.mSession?.on('isoInfoChange', this.mIsoInfoCallback);
this.mSession?.on('exposureInfoChange', this.mExposureInfoCallback);
this.mSession?.on('luminationInfoChange', this.mLuminationCallback);
this.mSession?.on('error', this.mTimeLapseErrorCallback);
this.mSession?.on('tryAEInfoChange', this.mTryAeCallback);
this.mSession?.on('abilityChange', this.mAbilityChangeCallback);
} catch (error) {
HiLog.e(TAG, `timeLapseVideo register callback error: ${error.code}`);
}
}
private handleNightSubModeOff() {
if (this.getSupportedNightSubModeTypes().length > 0) {
this.handleImageStabilizationGuideOff();
this.handleConstellationDrawingOff();
}
try {
this.mSession?.off('abilityChange', this.mAbilityChangeCallback);
} catch (error) {
HiLog.e(TAG, `NightSubMode register callback error: ${error.code}`);
}
}
private handleStitchingModeSessionOn(mode: ModeType): void {
try {
HiLog.i(TAG, `stitching session on`);
} catch (error) {
HiLog.e(TAG, `stitching register callback error: ${error.code}`);
}
}
private handleCinemaSessionOn(mode: ModeType): void {
if (this.mCameraContext.getCameraPosition() !== camera.CameraPosition.CAMERA_POSITION_BACK) {
return;
}
try {
this.mSession?.on('apertureEffectChange', (error: BusinessError<void>, effect: camera.ApertureEffect) => {
HiLog.i(TAG, `cinema apertureEffectChange: ${effect}.`);
workerCallback.apertureEffectChange(effect);
});
HiLog.i(TAG, 'cinema session on');
} catch (error) {
HiLog.e(TAG, `cinema register callback error: ${error.code}`);
}
}
private handleCinemaSessionOff(): void {
try {
this.mSession?.off('apertureEffectChange');
} catch (error) {
HiLog.e(TAG, `cinema apertureEffectChange callback error: ${error.code}`);
}
}
private startCaptureLoop(captureInterval: number): void {
this.mTimeLapseStopCapture = false;
this.captureTimelapseFun();
this.timeLapseTimerId = setInterval(this.captureTimelapseFun, Math.max(captureInterval, TIME_LAPSE_MIN_INTERVAL));
}
public stopCaptureLoop(): void {
this.mTimeLapseStopCapture = true;
this.clearTimeLapseInterval();
this.timeLapseTimerId = Number.MIN_VALUE;
this.mSession?.setTimeLapseRecordState(camera.TimeLapseRecordState.IDLE);
HiLog.w(TAG, 'stopCaptureLoop E.');
}
private clearTimeLapseInterval(): void {
if (Number.MIN_VALUE !== this.timeLapseTimerId) {
clearInterval(this.timeLapseTimerId);
}
}
private handleProfessionOn(mode: ModeType): void {
this.mSession?.on('isoInfoChange', this.mIsoInfoCallback);
this.mSession?.on('exposureInfoChange', this.mExposureInfoCallback);
this.mSession?.on('apertureInfoChange', this.mApertureInfoCallback);
this.mSession?.on('luminationInfoChange', this.mLuminationCallback);
this.mSession?.on('abilityChange', this.mAbilityChangeCallback);
}
private handleProfessionOff(): void {
try {
this.mSession?.off('isoInfoChange', this.mIsoInfoCallback);
this.mSession?.off('exposureInfoChange', this.mExposureInfoCallback);
this.mSession?.off('apertureInfoChange', this.mApertureInfoCallback);
this.mSession?.off('luminationInfoChange', this.mLuminationCallback);
this.mSession?.off('abilityChange', this.mAbilityChangeCallback);
HiLog.d(TAG, 'handleProfessionOff');
} catch (e) {
HiLog.e(TAG, `handleProfessionOff err:${e}`);
}
}
public getExposureValue(): number {
let curExposureValue = this.mSession.getExposureValue();
return curExposureValue;
}
public setExposureMode(exposureMode: camera.ExposureMode): void {
HiLog.i(TAG, `setExposureMode exposureMode: ${exposureMode}.`);
this.mSession.setExposureMode(exposureMode);
}
public setExposureBias(value: number): void {
HiLog.i(TAG, `setExposureBias value: ${value}.`);
this.mSession.setExposureBias(value);
}
public enableMacro(enable: boolean): void {
HiLog.i(TAG, `enableMacro [SuperMacro] enable: ${enable}.`);
try {
this.mSession.enableMacro(enable);
} catch (err) {
HiLog.e(TAG, `enableMacro [SuperMacro] set fail..., ${simpleStringify(err)}`);
}
}
public isStageBoostSupported(): boolean {
let isStageSupported = this.mSession.isStageBoostSupported();
return isStageSupported;
}
public enableStageBoost(enable: boolean): void {
HiLog.i(TAG, `enableStageBoost [Stage] enable: ${enable}.`);
try {
this.mSession.enableStageBoost(enable);
} catch (err) {
HiLog.e(TAG, `enableStageBoost [Stage] set fail..., ${simpleStringify(err)}`);
}
}
private handleMacroAbilityOn(mode: ModeType): void {
if (mode !== ModeType.PHOTO && mode !== ModeType.VIDEO) {
return;
}
this.mIsMacroSupported = this.mSession.isMacroSupported();
HiLog.i(TAG, `handleMacroAbilityOn [SuperMacro] mIsMacroSupported: ${this.mIsMacroSupported}`);
this.mSession.on('macroStatusChanged', this.mSuperMacroIconVisibleCallback);
}
private handleMacroAbilityOff(): void {
try {
this.mSession.off('macroStatusChanged', this.mSuperMacroIconVisibleCallback);
HiLog.d(TAG, 'handleMacroAbilityOff');
} catch (e) {
HiLog.e(TAG, `handleMacroAbilityOff err:${e}`);
}
}
public prepareZoom(): void {
this.mSession.prepareZoom();
}
public unPrepareZoom(): void {
this.mSession.unprepareZoom();
}
public setSmoothZoom(targetRatio: number): void {
HiLog.i(TAG, `setSmoothZoom: ${targetRatio}`);
if (!!targetRatio) {
this.mSession.setSmoothZoom(targetRatio, 0);
this.mMetadataOutput?.setZoomRatio(targetRatio);
}
}
public getIsDeferPhoto(): boolean {
return this.mIsDeferPhoto;
}
public getIsDeferVideo(): boolean {
return this.mIsDeferVideo;
}
public isSceneFeatureSupported(scene: camera.SceneFeatureType): boolean {
const result: boolean = this.mSession.isSceneFeatureSupported(scene);
HiLog.i(TAG, `get sceneFeature: ${scene}, result: ${result}`);
return result;
}
public async enableSceneFeature(scene: camera.SceneFeatureType, enabled: boolean): Promise<void> {
HiLog.i(TAG, `enableSceneFeature enable: ${enabled}.`);
try {
this.mSession.enableSceneFeature(scene, enabled);
} catch (err) {
HiLog.e(TAG, 'enableSceneFeature set fail...');
}
}
private handleSceneFeatureOn(type: camera.SceneFeatureType): void {
const isSupported: boolean = this.mSession.isSceneFeatureSupported(type);
if (isSupported) {
this.mSession.on('featureDetectionStatus', this.mSceneFeatureCallBack, type);
}
HiLog.i(TAG, `handleSceneFeatureOn type: ${type}, isSupported: ${isSupported}.`);
this.mIsSceneFeatureSupported = this.mIsSceneFeatureSupported || isSupported;
HiLog.i(TAG, `handleSceneFeatureOn mIsSceneFeatureSupported: ${this.mIsSceneFeatureSupported}.`);
}
private handleScenesFeatureOn(mode: ModeType): void {
if (mode !== ModeType.PHOTO) {
return;
}
this.handleSceneFeatureOn(camera.SceneFeatureType.MOON_CAPTURE_BOOST);
this.handleSceneFeatureOn(camera.SceneFeatureType.TRIPOD_DETECTION);
this.handleSceneFeatureOn(camera.SceneFeatureType.LOW_LIGHT_BOOST);
};
private handleSceneFeatureOff(): void {
try {
this.mSession?.off('featureDetectionStatus', this.mSceneFeatureCallBack);
HiLog.d(TAG, 'handleSceneFeatureOff');
} catch (e) {
HiLog.e(TAG, `handleSlowMotionOff err:${e}`);
}
}
public getSupportedVirtualApertures(): number[] {
HiLog.i(TAG, 'getSupportedVirtualApertures E');
let supportedVirtualApertures = this.mSession.getSupportedVirtualApertures();
HiLog.i(TAG, `getSupportedVirtualApertures X`);
return supportedVirtualApertures;
}
public getVirtualAperture(): number {
let virtualAperture = this.mSession.getVirtualAperture();
return virtualAperture;
}
public setVirtualAperture(value: number): void {
HiLog.i(TAG, 'setVirtualAperture: ' + value);
this.mSession.setVirtualAperture(value);
}
public getSupportedPhysicalApertures(): camera.PhysicalAperture[] {
HiLog.i(TAG, 'getSupportedPhysicalApertures E');
try {
let supportedPhysicalApertures = this.mSession.getSupportedPhysicalApertures();
HiLog.i(TAG, `getSupportedPhysicalApertures `);
return supportedPhysicalApertures;
} catch (err) {
HiLog.e(TAG, 'getSupportedPhysicalApertures' + simpleStringify(err));
return [];
}
}
public getIsPortraitThemeSupported(): boolean {
let isPortraitThemeSupported = this.mSession.getIsPortraitThemeSupported();
return isPortraitThemeSupported;
}
public getPhysicalAperture(): number {
let physicalAperture = this.mSession.getPhysicalAperture();
return physicalAperture;
}
public setPhysicalAperture(value: number): void {
HiLog.i(TAG, 'setPhysicalAperture: ' + value);
this.mSession.setPhysicalAperture(value);
}
public getExposureMeteringMode(): number {
let exposureMeteringMode = this.mSession.getExposureMeteringMode();
return exposureMeteringMode;
}
public setExposureMeteringMode(meteringValue: number): void {
HiLog.i(TAG, 'setExposureMeteringMode meteringValue: ' + meteringValue);
this.mSession.setExposureMeteringMode(this.number2MeteringMode(meteringValue));
}
private number2MeteringMode(meteringValue: number): camera.ExposureMeteringMode {
let mode: camera.ExposureMeteringMode;
switch (meteringValue) {
case 0:
mode = camera.ExposureMeteringMode.MATRIX;
break;
case 1:
mode = camera.ExposureMeteringMode.CENTER;
break;
case 2:
mode = camera.ExposureMeteringMode.SPOT;
break;
default:
mode = camera.ExposureMeteringMode.MATRIX;
}
return mode;
}
public setApertureValue(Aperture: number): void {
HiLog.i(TAG, `setAperatureValue Aperature: ${Aperture}.`);
this.mSession.setApertureValue(Aperture);
}
public getAuxiliary(): boolean {
let auxiliary = this.mSession.getFocusAssist();
return auxiliary;
}
public setAuxiliary(auxiliaryValue: number): void {
HiLog.i(TAG, `setAuxiliary auxiliaryValue: ${auxiliaryValue} .`);
this.mSession.setFocusAssist(auxiliaryValue);
}
public setExposureDuration(exposureValue: number): void {
HiLog.i(TAG, `setExposureDuration exposureValue: ${exposureValue}.`);
this.mSession.setExposureDuration(exposureValue);
}
public getExposureDuration(): camera.ExposureMode {
let curExposureMode = this.mSession.getExposureDuration();
return curExposureMode;
}
public getIsoValue(): number {
let curIso = this.mSession.getIso();
return curIso;
}
public setIsoValue(isoValue: number): void {
HiLog.i(TAG, `setIsoValue isoValue: ${isoValue}.`);
this.mSession.setIso(isoValue);
}
public getWhiteBalanceMode(): number {
let whiteBalanceMode = this.mSession.getWhiteBalanceMode();
return whiteBalanceMode;
}
public getWhiteBalance(): number {
let curIso = this.mSession.getWhiteBalance();
return curIso;
}
public setWhiteBalance(whiteBalanceValue: number): void {
HiLog.i(TAG, `setWhitebalance whitebalanceValue: ${whiteBalanceValue} .`);
this.mSession.setWhiteBalance(whiteBalanceValue);
}
public setSlowMotionDetectionArea(posData: camera.Rect): void {
if (this.mSession.isSlowMotionDetectionSupported()) {
HiLog.i(TAG, `set superSlowMotion detection box position data:${JSON.stringify(posData)}`);
this.mSession.setSlowMotionDetectionArea(posData);
}
}
private handleSlowZoomChangeOn(): void {
try {
this.mSession.on('zoomInfoChange', this.watchSlowZoomRangeCallback);
} catch (e) {
HiLog.e(TAG, `handleSlowMotionOn zoomInfoChange:${JSON.stringify(e)}`);
}
}
private async handleSlowMotionOn(mode: ModeType, isSuperSlowMotion: boolean): Promise<void> {
WorkerDataCache.getInstance().setMotionStateForRecord(true);
this.handleSlowZoomChangeOn();
if (isSuperSlowMotion) {
const superDetectionPos: camera.Rect = {
topLeftX: -1.0,
topLeftY: -1.0,
width: -1.0,
height: -1.0,
};
this.setSlowMotionDetectionArea(superDetectionPos);
if (this.mSession.isSlowMotionDetectionSupported()) {
this.mSession.on('slowMotionStatus', this.watchSuperMotionStatusCallback);
}
}
}
private handleSlowMotionOff(): void {
try {
this.mSession.off('slowMotionStatus');
this.mSession.off('zoomInfoChange');
HiLog.d(TAG, 'handleSlowMotionOff');
} catch (e) {
HiLog.e(TAG, `handleSlowMotionOff err:${e}`);
}
}
public handleConstellationDrawingOn(): void {
try {
this.mSession.on('featureDetection', this.mConstellationDraw, camera.SceneFeatureType.CONSTELLATION_DRAWING);
HiLog.i(TAG, 'on ConstellationDrawing');
} catch (e) {
HiLog.e(TAG, `on ConstellationDrawing err:${e}`);
}
}
public handleConstellationDrawingOff(): void {
if (this.mSession.isSceneFeatureSupported(camera.SceneFeatureType.CONSTELLATION_DRAWING)) {
try {
this.mSession.off('featureDetection', this.mConstellationDraw);
HiLog.i(TAG, 'off ConstellationDrawing');
} catch (e) {
HiLog.e(TAG, `off ConstellationDrawing err:${e}`);
}
}
}
private handleLcdFlashStatusOn(): void {
if (this.mSession.isLcdFlashSupported()) {
this.mSession.on('lcdFlashStatus', this.mWatchLcdStatusCallback);
}
}
private handleLcdFlashStatusOff(): void {
try {
this.mSession.off('lcdFlashStatus', this.mWatchLcdStatusCallback);
HiLog.d(TAG, 'handleLcdFlashStatusOff');
} catch (e) {
HiLog.e(TAG, `handleLcdFlashStatusOff err:${e}`);
}
}
private handleImageStabilizationGuideOn(): void {
if (this.mSession.isImageStabilizationGuideSupported()) {
try {
} catch (e) {
HiLog.e(TAG, `on imageStabilizationGuide err:${e}`);
}
}
}
private handleImageStabilizationGuideOff(): void {
if (this.mSession.isImageStabilizationGuideSupported()) {
try {
HiLog.d(TAG, 'handleImageStabilizationGuideOff');
} catch (e) {
HiLog.e(TAG, `handleImageStabilizationGuideOff err:${e}`);
}
}
}
public isImageStabilizationGuideSupported(): boolean {
let isSupported: boolean = this.mSession.isImageStabilizationGuideSupported();
HiLog.i(TAG, `isImageStabilizationGuideSupported: ${isSupported}`);
return isSupported;
}
public enableImageStabilizationGuide(enabled: boolean): void {
HiLog.i(TAG, `enableImageStabilizationGuide: ${enabled}`);
this.mSession.enableImageStabilizationGuide(enabled);
}
public getZoomPointInfo(): ZoomPointInfo {
return this.mZoomPointInfo;
}
public getFocusDistance(): number {
let focusDistance = this.mSession.getFocusDistance();
HiLog.i(TAG, `getFocusDistance focusDistance: ${focusDistance}`);
return focusDistance;
}
public getIsoRange(): number[] {
return this.mSession.getIsoRange();
}
private handleEffectSuggestionChangeOn(mode: ModeType): void {
if (mode !== ModeType.PHOTO && mode !== ModeType.VIDEO) {
return;
}
this.mIsEffectSuggestionSupported = this.mSession.isEffectSuggestionSupported();
HiLog.i(TAG, `handleEffectSuggestionChangeOn isEffectSuggestionSupported: ${this.mIsEffectSuggestionSupported}.`);
if (this.mIsEffectSuggestionSupported) {
this.mSession.enableEffectSuggestion(true);
}
};
private handleEffectSuggestionChangeOff(): void {
try {
HiLog.d(TAG, 'handleEffectSuggestionChangeOff');
} catch (e) {
HiLog.e(TAG, `handleEffectSuggestionChangeOff err:${e}`);
}
}
public setTimeLapseInterval(interval: number): void {
this.mSession.setTimeLapseInterval(interval);
}
public getTimeLapseInterval(): number {
return this.mSession.getTimeLapseInterval();
}
public getTimeLapseIntervalRange(): number[] {
return this.mSession.getTimeLapseIntervalRange();
}
public setTimeLapseRecordState(state: camera.TimeLapseRecordState): void {
this.mSession.setTimeLapseRecordState(state);
}
private handleSmoothZoomInfoAvailableOff(): void {
try {
this.mSession?.off('smoothZoomInfoAvailable', this.mSmoothZoomInfoCallback);
HiLog.d(TAG, 'handleSmoothZoomInfoAvailableOff');
} catch (e) {
HiLog.e(TAG, `handleSmoothZoomInfoAvailableOff err:${e}`);
}
}
private setSessionUsage(tagMessage): void {
}
public setAudioZoomExtra(value: Record<string, string>): void {
this.mSession?.setAudioZoomExtra(value);
HiLog.i(TAG, 'SessionWrap setUsage AudioZoom.');
}
public setShortVideoIndex(index: number): void {
HiLog.i(TAG, 'setShortVideoIndex' + index);
}
public getFocusRange(): camera.FocusRangeType {
return this.mSession.getFocusRange();
}
public setFocusRange(type: camera.FocusRangeType): void {
this.mSession.setFocusRange(type);
HiLog.i(TAG, 'SessionWrap setUsage AudioZoom.');
}
public getFocusDriven(): camera.FocusDrivenType {
return this.mSession.getFocusDriven();
}
public setFocusDriven(type: camera.FocusDrivenType): void {
this.mSession.setFocusDriven(type);
HiLog.i(TAG, 'SessionWrap setFocusDriven.');
}
public setFocusTrackingMode(mode: camera.FocusTrackingMode): void {
this.mSession.setFocusTrackingMode(mode);
HiLog.i(TAG, 'SessionWrap setFocusTrackingMode.');
}
public getColorReservation(): camera.ColorReservationType {
return this.mSession.getColorReservation();
}
public setColorReservation(type: camera.ColorReservationType): void {
this.mSession.setColorReservation(type);
HiLog.i(TAG, 'SessionWrap setColorReservation.');
}
public setWindNoiseSuppression(value: Record<string, string>): void {
this.mSession.setWindNoiseSuppression(value);
HiLog.i(TAG, 'SessionWrap setUsage WindNoiseSuppression.');
}
public getIsCompositionSuggestionSupported(): boolean {
let isCompositionSuggestionSupported = this.mSession.getIsCompositionSuggestionSupported();
return isCompositionSuggestionSupported;
}
private handleCompositionBeginNotice: AsyncCallback<void> =
(err) => {
HiLog.i(TAG, `onRecvAICompositionBeginNotice`);
workerCallback.onRecvAICompositionBeginNotice();
};
private handleCompositionCalibrationData: AsyncCallback<camera.CompositionCalibrationInfo> =
(err, data: camera.CompositionCalibrationInfo) => {
workerCallback.onRecvAICompositionCalibrationData(data);
};
private handleCompositionConfig: AsyncCallback<camera.CompositionConfigInfo> =
(err, data: camera.CompositionConfigInfo) => {
workerCallback.onRecvAICompositionConfigData(data);
};
private handleCompositionEnd: AsyncCallback<camera.CompositionEndInfo> = (err, data: camera.CompositionEndInfo) => {
workerCallback.onRecvAICompositionEndData(data);
};
public enableCompositionSuggestion(enable: boolean): void {
this.mIsCompositionSuggestionSupported = this.mSession.getIsCompositionSuggestionSupported();
HiLog.i(TAG, `enableCompositionSuggestion mIsCompositionSuggestionSupported: ` +
`${this.mIsCompositionSuggestionSupported}, enable: ${enable}`);
if (!this.mIsCompositionSuggestionSupported) {
return;
}
if (enable) {
this.mSession.enableCompositionSuggestion(true);
this.handleCompositionSuggestionOn();
} else {
this.handleCompositionSuggestionOff();
this.mSession.enableCompositionSuggestion(false);
}
}
private handleCompositionSuggestionOn(): void {
try {
this.mSession?.on('compositionBegin', this.handleCompositionBeginNotice);
this.mSession?.on('compositionCalibration', this.handleCompositionCalibrationData);
this.mSession?.on('compositionConfig', this.handleCompositionConfig);
this.mSession?.on('compositionEnd', this.handleCompositionEnd);
HiLog.d(TAG, 'handleCompositionSuggestionOn success.');
} catch (e) {
HiLog.e(TAG, `handleCompositionSuggestionOn err:${e}`);
}
}
private handleCompositionSuggestionOff(): void {
try {
this.mSession?.off('compositionBegin');
this.mSession?.off('compositionCalibration');
this.mSession?.off('compositionConfig');
this.mSession?.off('compositionEnd');
HiLog.d(TAG, 'handleCompositionSuggestionOff success.');
} catch (e) {
HiLog.e(TAG, `handleCompositionSuggestionOff err:${e}`);
}
}
public handleLightStatusOn(): void {
HiLog.i(TAG, 'handleLightStatusOn');
try {
this.mSession?.on('lightStatusChange', this.handleLightStatusCallback);
} catch (e) {
HiLog.e(TAG, `handleLightStatusOn err:${e}`);
}
}
public handleLightStatusOff(): void {
HiLog.i(TAG, 'handleLightStatusOff');
try {
this.mSession?.off('lightStatusChange');
workerCallback.onRecvLightStatusData(LightStatus.DEFAULT);
} catch (e) {
HiLog.e(TAG, `handleLightStatusOff err:${e}`);
}
}
private handleLightStatusCallback: AsyncCallback<camera.LightStatus> =
(err, data: camera.LightStatus) => {
if (err) {
HiLog.e(TAG, `handleLightStatusOff err: ${simpleStringify(err)}}`);
return;
}
HiLog.i(TAG, `lightStatusCallback: ${data}`);
workerCallback.onRecvLightStatusData(data);
};
private sessionAddOutputWrap(output): void {
let canAddOutput = this.mSession.canAddOutput(output);
HiLog.i(TAG, `sessionAddOutputWrap canAddOutput: ${canAddOutput}`);
if (canAddOutput) {
this.mSession.addOutput(output);
} else {
this.mCanAddOutput = false;
HiLog.e(TAG, `sessionAddOutputWrap failed!`);
}
}
public getCanAddOutput(): boolean {
if (!this.mCanAddOutput) {
this.mCanAddOutput = true;
return false;
}
return this.mCanAddOutput;
}
public setFilterType(filterType: number): void {
HiLog.i(TAG, `setFilterType: ${filterType}`);
this.mSession.setFilterType(filterType);
}
public setEffectAudioStage(isSupportAudioStage: boolean): void {
if (isSupportAudioStage) {
this.mSession?.setAudioEffectStage(true);
HiLog.i(TAG, 'setAudioEffectStage: True');
} else {
this.mSession?.setAudioEffectStage(false);
HiLog.i(TAG, 'setAudioEffectStage: False');
}
}
}