# Phone SDK — API reference
## 1 SDK initialization
```kotlin

private fun initSDK() {
        lifecycleScope.launch {
           // SecurityPhone: system id; GlassSample: app id — phone and glasses MUST match.
            val clientIds = arrayListOf("SecurityPhone", "GlassSample")

            // AK/SK credentials — request from BizDev.
            val userAuthInfo = UserAuthInfo("","")

            // Skip translate/RTC bootstrap; enable only ASR/TTS services
//            val banServiceList: List<NetServiceType>? = arrayListOf(NetServiceType.TranslateService, NetServiceType.RtcService)

            // ALL = skip optional cloud service init
             val banServiceList: List<NetServiceType>? = arrayListOf(NetServiceType.ALL)

            // PUBLIC = production cloud
            val param = EngineParam(clientIds = clientIds, userAuthInfo = userAuthInfo, banServiceList = banServiceList, envType = EnvType.Companion.PUBLIC)
            mPhoneEngineService.initSDK(param) {
                if (it.isSuccess) {
                    Log.d(TAG, "Phone SDK init OK")
                } else {
                    Log.e(TAG, "Phone SDK init failed")
                }
            }
        }

    }

data class EngineParam( 
    var clientIds: ArrayList<String>? = null,
    
     // AK/SK credentials — request from BizDev.
    var userAuthInfo: UserAuthInfo?=null,
    
    @EnvType
    var envType:String, // env: EnvType.Companion.PUBLIC = public cloud
    var customHost:String?, // REQUIRED when envType=CUSTOM — custom hostname

     // ALL表示 所有服务都不初始化
    var banServiceList: List<NetServiceType>?=null
)

```

### `IMobileEngine`
```kotlin
interface IMobileEngine {
    /**
     * Initialize SDK
     * @param param bootstrap payload
     * @param onResult completion
     */
    fun initSDK(params: EngineParam, onResult: (result: IResult<Boolean>) -> Unit)

    /**
     * @param user user profile surfaced on glasses
     * @param userInfox
     */
    fun setUserInfo(user: UserInfo)

    /**
     * @return SDK ready flag
     */
    fun isInit():Boolean

    /**
     * Destroy SDK singleton
     */
    fun destroy()

}
```

## 2 Wi-Fi P2P client

```kotlin
PSecuritySDK.getWifiP2PClientService() 

interface IWifiP2PClientOperate {

    /**
     * Bring up Wi-Fi Direct channel
     */
    fun initialize(onResult: ((result: IResult<Boolean>) -> Unit)? = null)

    /**
     * Attach to peripheral
     * @param device
     * @param onResult completion
     */
    fun connectDevice(device: WifiP2pDevice, onResult: ((result: IResult<Boolean>) -> Unit))

    /**
     * Disconnect
     */
    fun disconnect()

    /**
     * Discover peers
     */
    fun startDiscoverPeers(onResult: ((result: IResult<Boolean>) -> Unit)? = null)

    /**
     * Provide latest `WifiP2pInfo`
     * @param action
     */
    fun requestConnectionInfo(action: (info: WifiP2pInfo?) -> Unit)

    /**
     * Inspect whether TCP channel is alive
     * @param action
     */
    fun isConnect(action: (isConnect: Boolean) -> Unit)

    /**
     * Add listener
     * @param listener
     */
    fun addWifiP2PClientListener(listener: IWifiP2PClientListener)

    /**
     * Remove listener
     * @param listener
     */
    fun removeWifiP2PClientListener(listener: IWifiP2PClientListener)

}
```

### `IWifiP2PClientOperate` (detailed surface)

```kotlin
/**
 * Created by wjm on 2025/5/8
 */
interface IWifiP2PClientOperate {

    /**
     * Bring up Wi-Fi Direct channel
     */
    fun initialize(onResult: ((result: IResult<Boolean>) -> Unit)? = null)

    /**
     * Attach to peripheral
     * @param device
     * @param onResult completion
     */
    fun connectDevice(device: WifiP2pDevice, onResult: ((result: IResult<Boolean>) -> Unit))

    /**
     * Auto connect Wi-Fi Direct (classic BT must precede)
     */
    fun sendConnectP2pRequest(action: (isSuccess: Boolean) -> Unit)

    /**
     * Disconnect
     */
    fun disconnect()

    /**
     * Discover peers
     */
    fun startDiscoverPeers(onResult: ((result: IResult<Boolean>) -> Unit)? = null)

    /**
     * Stop peer discovery
     */
    fun stopPeerDiscovery(onResult: ((result: IResult<Boolean>) -> Unit)? = null)

    /**
     * Provide latest `WifiP2pInfo`
     * @param action
     */
    fun requestConnectionInfo(action: (info: WifiP2pInfo?) -> Unit)

    /**
     * @param action
     */
    fun getGroupInfo(action: (group: WifiP2pGroup?) -> Unit)

    /**
     * Inspect whether TCP channel is alive
     * @param action
     */
    fun isConnect(action: (isConnect: Boolean) -> Unit)

    /**
     * Add listener
     * @param listener
     */
    fun addWifiP2PClientListener(listener: IWifiP2PClientListener)

    /**
     * Remove listener
     * @param listener
     */
    fun removeWifiP2PClientListener(listener: IWifiP2PClientListener)


    /**
     * Acquire `IP2PConnectControl`
     */
    fun getIP2PConnectControl(): IP2PConnectControl

}
```

