Device & Resolution
Device & Resolution
Hosanna exposes a device abstraction that reports UI resolution and quality. Resolution info drives resource selection and can influence image URI resolution.
Platform-Neutral Device Facade
IHosannaDevice provides cross-platform access to four key areas:
export interface IHosannaDevice {
configure(): unknown;
onSystemDeviceInfoEvent(event: ISystemEvent<JsonData>): unknown;
/** Information about the device. */
deviceInfo: ISGRODeviceInfo;
/** The device registry for storing key-value pairs. */
deviceRegistry: IDeviceRegistry;
/** Information about the application running on the device. */
appInfo: ISGROAppInfo;
resolutionInfo: IResolutionInfo
}
- deviceRegistry: Platform-neutral key-value storage for your app. Use it for tokens, flags, and lightweight settings.
- deviceInfo: Low-level device information (UI resolution, model, etc.).
- appInfo: Metadata about the running app/build.
- resolutionInfo: Normalized resolution details used by Hosanna (see below).
IResolutionInfo
export interface IResolutionInfo {
suffix: string;
scale: number;
width: number;
height: number;
}
- suffix: Resolution suffix (e.g.,
fhd,hd,sd). - scale: Pixel scale relative to FHD (1.0 for FHD; 2/3 for HD; 1/3 for SD).
- width / height: UI resolution in pixels.
BaseHosannaDevice
BaseHosannaDevice resolves UI resolution and an overall device quality. You can override quality or supply a forced quality via the debug flag device.forcedDeviceQuality, which can be a value of DeviceQuality.Low, DeviceQuality.Medium, or DeviceQuality.High.
export class BaseHosannaDevice implements IHosannaDevice {
appInfo: ISGROAppInfo = CreateObject('roAppInfo');
deviceInfo: ISGRODeviceInfo = CreateObject('roDeviceInfo');
deviceQuality: DeviceQuality = DeviceQuality.High; // Default value, will be overridden in subclasses
@injectFlag('device.forcedDeviceQuality') forcedDeviceQuality?: DeviceQuality;
resolutionInfo: IResolutionInfo = {
suffix: 'fhd',
scale: 1.0,
width: 1920,
height: 1080,
};
@inject() deviceRegistry!: DeviceRegistry;
configure(): void {
this.resolutionInfo = this.getUIResolutionInfo();
this.deviceQuality = this.getDeviceQuality();
}
}
Resolution is derived from Roku roDeviceInfo.GetUIResolution() and adjusted for quality:
private getUIResolutionInfo(): IResolutionInfo {
const quality = this.getDeviceQuality();
const info = this.deviceInfo.GetUIResolution();
const realSuffix = info.name.toLowerCase();
const scale = realSuffix=== 'fhd' ? 1.0 : realSuffix=== 'hd' ? 2 / 3 : 1 / 3;
const suffix = quality === DeviceQuality.Low ? 'hd' : realSuffix;
return { suffix, scale, width: info.width, height: info.height };
}
Inject device.forcedDeviceQuality to quickly simulate low-end devices and test scaling.
@res Auto-Substitution (Roku)
On Roku, packaged resource URIs with @res auto-resolve based on manifest:
uri_resolution_autosub=@res,-sd,-hd,-fhd
Use pkg:/path/to/image@res.png and include the matching -sd, -hd, -fhd files in your package.
Remote URLs
Remote HTTP(S) URLs do not go through Roku auto-substitution. Use resolveImageUri(url) to replace @res with a concrete suffix and to normalize pkg:/ URIs on web:
export function resolveImageUri(uri: string): string {
const normalizedUri = normalizePkgUri(uri);
return normalizedUri?.replace('@res', '-fhd') ?? '';
}