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 名/数量不变。
|
* (RoomStubProvider/PayStubProvider,§6.5),契约 handler 名/数量不变。
|
||||||
*/
|
*/
|
||||||
import { CapabilityProvider, EchoSampleProvider, RoomStubProvider, PayStubProvider,
|
import { CapabilityProvider, EchoSampleProvider, RoomStubProvider, PayStubProvider,
|
||||||
VibrateProvider, ClipboardProvider, AppSystemProvider } from 'feature_capabilities';
|
VibrateProvider, ClipboardProvider, AppSystemProvider, DeviceProvider,
|
||||||
|
NetworkProvider } from 'feature_capabilities';
|
||||||
|
|
||||||
export function buildCapabilities(): CapabilityProvider[] {
|
export function buildCapabilities(): CapabilityProvider[] {
|
||||||
return [
|
return [
|
||||||
@@ -15,6 +16,8 @@ export function buildCapabilities(): CapabilityProvider[] {
|
|||||||
new AppSystemProvider(), // orientation/browser/finsh/openApplyDownloadpath/notification
|
new AppSystemProvider(), // orientation/browser/finsh/openApplyDownloadpath/notification
|
||||||
new VibrateProvider(), // vibrator/repeatvibrator/canclevibrator
|
new VibrateProvider(), // vibrator/repeatvibrator/canclevibrator
|
||||||
new ClipboardProvider(), // gameCopytext/gamepastetext
|
new ClipboardProvider(), // gameCopytext/gamepastetext
|
||||||
|
new DeviceProvider(), // getTime/getphonestate/getbattery/getwifiLevel/getphoneInfo/getmarketname/getothername/getOther/getcompareCode
|
||||||
|
new NetworkProvider(), // getnetwork + 出站广播
|
||||||
// —— 暂缓能力占位桩(§6.5)——
|
// —— 暂缓能力占位桩(§6.5)——
|
||||||
new RoomStubProvider(),
|
new RoomStubProvider(),
|
||||||
new PayStubProvider(),
|
new PayStubProvider(),
|
||||||
|
|||||||
@@ -58,6 +58,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ohos.permission.VIBRATE"
|
"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 { VibrateProvider } from './src/main/ets/providers/VibrateProvider';
|
||||||
export { ClipboardProvider } from './src/main/ets/providers/ClipboardProvider';
|
export { ClipboardProvider } from './src/main/ets/providers/ClipboardProvider';
|
||||||
export { AppSystemProvider } from './src/main/ets/providers/AppSystemProvider';
|
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