## 3 Classic Bluetooth client

```kotlin
	/**
     * `PSecuritySDK.getClassicBlueToothClientService()`
     * @param timeoutMillis scan budget
     * */
PSecuritySDK.getClassicBlueToothClientService()
```

```kotlin
interface IClassicBluetoothClient {


    /**
     * Start classic scan
     * @param timeoutMillis scan budget
     * */
    fun startScan(
        timeoutMillis: Long = 20000L,
    )

    /***
     * Stop scanning
     */
    fun stopScan()

    /***
     * Connect to handset
     * @param device target
     * @param action
     */
    fun connectToServer(device: BluetoothDevice,action: (isConnect : Boolean) -> Unit)

    /***
     * Tear down sockets
     */
    fun disconnect()


    /***
     * Register listener
     */
    fun addClientListener(listener: IClassicBTClientListener)

    /***
     * Unregister listener
     */
    fun removeClientListener(listener: IClassicBTClientListener)

    /***
     * Connected?
     */
    fun isConnected(): Boolean

}
```

### `IClassicBTClientListener`

```kotlin
interface IClassicBTClientListener {

    /***
     * Device FOUND
     * @param device peer
     */
    fun onDeviceFound(device: BluetoothDevice)
    /***
     * Scan finished
     */
    fun onScanFinished()

    /***
     * Connection state
     * @param success success flag
     */
    fun onConnect(success: Boolean)

    /**
     * Rejected handshake
     */
    fun onConnectionRejected(reason: String, code: Int)

}
```



## 4 Messaging

```kotlin
 /**
     * `PSecuritySDK.getMessageService()`
     */
PSecuritySDK.getMessageService()
```

```kotlin
interface IMessage {

    /**
     * Add listener
     *  @param listener
     */
    fun addMessageListener(listener: IMessageListener)

    /**
     * Remove listener
     *  @param listener
     */
    fun removeMessageListener(listener: IMessageListener)

    /**
     * Send Unicode over Wi-Fi Direct
     * @param message
     * @param clientId destination Glass app id ("" = default)
     */
    fun sendTextMessageByP2P(message: String,clientId: String = "")

    /**
     * Send text over classic BT
     * @param message
     * @param clientId destination client ("" = default)
     */
    fun sendTextMessageByClassicBT(message: String,clientId: String = "")



    /**
     * Stream PCM over P2P
     * @param streamData
     */
    fun sendAudioStreamDataByP2P(streamData: ByteArray)

    /**
     * Stream PCM over classic BT
     * @param streamData
     */
    fun sendAudioStreamDataByClassicBT(streamData: ByteArray)

    /**
     * Send text over BLE
     * @param streamData
     */
    fun sendTextMessageByBle(message: String)

    /**
     * Send opaque binary payload
     * @param tag
     * @param data
     * @param clientId
     * @param callback
     */
    fun sendStreamData(tag:String,data: ByteArray, clientId: String,callback: IResultCallback<Boolean>?)

    /**
     * `getFileOperater()` P2P
     */
    fun getFileOperater(): IFileOperate

    /**
     * `getBtFileOperater()` classic
     */
    fun getBtFileOperater(): IFileOperate

    fun getApkFileOperator() : IApkFileOperate

}
```

### `IMessageListener`

```kotlin
interface IMessageListener {
    /**
     * Incoming text
     * @param msg
     */
    fun onP2PTextMessage(msg: String ,clientId: String){}

    /**
     * H.264 chunk
     * @param buffer
     */
    fun onVideoH264Stream(buffer: ByteBuffer){}

    /**
     * PCM buffer
     * @param buffer
     */
    fun onAudioStream(buffer: ByteBuffer){}

    /**
     * NV21 frame
     * @param data
     * @param width
     * @param height
     */
    fun onNv21Data(data: ByteArray, width: Int, height: Int) {}
    /**
     * Incoming text
     * @param msg
     */
    fun onClassicBTTextMessage(msg: String, clientId: String){}

    /**
     * PCM buffer
     * @param buffer
     */
    fun onClassicBTAudioStream(buffer: ByteArray){}

    /**
     * Binary payload
     * @param tag
     * @param data
     */
    fun onBTStreamDataReceived(tag: String, data: ByteArray, clientId: String){}

}
```

