remove Samsung Face Widget (signature-restricted, unusable by third-party apps)
Samsung's FACE_WIDGET permission requires platform signing, making it impossible for non-Samsung apps to register lock screen face widgets. The existing AppWidgetProvider already works via Good Lock LockStar and will be natively supported on lock screens with One UI 8 / Android 16 QPR1.
This commit is contained in:
@@ -2,8 +2,6 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="com.samsung.systemui.permission.FACE_WIDGET" />
|
|
||||||
|
|
||||||
<!-- AndroidTV support -->
|
<!-- AndroidTV support -->
|
||||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||||
|
|
||||||
@@ -100,20 +98,6 @@
|
|||||||
android:permission="android.permission.BIND_REMOTEVIEWS"
|
android:permission="android.permission.BIND_REMOTEVIEWS"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<!-- Samsung Lock Screen Face Widget -->
|
|
||||||
<receiver
|
|
||||||
android:name=".LockScreenWidgetReceiver"
|
|
||||||
android:permission="com.samsung.systemui.permission.FACE_WIDGET"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.samsung.android.intent.action.REQUEST_SERVICEBOX_REMOTEVIEWS" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
|
|
||||||
<meta-data
|
|
||||||
android:name="com.samsung.systemui.facewidget.executable"
|
|
||||||
android:resource="@raw/facewidgets" />
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.fileprovider"
|
android:authorities="${applicationId}.fileprovider"
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
package com.agentui.desktop
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.RemoteViews
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import org.json.JSONObject
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Samsung Face Widget receiver for the lock screen / AOD.
|
|
||||||
*
|
|
||||||
* Samsung's proprietary system sends REQUEST_SERVICEBOX_REMOTEVIEWS
|
|
||||||
* and expects RESPONSE_SERVICEBOX_REMOTEVIEWS back with RemoteViews
|
|
||||||
* for both the lock screen ("origin") and AOD ("aod").
|
|
||||||
*/
|
|
||||||
class LockScreenWidgetReceiver : BroadcastReceiver() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "AgentUI.FaceWidget"
|
|
||||||
private const val ACTION_REQUEST =
|
|
||||||
"com.samsung.android.intent.action.REQUEST_SERVICEBOX_REMOTEVIEWS"
|
|
||||||
private const val ACTION_RESPONSE =
|
|
||||||
"com.samsung.android.intent.action.RESPONSE_SERVICEBOX_REMOTEVIEWS"
|
|
||||||
private const val PAGE_ID = "agent_ui_transcript"
|
|
||||||
|
|
||||||
private val STATUS_COLORS = mapOf(
|
|
||||||
"idle" to 0xFF6b7280.toInt(),
|
|
||||||
"thinking" to 0xFF60a5fa.toInt(),
|
|
||||||
"reading" to 0xFF22d3ee.toInt(),
|
|
||||||
"writing" to 0xFF4ade80.toInt(),
|
|
||||||
"toolUse" to 0xFFfbbf24.toInt(),
|
|
||||||
"permissionRequest" to 0xFFfb923c.toInt(),
|
|
||||||
"interrupted" to 0xFFf87171.toInt(),
|
|
||||||
"error" to 0xFFf87171.toInt(),
|
|
||||||
"sessionStart" to 0xFF60a5fa.toInt(),
|
|
||||||
"sessionEnd" to 0xFF6b7280.toInt()
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dimmed versions for AOD
|
|
||||||
private val AOD_STATUS_COLORS = mapOf(
|
|
||||||
"idle" to 0xFF3b3f47.toInt(),
|
|
||||||
"thinking" to 0xFF304f7a.toInt(),
|
|
||||||
"reading" to 0xFF116670.toInt(),
|
|
||||||
"writing" to 0xFF256b40.toInt(),
|
|
||||||
"toolUse" to 0xFF7a5f12.toInt(),
|
|
||||||
"permissionRequest" to 0xFF7a491e.toInt(),
|
|
||||||
"interrupted" to 0xFF7a3838.toInt(),
|
|
||||||
"error" to 0xFF7a3838.toInt(),
|
|
||||||
"sessionStart" to 0xFF304f7a.toInt(),
|
|
||||||
"sessionEnd" to 0xFF3b3f47.toInt()
|
|
||||||
)
|
|
||||||
|
|
||||||
private val client = OkHttpClient.Builder()
|
|
||||||
.connectTimeout(5, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(5, TimeUnit.SECONDS)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
if (intent.action != ACTION_REQUEST) return
|
|
||||||
|
|
||||||
val pageId = intent.getStringExtra("pageId")
|
|
||||||
if (pageId != PAGE_ID) return
|
|
||||||
|
|
||||||
Log.d(TAG, "Face widget update requested for pageId=$pageId")
|
|
||||||
|
|
||||||
// Fetch data on a background thread to avoid ANR
|
|
||||||
val pendingResult = goAsync()
|
|
||||||
|
|
||||||
Thread {
|
|
||||||
try {
|
|
||||||
val terminals = fetchTerminals(context)
|
|
||||||
val lockViews = buildLockScreenViews(context, terminals)
|
|
||||||
val aodViews = buildAodViews(context, terminals)
|
|
||||||
|
|
||||||
val response = Intent(ACTION_RESPONSE).apply {
|
|
||||||
setPackage("com.android.systemui")
|
|
||||||
putExtra("package", context.packageName)
|
|
||||||
putExtra("pageId", PAGE_ID)
|
|
||||||
putExtra("show", true)
|
|
||||||
putExtra("origin", lockViews)
|
|
||||||
putExtra("aod", aodViews)
|
|
||||||
}
|
|
||||||
|
|
||||||
context.sendBroadcast(response)
|
|
||||||
Log.d(TAG, "Face widget response sent with ${terminals.size} terminals")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, "Failed to build face widget", e)
|
|
||||||
// Send empty response so widget doesn't get stuck
|
|
||||||
val response = Intent(ACTION_RESPONSE).apply {
|
|
||||||
setPackage("com.android.systemui")
|
|
||||||
putExtra("package", context.packageName)
|
|
||||||
putExtra("pageId", PAGE_ID)
|
|
||||||
putExtra("show", true)
|
|
||||||
putExtra("origin", buildEmptyLockScreenViews(context))
|
|
||||||
putExtra("aod", buildEmptyAodViews(context))
|
|
||||||
}
|
|
||||||
context.sendBroadcast(response)
|
|
||||||
} finally {
|
|
||||||
pendingResult.finish()
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildLockScreenViews(
|
|
||||||
context: Context,
|
|
||||||
terminals: List<FaceWidgetTerminal>
|
|
||||||
): RemoteViews {
|
|
||||||
val views = RemoteViews(context.packageName, R.layout.face_widget_lockscreen)
|
|
||||||
|
|
||||||
val statusText = if (terminals.isEmpty()) "offline"
|
|
||||||
else "${terminals.size} agent${if (terminals.size > 1) "s" else ""}"
|
|
||||||
views.setTextViewText(R.id.fw_status, statusText)
|
|
||||||
|
|
||||||
if (terminals.isEmpty()) {
|
|
||||||
views.setViewVisibility(R.id.fw_empty, View.VISIBLE)
|
|
||||||
} else {
|
|
||||||
views.setViewVisibility(R.id.fw_empty, View.GONE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lockscreen terminal slot IDs
|
|
||||||
val slotIds = listOf(
|
|
||||||
Triple(R.id.fw_terminal_1, R.id.fw_dot_1, R.id.fw_name_1),
|
|
||||||
Triple(R.id.fw_terminal_2, R.id.fw_dot_2, R.id.fw_name_2),
|
|
||||||
Triple(R.id.fw_terminal_3, R.id.fw_dot_3, R.id.fw_name_3)
|
|
||||||
)
|
|
||||||
|
|
||||||
for (i in slotIds.indices) {
|
|
||||||
val (container, dot, name) = slotIds[i]
|
|
||||||
if (i < terminals.size) {
|
|
||||||
val t = terminals[i]
|
|
||||||
views.setViewVisibility(container, View.VISIBLE)
|
|
||||||
views.setTextColor(dot, t.statusColor)
|
|
||||||
views.setTextViewText(name, "T${t.index} ${t.agent} ${t.status}")
|
|
||||||
} else {
|
|
||||||
views.setViewVisibility(container, View.GONE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return views
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildAodViews(
|
|
||||||
context: Context,
|
|
||||||
terminals: List<FaceWidgetTerminal>
|
|
||||||
): RemoteViews {
|
|
||||||
val views = RemoteViews(context.packageName, R.layout.face_widget_aod)
|
|
||||||
|
|
||||||
if (terminals.isEmpty()) {
|
|
||||||
views.setViewVisibility(R.id.fw_aod_empty, View.VISIBLE)
|
|
||||||
} else {
|
|
||||||
views.setViewVisibility(R.id.fw_aod_empty, View.GONE)
|
|
||||||
}
|
|
||||||
|
|
||||||
val slotIds = listOf(
|
|
||||||
Triple(R.id.fw_aod_terminal_1, R.id.fw_aod_dot_1, R.id.fw_aod_name_1),
|
|
||||||
Triple(R.id.fw_aod_terminal_2, R.id.fw_aod_dot_2, R.id.fw_aod_name_2),
|
|
||||||
Triple(R.id.fw_aod_terminal_3, R.id.fw_aod_dot_3, R.id.fw_aod_name_3)
|
|
||||||
)
|
|
||||||
|
|
||||||
for (i in slotIds.indices) {
|
|
||||||
val (container, dot, name) = slotIds[i]
|
|
||||||
if (i < terminals.size) {
|
|
||||||
val t = terminals[i]
|
|
||||||
views.setViewVisibility(container, View.VISIBLE)
|
|
||||||
val aodColor = AOD_STATUS_COLORS[t.status] ?: AOD_STATUS_COLORS["idle"]!!
|
|
||||||
views.setTextColor(dot, aodColor)
|
|
||||||
views.setTextViewText(name, "T${t.index} ${t.agent}")
|
|
||||||
} else {
|
|
||||||
views.setViewVisibility(container, View.GONE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return views
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildEmptyLockScreenViews(context: Context): RemoteViews {
|
|
||||||
return RemoteViews(context.packageName, R.layout.face_widget_lockscreen)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildEmptyAodViews(context: Context): RemoteViews {
|
|
||||||
return RemoteViews(context.packageName, R.layout.face_widget_aod)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fetchTerminals(context: Context): List<FaceWidgetTerminal> {
|
|
||||||
val apiBase = ServerConfig.apiBaseUrl(context) ?: return emptyList()
|
|
||||||
|
|
||||||
try {
|
|
||||||
val url = "$apiBase/session-state"
|
|
||||||
val req = Request.Builder().url(url).build()
|
|
||||||
val resp = client.newCall(req).execute()
|
|
||||||
if (!resp.isSuccessful) return emptyList()
|
|
||||||
|
|
||||||
val json = JSONObject(resp.body?.string() ?: "{}")
|
|
||||||
val registry = json.optJSONArray("registry") ?: return emptyList()
|
|
||||||
val agents = json.optJSONObject("agents")
|
|
||||||
|
|
||||||
val result = mutableListOf<FaceWidgetTerminal>()
|
|
||||||
|
|
||||||
for (i in 0 until minOf(registry.length(), 3)) { // Max 3 for face widget
|
|
||||||
val entry = registry.getJSONObject(i)
|
|
||||||
val agentName = entry.optString("agent", "")
|
|
||||||
val alive = entry.optBoolean("alive", false)
|
|
||||||
|
|
||||||
val agentState = agents?.optJSONObject(agentName)
|
|
||||||
val status = agentState?.optString("status", if (alive) "idle" else "closed")
|
|
||||||
?: if (alive) "idle" else "closed"
|
|
||||||
val statusColor = STATUS_COLORS[status] ?: STATUS_COLORS["idle"]!!
|
|
||||||
|
|
||||||
result.add(
|
|
||||||
FaceWidgetTerminal(
|
|
||||||
index = i + 1,
|
|
||||||
agent = agentName,
|
|
||||||
status = status,
|
|
||||||
statusColor = statusColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.w(TAG, "Failed to fetch terminals for face widget", e)
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class FaceWidgetTerminal(
|
|
||||||
val index: Int,
|
|
||||||
val agent: String,
|
|
||||||
val status: String,
|
|
||||||
val statusColor: Int
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
<solid android:color="#ff171717" />
|
|
||||||
<corners android:radius="22dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
<solid android:color="#99010101" />
|
|
||||||
<corners android:radius="22dp" />
|
|
||||||
</shape>
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:background="@drawable/face_widget_bg_aod">
|
|
||||||
|
|
||||||
<!-- Minimal AOD layout: title + terminal count -->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Agent UI"
|
|
||||||
android:textColor="#555588"
|
|
||||||
android:textSize="11sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:paddingBottom="4dp" />
|
|
||||||
|
|
||||||
<!-- Terminal 1 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_aod_terminal_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="1dp"
|
|
||||||
android:paddingBottom="1dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_dot_1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#444466"
|
|
||||||
android:textSize="7sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_name_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#777777"
|
|
||||||
android:textSize="9sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Terminal 2 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_aod_terminal_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="1dp"
|
|
||||||
android:paddingBottom="1dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_dot_2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#444466"
|
|
||||||
android:textSize="7sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_name_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#777777"
|
|
||||||
android:textSize="9sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Terminal 3 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_aod_terminal_3"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="1dp"
|
|
||||||
android:paddingBottom="1dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_dot_3"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#444466"
|
|
||||||
android:textSize="7sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_name_3"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#777777"
|
|
||||||
android:textSize="9sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Empty state -->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_aod_empty"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="No agents"
|
|
||||||
android:textColor="#444444"
|
|
||||||
android:textSize="9sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:gravity="center" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:background="@drawable/face_widget_bg_dark">
|
|
||||||
|
|
||||||
<!-- Title bar -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingBottom="6dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="Agent UI"
|
|
||||||
android:textColor="#8888FF"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:fontFamily="monospace" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_status"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#888888"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:fontFamily="monospace" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Terminal 1 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_terminal_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="2dp"
|
|
||||||
android:paddingBottom="2dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_dot_1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#6b7280"
|
|
||||||
android:textSize="8sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_name_1"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#DDDDDD"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Terminal 2 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_terminal_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="2dp"
|
|
||||||
android:paddingBottom="2dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_dot_2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#6b7280"
|
|
||||||
android:textSize="8sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_name_2"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#DDDDDD"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Terminal 3 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/fw_terminal_3"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingTop="2dp"
|
|
||||||
android:paddingBottom="2dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_dot_3"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="\u25CF"
|
|
||||||
android:textColor="#6b7280"
|
|
||||||
android:textSize="8sp"
|
|
||||||
android:paddingEnd="4dp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_name_3"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="#DDDDDD"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Empty state -->
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/fw_empty"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:text="No agents active"
|
|
||||||
android:textColor="#666666"
|
|
||||||
android:textSize="10sp"
|
|
||||||
android:fontFamily="monospace"
|
|
||||||
android:gravity="center" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"agent_ui_transcript": {
|
|
||||||
"menuInSetting": 1,
|
|
||||||
"labelResNameInSetting": "face_widget_label",
|
|
||||||
"actionDetailSetting": "com.agentui.desktop.FACE_WIDGET_SETTINGS"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,5 +2,4 @@
|
|||||||
<string name="app_name">Agent UI</string>
|
<string name="app_name">Agent UI</string>
|
||||||
<string name="main_activity_title">Agent UI</string>
|
<string name="main_activity_title">Agent UI</string>
|
||||||
<string name="widget_description">Shows recent transcript messages from Agent UI</string>
|
<string name="widget_description">Shows recent transcript messages from Agent UI</string>
|
||||||
<string name="face_widget_label">Agent UI Terminals</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user