/** * 系统/应用能力(契约 §8.4/§8.8/§8.10,T-M3-01)。 * - orientation:data="1" 横屏 / 其他 竖屏(窗口动态切换,§7.4 保留 H5 显式方向控制)。 * - browser:data=URL,隐式 want 拉起系统浏览器。 * - finsh(拼写原样):退出当前 Ability。 * - openApplyDownloadpath:data=JSON{packagename,downloadpath},按包名启动 App,失败则浏览器打开下载地址。 * - notification:空实现(契约标注未落地)。 */ import { common, Want } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; import { BridgeController } from 'feature_bridge'; import { InboundHandlers, OpenApplyDownloadReq } from 'contracts'; import { Logger } from 'common'; import { CapabilityContext, CapabilityProvider } from '../core/CapabilityProvider'; export class AppSystemProvider implements CapabilityProvider { readonly name: string = 'appsystem'; private readonly log: Logger = Logger.tag('AppSystemProvider'); private context: common.UIAbilityContext | undefined = undefined; register(bridge: BridgeController, ctx: CapabilityContext): void { this.context = ctx.uiAbilityContext; bridge.registerHandler(InboundHandlers.Orientation, (data: string, _cb: (resp: string) => void) => { this.setOrientation(data === '1'); }); bridge.registerHandler(InboundHandlers.Browser, (data: string, _cb: (resp: string) => void) => { this.openBrowser(data); }); bridge.registerHandler(InboundHandlers.Finsh, (_d: string, _cb: (resp: string) => void) => { this.context?.terminateSelf() .catch((e: BusinessError) => this.log.w(`terminateSelf failed: ${e.code} ${e.message}`)); }); bridge.registerHandler(InboundHandlers.OpenApplyDownloadPath, (data: string, _cb: (resp: string) => void) => { this.openApply(data); }); bridge.registerHandler(InboundHandlers.Notification, (_d: string, _cb: (resp: string) => void) => { // 契约标注:空实现,未落地 }); } /** 动态设方向:横屏 LANDSCAPE / 竖屏 PORTRAIT(对齐 Android setRequestedOrientation)。 */ private setOrientation(landscape: boolean): void { const ctx = this.context; if (ctx === undefined) { return; } const target: window.Orientation = landscape ? window.Orientation.LANDSCAPE : window.Orientation.PORTRAIT; window.getLastWindow(ctx) .then((win: window.Window) => win.setPreferredOrientation(target)) .catch((e: BusinessError) => this.log.w(`setOrientation failed: ${e.code} ${e.message}`)); } private openBrowser(url: string): void { if (this.context === undefined || url === '') { return; } const want: Want = { action: 'ohos.want.action.viewData', entities: ['entity.system.browsable'], uri: url, }; this.context.startAbility(want) .catch((e: BusinessError) => this.log.w(`openBrowser failed: ${e.code} ${e.message}`)); } private openApply(data: string): void { const ctx = this.context; if (ctx === undefined) { return; } let req: OpenApplyDownloadReq; try { req = JSON.parse(data) as OpenApplyDownloadReq; } catch (e) { this.log.w(`openApply bad json: ${(e as Error).message}`); return; } // 按包名启动 App;失败回退浏览器打开下载地址 ctx.startAbility({ bundleName: req.packagename } as Want) .catch((e: BusinessError) => { this.log.i(`start app ${req.packagename} failed (${e.code}); fallback to download page`); this.openBrowser(req.downloadpath); }); } }