## 5 `IFileOperate`

```kotlin
/**
     * P2P file helper
     */
    private val mFileOperator by lazy {
        PSecuritySDK.getMessageService()?.getFileOperater()
    }

    /**
     * BT file helper
     */
    private val mBTFileOperator by lazy {
        PSecuritySDK.getMessageService()?.getBtFileOperater()
    }
```

```kotlin

interface IFileOperate {
    /**
     * Send file
     * @param dir relative recv dir (e.g. "custom" or "custom/file/")
     * @param file
     * @param listener remote receive ack
     * @param onResult completion
     */
    fun sendFile(dir: String? = null,file: File, listener: FileReceiveListener, onResult: ((result: IResult<Boolean>) -> Unit))

    /**
     * Abort transfer
     */
    fun stopSendFile()

    /**
     * Add local receive listener
     *  @param listener
     */
    fun addFileReceiveListener(listener: FileReceiveListener)

    /**
     * Remove receive listener
     *  @param listener
     */
    fun removeFileReceiveListener(listener: FileReceiveListener)

}
```

### `FileReceiveListener` sample

```kotlin
  private val mFileReceiveListener2 = object : FileReceiveListener {
        override fun onStart() {
            Log.e(TAG, "receive start")
        }


        override fun onProgressChanged(progress: Float) {
            Log.e(TAG, "receive progress $progress")

        }

        override fun onComplete(filePath: String) {
            Log.e(TAG, "receive done")

        }

        override fun onFail() {
            Log.e(TAG, "receive failed")

        }

        override fun onCancel() {
            Log.e(TAG, "remote cancelled send")

        }
    }
```

## 6 Bluetooth smart ring

```kotlin
/**
     * `PSecuritySDK.getBluetoothRingService()`
     */
PSecuritySDK.getBluetoothRingService()
```

```kotlin

interface IBluetoothRing {

    /**
     * Start classic scan
     * @param timeoutMillis scan budget
     * */
    fun startScan(
        timeoutMillis: Long = 20000L,
    ){}

    /***
     * Stop scanning
     */
    fun stopScan(){}

    /***
     * 选择蓝牙设备连接
     * @param device 选择的蓝牙设备
     */
    fun connectToServer(device: BluetoothDevice){}

    /***
     * Tear down sockets
     */
    fun disconnect(){}


    /***
     * Register listener
     */
    fun addClientListener(listener: IBTRingClientListener){}

    /***
     * Unregister listener
     */
    fun removeClientListener(listener: IBTRingClientListener){}

}
```

### `IBTRingClientListener`

```kotlin
interface IBTRingClientListener {

    /***
     * Device FOUND
     * @param device peer
     */
    fun onDeviceFound(device: BluetoothDevice)
    /***
     * Scan finished
     */
    fun onScanFinished()

    /***
     * Connection state
     * @param success success flag
     */
    fun onConnect(success: Boolean)
}
```

## 7 Notification bridge

```kotlin
/***
     * `PSecuritySDK.getAbsNotificationService()`
     */
PSecuritySDK.getAbsNotificationService()
```

```kotlin
interface INotification {


    /**
     * Raise notification
     * @param bean payload
     * */
    fun sendNotification(bean : NotificationMessage)

    /**
     * Personnel alert thumbnails
     * @param face1 left chip
     * @param face2 right chip
     * @param msg UI envelope
     * callback codes (0 OK)
     */
    fun sendPersonnelAlertNotification(face1: Bitmap, face2: Bitmap, msg: PersonnelAlertMessage,  callback: IResultCallback<Int>)
    
}
```

## 8 Device info / AV ingest

```kotlin
PSecuritySDK.getAbsDeviceInfoService()
```

```kotlin
interface IDevice {

    /**
     * `getGlassDeviceInfo()`
     */
    fun getGlassDeviceInfo() : GlassDeviceInfo?

    /**
     * Subscribe preview stream
     * @param tag subscription handle
     * @param videoStreamParam fps/bitrate knobs
     * @param callback subscribe result
     */
    fun requestVideoStream(tag: String,videoStreamParam: GlassVideoStreamParam = GlassVideoStreamParam(),callback: (isSuccess: Boolean) -> Unit)
    /**
     * Stop preview subscription
     * @param tag unsubscribe handle
     * @param callback stop acknowledgement
     */
    fun stopVideoStream(tag: String,callback: (isSuccess: Boolean) -> Unit)
    /**
     * Subscribe audio
     * @param tag audio correlation id
     * @param callback subscribe result
     */
    fun requestAudioStream(tag: String,callback: (isSuccess: Boolean) -> Unit)
    /**
     * Stop audio
     * @param tag audio stop token
     * @param callback stop acknowledgement
     */
    fun stopAudioStream(tag: String,callback: (isSuccess: Boolean) -> Unit)

}
```

