M3(批2): DeviceProvider + NetworkProvider
T-M3-02 DeviceProvider:getTime/getphonestate(call.getCallState)/getmarketname/getothername(按名查本地配置)/
getOther/getcompareCode(暂返 '0' 待接版本决策) 同步返回;getbattery→getBattery(batteryInfo.batterySOC/100)、
getwifiLevel→getwifiLevel(wifiManager 信号 0~4)、getphoneInfo→getphoneinfo(deviceInfo;IMEI/IMSI/MAC 鸿蒙受限留空) 出站推送。
裸串 vs JSON、出站命名陷阱(getphoneinfo 小写/getBattery 大写)逐字对齐
T-M3-03 NetworkProvider:getnetwork 同步返回 1无网/2WiFi/3移动(connection.getDefaultNet+bearerTypes);
connection 订阅 netAvailable/netLost/netCapabilitiesChange 变化时出站广播 getnetwork;onDestroy 注销
module.json5 增 GET_NETWORK_INFO/GET_WIFI_INFO;组装根装配二者
devecocli build 通过。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
* (RoomStubProvider/PayStubProvider,§6.5),契约 handler 名/数量不变。
|
||||
*/
|
||||
import { CapabilityProvider, EchoSampleProvider, RoomStubProvider, PayStubProvider,
|
||||
VibrateProvider, ClipboardProvider, AppSystemProvider } from 'feature_capabilities';
|
||||
VibrateProvider, ClipboardProvider, AppSystemProvider, DeviceProvider,
|
||||
NetworkProvider } from 'feature_capabilities';
|
||||
|
||||
export function buildCapabilities(): CapabilityProvider[] {
|
||||
return [
|
||||
@@ -15,6 +16,8 @@ export function buildCapabilities(): CapabilityProvider[] {
|
||||
new AppSystemProvider(), // orientation/browser/finsh/openApplyDownloadpath/notification
|
||||
new VibrateProvider(), // vibrator/repeatvibrator/canclevibrator
|
||||
new ClipboardProvider(), // gameCopytext/gamepastetext
|
||||
new DeviceProvider(), // getTime/getphonestate/getbattery/getwifiLevel/getphoneInfo/getmarketname/getothername/getOther/getcompareCode
|
||||
new NetworkProvider(), // getnetwork + 出站广播
|
||||
// —— 暂缓能力占位桩(§6.5)——
|
||||
new RoomStubProvider(),
|
||||
new PayStubProvider(),
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.VIBRATE"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.GET_NETWORK_INFO"
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.GET_WIFI_INFO"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,3 +12,5 @@ export { RoomStubProvider, PayStubProvider } from './src/main/ets/providers/Stub
|
||||
export { VibrateProvider } from './src/main/ets/providers/VibrateProvider';
|
||||
export { ClipboardProvider } from './src/main/ets/providers/ClipboardProvider';
|
||||
export { AppSystemProvider } from './src/main/ets/providers/AppSystemProvider';
|
||||
export { DeviceProvider } from './src/main/ets/providers/DeviceProvider';
|
||||
export { NetworkProvider } from './src/main/ets/providers/NetworkProvider';
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 设备/系统信息能力(契约 §8.3,T-M3-02)。裸串 vs JSON 严格区分。
|
||||
* 同步返回(responseCallback):getTime/getphonestate/getmarketname/getothername/getOther/getcompareCode
|
||||
* 异步出站推送:getbattery→getBattery、getwifiLevel→getwifiLevel、getphoneInfo→getphoneinfo(全小写)
|
||||
*
|
||||
* 注:HarmonyOS 隐私约束下 IMEI/IMSI/MAC 不可获取,PhoneInfoBean 对应字段留空(与平台能力一致)。
|
||||
* 需 module.json5 声明 GET_WIFI_INFO(getwifiLevel)。
|
||||
*/
|
||||
import { deviceInfo } from '@kit.BasicServicesKit';
|
||||
import { batteryInfo } from '@kit.BasicServicesKit';
|
||||
import { call } from '@kit.TelephonyKit';
|
||||
import { wifiManager } from '@kit.ConnectivityKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { BridgeController } from 'feature_bridge';
|
||||
import { InboundHandlers, OutboundHandlers, PhoneInfoBean, WifiLevelResp } from 'contracts';
|
||||
import { ConfigManager, AppConfig } from 'domain_resource';
|
||||
import { Logger } from 'common';
|
||||
import { CapabilityContext, CapabilityProvider } from '../core/CapabilityProvider';
|
||||
|
||||
export class DeviceProvider implements CapabilityProvider {
|
||||
readonly name: string = 'device';
|
||||
private readonly log: Logger = Logger.tag('DeviceProvider');
|
||||
private bridge: BridgeController | undefined = undefined;
|
||||
private config: ConfigManager | undefined = undefined;
|
||||
|
||||
register(bridge: BridgeController, ctx: CapabilityContext): void {
|
||||
this.bridge = bridge;
|
||||
this.config = ctx.config;
|
||||
|
||||
bridge.registerHandler(InboundHandlers.GetTime, (_d: string, cb: (resp: string) => void) => {
|
||||
cb(Date.now().toString());
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetPhoneState, (_d: string, cb: (resp: string) => void) => {
|
||||
call.getCallState().then((s: call.CallState) => cb(`${s}`)).catch(() => cb('0'));
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetMarketName, (_d: string, cb: (resp: string) => void) => {
|
||||
cb(this.local().market);
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetOther, (_d: string, cb: (resp: string) => void) => {
|
||||
cb(this.local().other);
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetOtherName, (data: string, cb: (resp: string) => void) => {
|
||||
cb(this.lookupConfig(data));
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetCompareCode, (_d: string, cb: (resp: string) => void) => {
|
||||
// TODO(M3):1=本地 appversion>网络 app_version/0=否,需接 StartupOrchestrator 的版本决策;暂安全返回 '0'
|
||||
cb('0');
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetBattery, (_d: string, _cb: (resp: string) => void) => {
|
||||
this.pushBattery();
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetWifiLevel, (_d: string, _cb: (resp: string) => void) => {
|
||||
this.pushWifiLevel();
|
||||
});
|
||||
bridge.registerHandler(InboundHandlers.GetPhoneInfo, (_d: string, _cb: (resp: string) => void) => {
|
||||
this.pushPhoneInfo();
|
||||
});
|
||||
}
|
||||
|
||||
private local(): AppConfig {
|
||||
return this.config!.getLocal();
|
||||
}
|
||||
|
||||
/** getothername:按配置名取本地配置值。 */
|
||||
private lookupConfig(name: string): string {
|
||||
const c: AppConfig = this.local();
|
||||
switch (name) {
|
||||
case 'agent': return c.agent;
|
||||
case 'channel': return c.channel;
|
||||
case 'gamedir': return c.gamedir;
|
||||
case 'gamestart': return c.gamestart;
|
||||
case 'appversion': return c.appversion;
|
||||
case 'market': return c.market;
|
||||
case 'gameid': return c.gameid;
|
||||
case 'weburl': return c.weburl;
|
||||
case 'gameconfig': return c.gameconfig;
|
||||
case 'other': return c.other;
|
||||
case 'tuiguang': return c.tuiguang;
|
||||
default: return '';
|
||||
}
|
||||
}
|
||||
|
||||
/** getBattery:电量 float 0~1。 */
|
||||
private pushBattery(): void {
|
||||
const soc: number = batteryInfo.batterySOC; // 0~100
|
||||
const level: number = Math.max(0, Math.min(100, soc)) / 100;
|
||||
this.bridge?.callHandler(OutboundHandlers.GetBattery, `${level}`);
|
||||
}
|
||||
|
||||
/** getwifiLevel:{ssidname, signalLevel(0~4)}。失败回安全默认(H5 不卡死)。 */
|
||||
private pushWifiLevel(): void {
|
||||
wifiManager.getLinkedInfo()
|
||||
.then((info: wifiManager.WifiLinkedInfo) => {
|
||||
const level: number = wifiManager.getSignalLevel(info.rssi, info.band);
|
||||
const resp: WifiLevelResp = { ssidname: info.ssid ?? '', signalLevel: level };
|
||||
this.bridge?.callHandler(OutboundHandlers.GetWifiLevel, JSON.stringify(resp));
|
||||
})
|
||||
.catch((e: BusinessError) => {
|
||||
this.log.w(`getwifiLevel failed: ${e.code} ${e.message}`);
|
||||
const resp: WifiLevelResp = { ssidname: '', signalLevel: 0 };
|
||||
this.bridge?.callHandler(OutboundHandlers.GetWifiLevel, JSON.stringify(resp));
|
||||
});
|
||||
}
|
||||
|
||||
/** getphoneinfo(出站全小写):PhoneInfoBean。IMEI/IMSI/MAC 受限留空。 */
|
||||
private pushPhoneInfo(): void {
|
||||
const bean: PhoneInfoBean = {
|
||||
PhoneVersion: deviceInfo.osFullName,
|
||||
PhoneAdresseMAC: '',
|
||||
PhoneModel: deviceInfo.productModel,
|
||||
PhoneDeviceBrand: deviceInfo.brand,
|
||||
PhoneProvidersName: '',
|
||||
PhoneIMEI: '',
|
||||
PhoneIMSI: '',
|
||||
};
|
||||
this.bridge?.callHandler(OutboundHandlers.GetPhoneInfo, JSON.stringify(bean));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 网络状态能力(契约 §8.3/§9,T-M3-03)。@ohos.net.connection。
|
||||
* - getnetwork:同步返回 int 裸串(1 无网 / 2 WiFi / 3 移动)。
|
||||
* - 出站 getnetwork:网络变化时广播同样的 int 裸串。
|
||||
* 需 module.json5 声明 GET_NETWORK_INFO。
|
||||
*/
|
||||
import { connection } from '@kit.NetworkKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { BridgeController } from 'feature_bridge';
|
||||
import { InboundHandlers, OutboundHandlers } from 'contracts';
|
||||
import { Logger } from 'common';
|
||||
import { CapabilityContext, CapabilityProvider } from '../core/CapabilityProvider';
|
||||
|
||||
/** 网络码(契约:1 无网 / 2 WiFi / 3 移动)。 */
|
||||
const NET_NONE: string = '1';
|
||||
const NET_WIFI: string = '2';
|
||||
const NET_MOBILE: string = '3';
|
||||
|
||||
export class NetworkProvider implements CapabilityProvider {
|
||||
readonly name: string = 'network';
|
||||
private readonly log: Logger = Logger.tag('NetworkProvider');
|
||||
private bridge: BridgeController | undefined = undefined;
|
||||
private conn: connection.NetConnection | undefined = undefined;
|
||||
|
||||
register(bridge: BridgeController, _ctx: CapabilityContext): void {
|
||||
this.bridge = bridge;
|
||||
bridge.registerHandler(InboundHandlers.GetNetwork, (_d: string, cb: (resp: string) => void) => {
|
||||
this.currentNetwork().then((code: string) => cb(code)).catch(() => cb(NET_NONE));
|
||||
});
|
||||
this.subscribe();
|
||||
}
|
||||
|
||||
onDestroy(): void {
|
||||
const c = this.conn;
|
||||
if (c !== undefined) {
|
||||
c.unregister((_e: BusinessError) => { });
|
||||
this.conn = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/** 取当前网络码。 */
|
||||
private async currentNetwork(): Promise<string> {
|
||||
const has: boolean = await connection.hasDefaultNet();
|
||||
if (!has) {
|
||||
return NET_NONE;
|
||||
}
|
||||
const netHandle: connection.NetHandle = await connection.getDefaultNet();
|
||||
const cap: connection.NetCapabilities = await connection.getNetCapabilities(netHandle);
|
||||
const bearers: number[] = cap.bearerTypes ?? [];
|
||||
if (bearers.includes(connection.NetBearType.BEARER_WIFI)) {
|
||||
return NET_WIFI;
|
||||
}
|
||||
if (bearers.includes(connection.NetBearType.BEARER_CELLULAR)) {
|
||||
return NET_MOBILE;
|
||||
}
|
||||
return NET_NONE;
|
||||
}
|
||||
|
||||
/** 订阅网络变化,变化时出站推送 getnetwork。 */
|
||||
private subscribe(): void {
|
||||
try {
|
||||
const conn: connection.NetConnection = connection.createNetConnection();
|
||||
this.conn = conn;
|
||||
conn.on('netAvailable', () => this.broadcast());
|
||||
conn.on('netLost', () => this.bridge?.callHandler(OutboundHandlers.GetNetwork, NET_NONE));
|
||||
conn.on('netCapabilitiesChange', () => this.broadcast());
|
||||
conn.register((e: BusinessError) => {
|
||||
if (e) {
|
||||
this.log.w(`net register failed: ${e.code} ${e.message}`);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
this.log.w(`subscribe failed: ${(e as BusinessError).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
private broadcast(): void {
|
||||
this.currentNetwork()
|
||||
.then((code: string) => this.bridge?.callHandler(OutboundHandlers.GetNetwork, code))
|
||||
.catch(() => { });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user