diff --git a/.auto-claude-security.json b/.auto-claude-security.json
new file mode 100644
index 0000000..f740b91
--- /dev/null
+++ b/.auto-claude-security.json
@@ -0,0 +1,185 @@
+{
+ "base_commands": [
+ ".",
+ "[",
+ "[[",
+ "ag",
+ "awk",
+ "basename",
+ "bash",
+ "bc",
+ "break",
+ "cat",
+ "cd",
+ "chmod",
+ "clear",
+ "cmp",
+ "column",
+ "comm",
+ "command",
+ "continue",
+ "cp",
+ "curl",
+ "cut",
+ "date",
+ "df",
+ "diff",
+ "dig",
+ "dirname",
+ "du",
+ "echo",
+ "egrep",
+ "env",
+ "eval",
+ "exec",
+ "exit",
+ "expand",
+ "export",
+ "expr",
+ "false",
+ "fd",
+ "fgrep",
+ "file",
+ "find",
+ "fmt",
+ "fold",
+ "gawk",
+ "gh",
+ "git",
+ "grep",
+ "gunzip",
+ "gzip",
+ "head",
+ "help",
+ "host",
+ "iconv",
+ "id",
+ "jobs",
+ "join",
+ "jq",
+ "kill",
+ "killall",
+ "less",
+ "let",
+ "ln",
+ "ls",
+ "lsof",
+ "man",
+ "mkdir",
+ "mktemp",
+ "more",
+ "mv",
+ "nl",
+ "paste",
+ "pgrep",
+ "ping",
+ "pkill",
+ "popd",
+ "printenv",
+ "printf",
+ "ps",
+ "pushd",
+ "pwd",
+ "read",
+ "readlink",
+ "realpath",
+ "reset",
+ "return",
+ "rev",
+ "rg",
+ "rm",
+ "rmdir",
+ "sed",
+ "seq",
+ "set",
+ "sh",
+ "shuf",
+ "sleep",
+ "sort",
+ "source",
+ "split",
+ "stat",
+ "tail",
+ "tar",
+ "tee",
+ "test",
+ "time",
+ "timeout",
+ "touch",
+ "tr",
+ "tree",
+ "true",
+ "type",
+ "uname",
+ "unexpand",
+ "uniq",
+ "unset",
+ "unzip",
+ "watch",
+ "wc",
+ "wget",
+ "whereis",
+ "which",
+ "whoami",
+ "xargs",
+ "yes",
+ "yq",
+ "zip",
+ "zsh"
+ ],
+ "stack_commands": [
+ "ant",
+ "gradle",
+ "gradlew",
+ "ipython",
+ "jar",
+ "java",
+ "javac",
+ "jupyter",
+ "kotlin",
+ "kotlinc",
+ "maven",
+ "mvn",
+ "node",
+ "notebook",
+ "npm",
+ "npx",
+ "pdb",
+ "pip",
+ "pip3",
+ "pipx",
+ "pudb",
+ "python",
+ "python3"
+ ],
+ "script_commands": [],
+ "custom_commands": [],
+ "detected_stack": {
+ "languages": [
+ "python",
+ "javascript",
+ "java",
+ "kotlin"
+ ],
+ "package_managers": [
+ "gradle"
+ ],
+ "frameworks": [],
+ "databases": [],
+ "infrastructure": [],
+ "cloud_providers": [],
+ "code_quality_tools": [],
+ "version_managers": []
+ },
+ "custom_scripts": {
+ "npm_scripts": [],
+ "make_targets": [],
+ "poetry_scripts": [],
+ "cargo_aliases": [],
+ "shell_scripts": []
+ },
+ "project_dir": "D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb",
+ "created_at": "2026-02-05T12:56:49.824459",
+ "project_hash": "0d6be561318e22002fe7a184fb411324",
+ "inherited_from": "D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb"
+}
\ No newline at end of file
diff --git a/.auto-claude-status b/.auto-claude-status
new file mode 100644
index 0000000..db8b938
--- /dev/null
+++ b/.auto-claude-status
@@ -0,0 +1,25 @@
+{
+ "active": true,
+ "spec": "002-quick-settings-tile",
+ "state": "building",
+ "subtasks": {
+ "completed": 9,
+ "total": 10,
+ "in_progress": 1,
+ "failed": 0
+ },
+ "phase": {
+ "current": "Integration Testing",
+ "id": null,
+ "total": 2
+ },
+ "workers": {
+ "active": 0,
+ "max": 1
+ },
+ "session": {
+ "number": 12,
+ "started_at": "2026-02-07T01:52:02.329153"
+ },
+ "last_update": "2026-02-07T02:19:18.722326"
+}
\ No newline at end of file
diff --git a/.claude_settings.json b/.claude_settings.json
new file mode 100644
index 0000000..40e7866
--- /dev/null
+++ b/.claude_settings.json
@@ -0,0 +1,39 @@
+{
+ "sandbox": {
+ "enabled": true,
+ "autoAllowBashIfSandboxed": true
+ },
+ "permissions": {
+ "defaultMode": "acceptEdits",
+ "allow": [
+ "Read(./**)",
+ "Write(./**)",
+ "Edit(./**)",
+ "Glob(./**)",
+ "Grep(./**)",
+ "Read(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile/**)",
+ "Write(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile/**)",
+ "Edit(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile/**)",
+ "Glob(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile/**)",
+ "Grep(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile/**)",
+ "Read(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile\\.auto-claude\\specs\\002-quick-settings-tile/**)",
+ "Write(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile\\.auto-claude\\specs\\002-quick-settings-tile/**)",
+ "Edit(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude\\worktrees\\tasks\\002-quick-settings-tile\\.auto-claude\\specs\\002-quick-settings-tile/**)",
+ "Read(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude/**)",
+ "Write(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude/**)",
+ "Edit(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude/**)",
+ "Glob(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude/**)",
+ "Grep(D:\\AI\\Android\\APK\\Android-Apps\\apps\\wirelessadb\\.auto-claude/**)",
+ "Bash(*)",
+ "WebFetch(*)",
+ "WebSearch(*)",
+ "mcp__context7__resolve-library-id(*)",
+ "mcp__context7__get-library-docs(*)",
+ "mcp__graphiti-memory__search_nodes(*)",
+ "mcp__graphiti-memory__search_facts(*)",
+ "mcp__graphiti-memory__add_episode(*)",
+ "mcp__graphiti-memory__get_episodes(*)",
+ "mcp__graphiti-memory__get_entity_edge(*)"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f0afa5e..d3992d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,30 +1,33 @@
-# Gradle
-.gradle/
-build/
-!gradle/wrapper/gradle-wrapper.jar
-
-# Android
-*.apk
-*.aab
-*.ap_
-*.dex
-local.properties
-
-# IDE
-.idea/
-*.iml
-.DS_Store
-
-# Research (local notes, not for repo)
-research/
-
-# Signing secrets (NEVER commit!)
-*.keystore
-*.jks
-.env
-
-# Screenshots and temp files
-screenshot*.png
-temp/
-nul
-.serena/
+# Gradle
+.gradle/
+build/
+!gradle/wrapper/gradle-wrapper.jar
+
+# Android
+*.apk
+*.aab
+*.ap_
+*.dex
+local.properties
+
+# IDE
+.idea/
+*.iml
+.DS_Store
+
+# Research (local notes, not for repo)
+research/
+
+# Signing secrets (NEVER commit!)
+*.keystore
+*.jks
+.env
+
+# Screenshots and temp files
+screenshot*.png
+temp/
+nul
+.serena/
+
+# Auto Claude data directory
+.auto-claude/
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c5209b8..96f025e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,6 +37,17 @@
android:value="adb_management" />
+
+
+
+
+
+
+ Log.e(TAG, "onClick: toggle failed - ${error.message}")
+ updateTileState()
+ }
+ )
+ } catch (e: Exception) {
+ Log.e(TAG, "onClick: error - ${e.message}")
+ }
+ }
+ }
+
+ /**
+ * Opens the main activity when the tile is long-pressed.
+ * This provides access to full app settings and features.
+ * Long-press is automatically handled by the Android system.
+ */
+ private fun openMainActivity() {
+ val intent = Intent(this, MainActivity::class.java).apply {
+ flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
+ }
+ startActivityAndCollapse(intent)
+ Log.d(TAG, "Opening MainActivity from tile")
+ }
+
+ /**
+ * Update the tile state based on current ADB status.
+ * Updates the tile's state (active/inactive), label, and subtitle.
+ */
+ private fun updateTileState() {
+ serviceScope.launch {
+ try {
+ val status = AdbManager.getStatus(applicationContext)
+ Log.d(TAG, "updateTileState: enabled=${status.enabled}, port=${status.port}, ip=${status.ip}")
+
+ qsTile?.apply {
+ // Set tile state
+ state = if (status.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
+
+ // Set icon based on state
+ icon = if (status.enabled) {
+ Icon.createWithResource(this@AdbTileService, R.drawable.ic_tile_adb_active)
+ } else {
+ Icon.createWithResource(this@AdbTileService, R.drawable.ic_tile_adb_inactive)
+ }
+
+ // Set label
+ label = "Wireless ADB"
+
+ // Set subtitle with connection info
+ subtitle = if (status.enabled) {
+ val ip = status.ip ?: "No WiFi"
+ "On - $ip:${status.port}"
+ } else {
+ getString(R.string.tile_subtitle_inactive)
+ }
+
+ // Update the tile UI
+ updateTile()
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "updateTileState: error - ${e.message}")
+ // Set error state
+ qsTile?.apply {
+ state = Tile.STATE_INACTIVE
+ icon = Icon.createWithResource(this@AdbTileService, R.drawable.ic_tile_adb_inactive)
+ label = "Wireless ADB"
+ subtitle = "Error"
+ updateTile()
+ }
+ }
+ }
+ }
+
+ /**
+ * Clean up resources when service is destroyed.
+ */
+ override fun onDestroy() {
+ serviceScope.cancel()
+ super.onDestroy()
+ }
+}
diff --git a/app/src/main/res/drawable/ic_tile_adb_active.xml b/app/src/main/res/drawable/ic_tile_adb_active.xml
new file mode 100644
index 0000000..45b076e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_tile_adb_active.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_tile_adb_inactive.xml b/app/src/main/res/drawable/ic_tile_adb_inactive.xml
new file mode 100644
index 0000000..8fb4562
--- /dev/null
+++ b/app/src/main/res/drawable/ic_tile_adb_inactive.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e87d4ad..a15f1bd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -328,4 +328,9 @@
Added: %1$s
Requested: Now
Remove device
+
+
+ Wireless ADB
+ Active on port %1$d
+ Tap to enable