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