Skip to content

Instantly share code, notes, and snippets.

View LethalMaus's full-sized avatar

James Cullimore LethalMaus

View GitHub Profile
@LethalMaus
LethalMaus / ZeroMq.kt
Created February 11, 2026 19:59
ZeroMq.kt
override fun close() {
try {
isRunning = false
receiveJob?.cancel()
subSocket?.close()
pubSocket?.close()
context?.close()
Log.d(TAG, "Disconnected from server")
CoroutineScope(Dispatchers.Main).launch { onConnectionChanged?.invoke(false) }
} catch (e: Exception) {
@LethalMaus
LethalMaus / ZeroMq.kt
Created February 11, 2026 19:59
ZeroMq.kt
fun sendMessage(message: String) {
if (!isRunning || pubSocket == null) {
Log.e(TAG, "Cannot send message, client not connected")
return
}
try {
pubSocket?.send(message)
Log.d(TAG, "Sent message to server: $message")
} catch (e: ZMQException) {
Log.e(TAG, "Error sending message or receiving response: ${e.message}", e)
@LethalMaus
LethalMaus / ZeroMq.kt
Created February 11, 2026 19:59
ZeroMq.kt
private fun startReceiving() {
receiveJob = CoroutineScope(Dispatchers.IO).launch {
try {
while (isRunning && subSocket != null) {
val message = subSocket?.recvStr()
if (message != null) {
Log.d(TAG, "Server received message: $message")
messageCallback?.invoke(message)
}
}
@LethalMaus
LethalMaus / ZeroMq.kt
Created February 11, 2026 19:59
ZeroMq.kt
fun connect() {
if (isRunning) return
CoroutineScope(Dispatchers.IO).launch {
try {
context = ZContext()
subPort?.let {
subSocket = context?.createSocket(SocketType.SUB)
subSocket?.subscribe("".toByteArray())
subSocket?.connect("tcp://127.0.0.1:$subPort")
Log.d(TAG, "Subbing to $subPort")
@LethalMaus
LethalMaus / ZeroMq.kt
Created February 11, 2026 19:58
ZeroMq.kt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.zeromq.SocketType
import org.zeromq.ZContext
import org.zeromq.ZMQ
import org.zeromq.ZMQException
import java.io.Closeable
@LethalMaus
LethalMaus / WearOSComplication.xml
Last active February 11, 2026 20:01
WearOSComplication.xml
<service
android:name=".service.QuickstartComplicationService"
android:exported="true"
android:label="@string/app_name"
android:icon="@drawable/app_icon"
android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
</intent-filter>
<!-- Supported types should be comma-separated e.g. SHORT_TEXT,SMALL_IMAGE -->
@LethalMaus
LethalMaus / WearOSComplication.kt
Created February 11, 2026 19:58
WearOSComplication.kt
return SmallImageComplicationData
.Builder(
SmallImage.Builder(
icon,
SmallImageType.ICON
).build(),
PlainComplicationText.Builder(appName).build()
)
.setTapAction(pendingIntent)
.build()
@LethalMaus
LethalMaus / WearOSComplication.kt
Created February 11, 2026 19:58
WearOSComplication.kt
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
val pendingIntent = PendingIntent.getActivity(
this,
0,
launchIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
@LethalMaus
LethalMaus / WearOSComplication.kt
Created February 11, 2026 19:58
WearOSComplication.kt
class QuickstartComplicationService: ComplicationDataSourceService() {
override fun onComplicationRequest(
request: ComplicationRequest,
listener: ComplicationRequestListener
) {
listener.onComplicationData(getComplicationData())
}
override fun getPreviewData(type: ComplicationType): ComplicationData? {
return getComplicationData()
}
@LethalMaus
LethalMaus / AndroidSecurityTraining_Pinning.xml
Last active February 11, 2026 20:00
AndroidSecurityTraining_Pinning.xml
<network-security-config>
<!-- Disallow user-added CAs, use only system certs -->
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
<!-- No user certs in secure profile -->
</trust-anchors>
</base-config>
<!-- Allow user CAs only for debug builds to facilitate MITM demos -->
<debug-overrides>