Device & Resolution
Hosanna exposes a device abstraction that reports resolution, quality, layout expression, orientation, DPI, and host screen metrics. Use this facade when shared app code needs device information; avoid direct window, user-agent, or native checks inside views.
For the broader platform vocabulary and capability model, see Cross-Platform Runtime Model. For web launch parameters, see Web Expression, DPI, and Touch Input.
Platform-Neutral Device Facade
IHosannaDevice provides cross-platform access to device services and normalized metrics:
export interface IHosannaDevice {
configure(): unknown;
onSystemDeviceInfoEvent(event: ISystemEvent<JsonData>): unknown;
deviceInfo: ISGRODeviceInfo;
deviceRegistry: IDeviceRegistry;
appInfo: ISGROAppInfo;
resolutionInfo: IResolutionInfo;
deviceQuality: DeviceQuality;
expression: Expression;
deviceLayoutOrientation: DeviceLayoutOrientation;
deviceDpi: number;
devicePreset?: string;
screenInfo: IHosannaScreenInfo;
getScreenInfo(): IHosannaScreenInfo;
}
- deviceRegistry: Platform-neutral key-value storage for tokens, flags, and lightweight settings.
- deviceInfo: Low-level device information, including UI resolution and model details where the target supports them.
- appInfo: Metadata about the running app/build.
- resolutionInfo: Normalized resource-resolution details.
- deviceQuality: Coarse performance/quality tier.
- expression: Active app/layout expression:
tv,web,phone, ortablet. - deviceLayoutOrientation: Active design-surface orientation:
portraitorlandscape. - deviceDpi: Physical pixel width for the active design surface.
- devicePreset: Optional preset name that supplied web/bootstrap metrics.
- screenInfo: Host viewport, screen, DPR, and safe-area metrics.
ScreenInfo
screenInfo is distinct from the Hosanna design surface. It describes the actual browser, WebView, or native host viewport.
export interface IHosannaScreenInfo {
viewportWidth: number;
viewportHeight: number;
screenWidth: number;
screenHeight: number;
devicePixelRatio: number;
safeAreaInsets: {
top: number;
right: number;
bottom: number;
left: number;
};
}
On Web and Capacitor, the web device reads browser/WebView metrics and CSS env(safe-area-inset-*) values. Native targets can feed platform-native screen and cutout values through the same interface.
IResolutionInfo
export interface IResolutionInfo {
suffix: string;
scale: number;
width: number;
height: number;
}
- suffix: Resolution suffix such as
fhd,hd, orsd. - scale: Pixel scale relative to FHD.
- width / height: UI resolution in pixels.
BaseHosannaDevice
BaseHosannaDevice resolves UI resolution, quality, expression, orientation, DPI, and screen metrics during configure(). You can override quality with the debug flag device.forcedDeviceQuality, using DeviceQuality.Low, DeviceQuality.Medium, or DeviceQuality.High.
export class BaseHosannaDevice implements IHosannaDevice {
appInfo: ISGROAppInfo = CreateObject('roAppInfo');
deviceInfo: ISGRODeviceInfo = CreateObject('roDeviceInfo');
deviceQuality: DeviceQuality = DeviceQuality.High;
expression: Expression = Expression.TV;
deviceLayoutOrientation: DeviceLayoutOrientation = DeviceLayoutOrientation.Landscape;
deviceDpi = 1920;
resolutionInfo: IResolutionInfo = {
suffix: 'fhd',
scale: 1.0,
width: 1920,
height: 1080,
};
screenInfo: IHosannaScreenInfo = {
viewportWidth: 1920,
viewportHeight: 1080,
screenWidth: 1920,
screenHeight: 1080,
devicePixelRatio: 1,
safeAreaInsets: { top: 0, right: 0, bottom: 0, left: 0 },
};
configure(): void {
this.resolutionInfo = this.getUIResolutionInfo();
this.deviceQuality = this.getDeviceQuality();
this.configureDesignMetrics();
this.screenInfo = this.getScreenInfo();
}
}
Inject device.forcedDeviceQuality to simulate lower-end devices and verify fallback styling, image density, and performance paths.
@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, and -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') ?? '';
}
AppConfig Resolution
AppConfig is configured after the device resolves resolutionInfo. Fragment data bindings can use $RES$ in paths such as ${data.imageSet.$RES$}; AppConfig replaces it with the active suffix before the fragment reads item data.