Skip to main content

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, or tablet.
  • deviceLayoutOrientation: Active design-surface orientation: portrait or landscape.
  • 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, or sd.
  • 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();
}
}
Force Quality in Dev

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.