137 lines
6.0 KiB
Plaintext
137 lines
6.0 KiB
Plaintext
/*
|
|
* Copyright (C) 2025 Huawei Device Co., Ltd.
|
|
* 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 { FileCache } from '../cache/FileCache';
|
|
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
|
|
import {
|
|
ImageKnifeData,
|
|
ImageKnifeRequestSource,
|
|
ImageKnifeRequestWithSource,
|
|
RequestJobRequest,
|
|
TimeInfo
|
|
} from '../model/ImageKnifeData';
|
|
import http from '@ohos.net.http';
|
|
import { ImageKnifeLoader } from '../ImageKnifeLoader';
|
|
import { combineArrayBuffers } from '../utils/ArrayBufferUtils';
|
|
import { BusinessError, emitter } from '@kit.BasicServicesKit';
|
|
import { Constants, LoadPhase, LoadPixelMapCode } from '../utils/Constants';
|
|
import { LogUtil } from '../utils/LogUtil';
|
|
import List from '@ohos.util.List';
|
|
|
|
class RequestData {
|
|
public receiveSize: number = 2000
|
|
public totalSize: number = 2000
|
|
}
|
|
|
|
// HTTP加载策略
|
|
export class HttpLoaderStrategy implements IImageLoaderStrategy {
|
|
async loadImage(
|
|
request: RequestJobRequest,
|
|
requestList: List<ImageKnifeRequestWithSource> | undefined,
|
|
fileKey: string,
|
|
callBackData: ImageKnifeData,
|
|
callBackTimeInfo: TimeInfo
|
|
): Promise<void> {
|
|
let resBuf: ArrayBuffer | undefined;
|
|
let loadError: string = '';
|
|
|
|
// 从文件缓存获取
|
|
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_NET);
|
|
callBackTimeInfo.diskCheckStartTime = Date.now();
|
|
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder);
|
|
callBackTimeInfo.diskCheckEndTime = Date.now();
|
|
|
|
if (resBuf !== undefined) {
|
|
LogUtil.log(`success get image from filecache for key = ${fileKey} src = ${request.componentId},
|
|
srcType:${request.requestSource}, ${request.componentVersion}`);
|
|
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
|
|
} else if (request.onlyRetrieveFromCache !== true) {
|
|
LogUtil.log(`HttpDownloadClient.start: ${request.componentId}, srcType:${request.requestSource},
|
|
${request.componentVersion}`);
|
|
callBackTimeInfo.netRequestStartTime = Date.now();
|
|
const httpRequest = http.createHttp();
|
|
emitter.once((request.src as string) + request.componentId,()=>{
|
|
httpRequest.destroy()
|
|
})
|
|
let progress: number = 0;
|
|
const arrayBuffers: ArrayBuffer[] = [];
|
|
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request);
|
|
|
|
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
|
|
arrayBuffers.push(data);
|
|
});
|
|
|
|
if (request.isWatchProgress) {
|
|
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
|
|
if (data != undefined && typeof data.receiveSize === 'number' && typeof data.totalSize === 'number') {
|
|
const percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100);
|
|
if (progress !== percent) {
|
|
progress = percent;
|
|
if (requestList === undefined) {
|
|
// 子线程
|
|
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { 'value': progress } });
|
|
} else {
|
|
// 主线程请求
|
|
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
|
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
|
|
requestWithSource.source === ImageKnifeRequestSource.SRC) {
|
|
requestWithSource.request.imageKnifeOption.progressListener(progress);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
let promise = httpRequest.requestInStream(request.src as string, {
|
|
header: headerObj,
|
|
method: http.RequestMethod.GET,
|
|
expectDataType: http.HttpDataType.ARRAY_BUFFER,
|
|
connectTimeout: request.connectTimeout ?? 60000,
|
|
readTimeout: request.readTimeout ?? 30000,
|
|
caPath: request.caPath
|
|
});
|
|
promise.then((data: number) => {
|
|
emitter.off((request.src as string) + request.componentId)
|
|
callBackData.httpCode = data;
|
|
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined);
|
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
if (data == 200 || data == 206 || data == 204) {
|
|
resBuf = combineArrayBuffers(arrayBuffers);
|
|
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData);
|
|
} else {
|
|
loadError = 'HttpDownloadClient has error, http code =' + JSON.stringify(data);
|
|
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
|
|
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
|
|
}
|
|
}).catch((err: BusinessError) => {
|
|
emitter.off((request.src as string) + request.componentId)
|
|
callBackData.httpCode = err.code;
|
|
loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err);
|
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
|
|
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
|
|
});
|
|
LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' +
|
|
request.requestSource + ',' + request.componentVersion);
|
|
return;
|
|
} else {
|
|
callBackTimeInfo.netRequestEndTime = Date.now();
|
|
loadError = `onlyRetrieveFromCache, do not fetch image src = ${request.src}`;
|
|
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
|
|
return;
|
|
}
|
|
}
|
|
}
|