blob: 581c04306fefa58a55b6b74abcedb87050bc9332 [file] [log] [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {assert} from 'chrome://resources/js/assert.js';
import {ImageCache} from './cache.js';
import type {ImageTransformParam} from './image_orientation.js';
import {ImageOrientation} from './image_orientation.js';
import {ImageRequestTask} from './image_request_task.js';
import type {LoadImageRequest, LoadImageResponse} from './load_image_request.js';
import {Scheduler} from './scheduler.js';
let instance: ImageLoader|null = null;
/**
* Loads and resizes an image.
*/
export class ImageLoader {
/**
* Persistent cache object.
*/
private cache_: ImageCache = new ImageCache();
/**
* Manages pending requests and runs them in order of priorities.
*/
private scheduler_: Scheduler = new Scheduler();
constructor() {
// Initialize the cache and then start the scheduler.
this.cache_.initialize(() => this.scheduler_.start());
}
/**
* Handles a request. Depending on type of the request, starts or stops
* an image task.
* @return True if the message channel should stay alive until the
* sendResponse callback is called.
*/
handle(
request: LoadImageRequest,
sendResponse: (r: LoadImageResponse) => void): boolean {
assert(request.imageLoaderRequestId);
if (request.cancel) {
this.scheduler_.remove(request.imageLoaderRequestId);
return false;
}
// When manually debugging the Image Loader extension, you can reply with
// a placeholder image here by patching in https://crrev.com/c/5796592
// Sending a response may fail if the receiver already went offline.
// This is not an error, but a normal and quite common situation.
const failSafeSendResponse = function(response: LoadImageResponse) {
try {
sendResponse(response);
} catch (e) {
// Ignore the error.
}
};
// Incoming requests won't have the full type.
assert(!(request.orientation instanceof ImageOrientation));
assert(typeof request.orientation !== 'number');
if (request.orientation) {
request.orientation = ImageOrientation.fromRotationAndScale(
request.orientation as ImageTransformParam);
} else {
request.orientation = new ImageOrientation(1, 0, 0, 1);
}
// Add a new request task to the scheduler (queue).
this.scheduler_.add(new ImageRequestTask(
request.imageLoaderRequestId, this.cache_, request,
failSafeSendResponse));
return true;
}
/**
* Returns a singleton instance.
*/
static getInstance(): ImageLoader {
if (!instance) {
instance = new ImageLoader();
}
return instance;
}
}