Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
namespace Unity.Android.Logcat
{
internal static class AndroidLogcatAdbCommandCatalog
{
internal static readonly AndroidLogcatCommandEntry[] All = new[]
{
// --- Device Management ---
new AndroidLogcatCommandEntry("List Devices", "adb devices"),
new AndroidLogcatCommandEntry("List Devices (Verbose)", "adb devices -l"),
new AndroidLogcatCommandEntry("Start Server", "adb start-server"),
new AndroidLogcatCommandEntry("Kill Server", "adb kill-server"),
new AndroidLogcatCommandEntry("Reboot Device", "adb reboot"),
new AndroidLogcatCommandEntry("Reboot to Bootloader", "adb reboot bootloader"),
new AndroidLogcatCommandEntry("Reboot to Recovery", "adb reboot recovery"),
new AndroidLogcatCommandEntry("Get Device State", "adb get-state"),
new AndroidLogcatCommandEntry("Get Serial Number", "adb get-serialno"),
new AndroidLogcatCommandEntry("Wait for Device", "adb wait-for-device"),

// --- App Management ---
new AndroidLogcatCommandEntry("List All Packages", "adb shell pm list packages"),
new AndroidLogcatCommandEntry("List Third-Party Packages", "adb shell pm list packages -3"),
new AndroidLogcatCommandEntry("List System Packages", "adb shell pm list packages -s"),
new AndroidLogcatCommandEntry("Clear App Data", "adb shell pm clear <package>"),
new AndroidLogcatCommandEntry("Force Stop App", "adb shell am force-stop <package>"),
new AndroidLogcatCommandEntry("Start Activity", "adb shell am start -n <package/activity>"),
new AndroidLogcatCommandEntry("Start App (Launcher)", "adb shell monkey -p <package> -c android.intent.category.LAUNCHER 1"),
new AndroidLogcatCommandEntry("Start App (UnityPlayerActivity)", "adb shell am start -n <package>/com.unity3d.player.UnityPlayerActivity"),
new AndroidLogcatCommandEntry("Start App (GameActivity)", "adb shell am start -n <package>/com.google.androidgamesdk.GameActivity"),
new AndroidLogcatCommandEntry("Uninstall App", "adb uninstall <package>"),
new AndroidLogcatCommandEntry("Install APK", "adb install <path.apk>"),
new AndroidLogcatCommandEntry("Install APK (Replace)", "adb install -r <path.apk>"),
new AndroidLogcatCommandEntry("Install Multiple APKs (Split)", "adb install-multiple -r <path1.apk> <path2.apk>"),
new AndroidLogcatCommandEntry("Push OBB File", "adb push <local.obb> /sdcard/Android/obb/<package>/"),
new AndroidLogcatCommandEntry("Create OBB Directory", "adb shell mkdir -p /sdcard/Android/obb/<package>"),
new AndroidLogcatCommandEntry("Grant Permission", "adb shell pm grant <package> <permission>"),
new AndroidLogcatCommandEntry("Revoke Permission", "adb shell pm revoke <package> <permission>"),
new AndroidLogcatCommandEntry("Dump App Info", "adb shell dumpsys package <package>"),

// --- File Transfer ---
new AndroidLogcatCommandEntry("Push File to Device", "adb push <local> <remote>"),
new AndroidLogcatCommandEntry("Pull File from Device", "adb pull <remote> <local>"),
new AndroidLogcatCommandEntry("List Directory", "adb shell ls -la <path>"),
new AndroidLogcatCommandEntry("Remove File", "adb shell rm <path>"),
new AndroidLogcatCommandEntry("Make Directory", "adb shell mkdir -p <path>"),

// --- Logcat ---
new AndroidLogcatCommandEntry("View Logcat", "adb logcat"),
new AndroidLogcatCommandEntry("Clear Logcat", "adb logcat -c"),
new AndroidLogcatCommandEntry("Dump Logcat & Exit", "adb logcat -d"),
new AndroidLogcatCommandEntry("Logcat Errors Only", "adb logcat *:E"),
new AndroidLogcatCommandEntry("Logcat Warnings & Above", "adb logcat *:W"),
new AndroidLogcatCommandEntry("Logcat with Timestamps", "adb logcat -v time"),
new AndroidLogcatCommandEntry("Logcat by Tag", "adb logcat -s <TAG>"),
new AndroidLogcatCommandEntry("Logcat Unity Only", "adb logcat -s Unity"),

// --- Screen Capture ---
new AndroidLogcatCommandEntry("Take Screenshot", "adb shell screencap /sdcard/screenshot.png"),
new AndroidLogcatCommandEntry("Record Screen", "adb shell screenrecord /sdcard/recording.mp4"),
new AndroidLogcatCommandEntry("Record Screen (30s)", "adb shell screenrecord --time-limit 30 /sdcard/recording.mp4"),

// --- System Info ---
new AndroidLogcatCommandEntry("Get Android Version", "adb shell getprop ro.build.version.release"),
new AndroidLogcatCommandEntry("Get SDK Version", "adb shell getprop ro.build.version.sdk"),
new AndroidLogcatCommandEntry("Get Device Model", "adb shell getprop ro.product.model"),
new AndroidLogcatCommandEntry("Get Device Manufacturer", "adb shell getprop ro.product.manufacturer"),
new AndroidLogcatCommandEntry("Get All Properties", "adb shell getprop"),
new AndroidLogcatCommandEntry("Get Screen Resolution", "adb shell wm size"),
new AndroidLogcatCommandEntry("Get Screen Density", "adb shell wm density"),
new AndroidLogcatCommandEntry("Get Battery Info", "adb shell dumpsys battery"),
new AndroidLogcatCommandEntry("Get CPU Info", "adb shell cat /proc/cpuinfo"),
new AndroidLogcatCommandEntry("Get Memory Info", "adb shell cat /proc/meminfo"),
new AndroidLogcatCommandEntry("Get Disk Usage", "adb shell df"),
new AndroidLogcatCommandEntry("Get Running Processes", "adb shell ps"),
new AndroidLogcatCommandEntry("Get Top Processes", "adb shell top -n 1"),
new AndroidLogcatCommandEntry("Get Build Properties", "adb shell cat /system/build.prop"),

// --- Input Simulation ---
new AndroidLogcatCommandEntry("Send Keyevent (Home)", "adb shell input keyevent KEYCODE_HOME"),
new AndroidLogcatCommandEntry("Send Keyevent (Back)", "adb shell input keyevent KEYCODE_BACK"),
new AndroidLogcatCommandEntry("Send Keyevent (Menu)", "adb shell input keyevent KEYCODE_MENU"),
new AndroidLogcatCommandEntry("Send Keyevent (Power)", "adb shell input keyevent KEYCODE_POWER"),
new AndroidLogcatCommandEntry("Send Keyevent (Volume Up)", "adb shell input keyevent KEYCODE_VOLUME_UP"),
new AndroidLogcatCommandEntry("Send Keyevent (Volume Down)", "adb shell input keyevent KEYCODE_VOLUME_DOWN"),
new AndroidLogcatCommandEntry("Send Keyevent (Enter)", "adb shell input keyevent KEYCODE_ENTER"),
new AndroidLogcatCommandEntry("Send Keyevent (Tab)", "adb shell input keyevent KEYCODE_TAB"),
new AndroidLogcatCommandEntry("Send Text", "adb shell input text <text>"),
new AndroidLogcatCommandEntry("Tap Screen", "adb shell input tap <x> <y>"),
new AndroidLogcatCommandEntry("Swipe Screen", "adb shell input swipe <x1> <y1> <x2> <y2>"),

// --- Networking ---
new AndroidLogcatCommandEntry("Enable WiFi ADB", "adb tcpip 5555"),
new AndroidLogcatCommandEntry("Connect via IP", "adb connect <ip>:5555"),
new AndroidLogcatCommandEntry("Disconnect All", "adb disconnect"),
new AndroidLogcatCommandEntry("Forward Port", "adb forward tcp:<local> tcp:<remote>"),
new AndroidLogcatCommandEntry("Reverse Port", "adb reverse tcp:<remote> tcp:<local>"),
new AndroidLogcatCommandEntry("Get IP Address", "adb shell ip addr show wlan0"),
new AndroidLogcatCommandEntry("Ping Host", "adb shell ping -c 4 <host>"),

// --- Dumpsys ---
new AndroidLogcatCommandEntry("Dump Activity Stack", "adb shell dumpsys activity activities"),
new AndroidLogcatCommandEntry("Dump Memory Info", "adb shell dumpsys meminfo"),
new AndroidLogcatCommandEntry("Dump Window Info", "adb shell dumpsys window"),
new AndroidLogcatCommandEntry("Dump Display Info", "adb shell dumpsys display"),
new AndroidLogcatCommandEntry("Dump CPU Info", "adb shell dumpsys cpuinfo"),
new AndroidLogcatCommandEntry("Dump Battery Stats", "adb shell dumpsys batterystats"),
new AndroidLogcatCommandEntry("Dump SurfaceFlinger", "adb shell dumpsys SurfaceFlinger"),
new AndroidLogcatCommandEntry("Dump Graphics Stats", "adb shell dumpsys gfxinfo <package>"),
new AndroidLogcatCommandEntry("Dump Wifi Info", "adb shell dumpsys wifi"),
new AndroidLogcatCommandEntry("Dump Alarm Info", "adb shell dumpsys alarm"),
new AndroidLogcatCommandEntry("Dump Notification Info", "adb shell dumpsys notification"),

// --- Settings ---
new AndroidLogcatCommandEntry("Enable Stay Awake", "adb shell settings put global stay_on_while_plugged_in 3"),
new AndroidLogcatCommandEntry("Disable Stay Awake", "adb shell settings put global stay_on_while_plugged_in 0"),
new AndroidLogcatCommandEntry("Show Touches On", "adb shell settings put system show_touches 1"),
new AndroidLogcatCommandEntry("Show Touches Off", "adb shell settings put system show_touches 0"),
new AndroidLogcatCommandEntry("Enable USB Debugging", "adb shell settings put global adb_enabled 1"),
new AndroidLogcatCommandEntry("Set Screen Off Timeout", "adb shell settings put system screen_off_timeout <ms>"),

// --- Debug / Advanced ---
new AndroidLogcatCommandEntry("Bug Report", "adb bugreport"),
new AndroidLogcatCommandEntry("Remount System", "adb remount"),
new AndroidLogcatCommandEntry("Root Shell", "adb root"),
new AndroidLogcatCommandEntry("Unroot Shell", "adb unroot"),
new AndroidLogcatCommandEntry("Disable Verity", "adb disable-verity"),
new AndroidLogcatCommandEntry("Enable Verity", "adb enable-verity"),
new AndroidLogcatCommandEntry("Wait for Device Boot", "adb wait-for-device shell getprop sys.boot_completed"),
new AndroidLogcatCommandEntry("List Tombstones", "adb shell ls -lt /data/tombstones/"),
new AndroidLogcatCommandEntry("Pull Tombstone", "adb pull /data/tombstones/<tombstone_XX> <local_path>"),

// --- Meta Quest / XR ---
new AndroidLogcatCommandEntry("List OVR Packages", "adb shell pm list packages | grep oculus"),
new AndroidLogcatCommandEntry("Get Guardian State", "adb shell dumpsys OVRGuardianService"),
new AndroidLogcatCommandEntry("Get Compositor Stats", "adb shell dumpsys OVRCompositor"),
new AndroidLogcatCommandEntry("Set GPU Level", "adb shell setprop debug.oculus.gpuLevel <0-4>"),
new AndroidLogcatCommandEntry("Set CPU Level", "adb shell setprop debug.oculus.cpuLevel <0-4>"),
new AndroidLogcatCommandEntry("Enable Perf Overlay", "adb shell setprop debug.oculus.enablePerfOverlay 1"),
new AndroidLogcatCommandEntry("Disable Perf Overlay", "adb shell setprop debug.oculus.enablePerfOverlay 0"),
new AndroidLogcatCommandEntry("Set Fixed Foveation", "adb shell setprop debug.oculus.foveation.level <0-4>"),
new AndroidLogcatCommandEntry("Set Refresh Rate", "adb shell setprop debug.oculus.refreshRate <72|90|120>"),

// --- AAB / Bundletool ---
new AndroidLogcatCommandEntry("bundletool: Build Split APKs", "java -jar bundletool.jar build-apks --bundle=<path.aab> --output=<output.apks> --connected-device"),
new AndroidLogcatCommandEntry("bundletool: Install APKs", "java -jar bundletool.jar install-apks --apks=<path.apks>"),
new AndroidLogcatCommandEntry("bundletool: Get Device Spec", "java -jar bundletool.jar get-device-spec --output=<device-spec.json>"),
};
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace Unity.Android.Logcat
{
internal class AndroidLogcatAddCommandDialog : EditorWindow
{
string m_Name = "";
string m_Command = "";
Action<AndroidLogcatCommandEntry> m_OnSave;
bool m_IsEdit;

internal static void Show(Action<AndroidLogcatCommandEntry> onSave, AndroidLogcatCommandEntry existing = null)
{
var wnd = CreateInstance<AndroidLogcatAddCommandDialog>();
wnd.titleContent = new GUIContent(existing != null ? "Edit Command" : "Add Command");
wnd.m_OnSave = onSave;
wnd.minSize = new Vector2(400, 200);
wnd.maxSize = new Vector2(600, 400);

if (existing != null)
{
wnd.m_Name = existing.name;
wnd.m_Command = existing.command;
wnd.m_IsEdit = true;
}

wnd.ShowUtility();
}

void OnEnable()
{
LoadUI();
}

void LoadUI()
{
var r = rootVisualElement;
var tree = AndroidLogcatUtilities.LoadUXML("AndroidLogcatAddCommand.uxml");
tree.CloneTree(r);

var nameField = r.Q<TextField>("NameField");
nameField.value = m_Name;
nameField.RegisterValueChangedCallback(evt => m_Name = evt.newValue);

var commandField = r.Q<TextField>("CommandField");
commandField.value = m_Command;
commandField.RegisterValueChangedCallback(evt => m_Command = evt.newValue);

var saveButton = r.Q<Button>("SaveButton");
saveButton.text = m_IsEdit ? "Save" : "Add";
saveButton.clicked += OnSaveClicked;

r.Q<Button>("CancelButton").clicked += () => Close();
}

void OnSaveClicked()
{
if (string.IsNullOrWhiteSpace(m_Name) || string.IsNullOrWhiteSpace(m_Command))
{
EditorUtility.DisplayDialog("Android Logcat", "Both name and command are required.", "OK");
return;
}

m_OnSave?.Invoke(new AndroidLogcatCommandEntry(m_Name.Trim(), m_Command.Trim()));
Close();
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using UnityEngine;

namespace Unity.Android.Logcat
{
[Serializable]
internal class AndroidLogcatCommandEntry
{
[SerializeField] internal string name;
[SerializeField] internal string command;

internal AndroidLogcatCommandEntry() { }

internal AndroidLogcatCommandEntry(string name, string command)
{
this.name = name;
this.command = command;
}
}

[Serializable]
internal class AndroidLogcatCommandExportData
{
public AndroidLogcatCommandEntry[] favorites = Array.Empty<AndroidLogcatCommandEntry>();
public AndroidLogcatCommandEntry[] general = Array.Empty<AndroidLogcatCommandEntry>();
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
using System.Collections.Generic;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace Unity.Android.Logcat
{
internal class AndroidLogcatCommandOutputWindow : EditorWindow
{
static AndroidLogcatCommandOutputWindow s_Instance;

readonly List<AndroidLogcatCommandsWindow.OutputLine> m_Lines = new List<AndroidLogcatCommandsWindow.OutputLine>();
bool m_AutoScroll = true;
const int kMaxLines = 5000;

ScrollView m_ScrollView;
VisualElement m_OutputContainer;

internal static void Open(List<AndroidLogcatCommandsWindow.OutputLine> existingLines)
{
var wnd = GetWindow<AndroidLogcatCommandOutputWindow>();
wnd.titleContent = new GUIContent("Command Output");
wnd.minSize = new Vector2(500, 300);
s_Instance = wnd;

wnd.m_Lines.Clear();
if (existingLines != null)
wnd.m_Lines.AddRange(existingLines);
wnd.RefreshOutput();
}

internal static void AppendIfOpen(string text, Color color)
{
if (s_Instance == null || string.IsNullOrEmpty(text))
return;

foreach (var line in text.Split('\n'))
{
var ol = new AndroidLogcatCommandsWindow.OutputLine { text = line, color = color };
s_Instance.m_Lines.Add(ol);
s_Instance.AddLineElement(ol);
}
Comment on lines +33 to +43

if (s_Instance.m_Lines.Count > kMaxLines)
{
var excess = s_Instance.m_Lines.Count - kMaxLines;
s_Instance.m_Lines.RemoveRange(0, excess);
for (int i = 0; i < excess && s_Instance.m_OutputContainer.childCount > 0; i++)
s_Instance.m_OutputContainer.RemoveAt(0);
}

if (s_Instance.m_AutoScroll)
s_Instance.ScrollToBottom();
}

void OnEnable()
{
s_Instance = this;
LoadUI();
}

void LoadUI()
{
var r = rootVisualElement;
var tree = AndroidLogcatUtilities.LoadUXML("AndroidLogcatCommandOutput.uxml");
tree.CloneTree(r);

m_ScrollView = r.Q<ScrollView>("OutputScroll");
m_OutputContainer = r.Q<VisualElement>("OutputContainer");

r.Q<Button>("ClearButton").clicked += () => { m_Lines.Clear(); m_OutputContainer?.Clear(); };
r.Q<Button>("CopyAllButton").clicked += CopyAll;

var autoScrollToggle = r.Q<Toggle>("AutoScrollToggle");
autoScrollToggle.value = m_AutoScroll;
autoScrollToggle.RegisterValueChangedCallback(evt => m_AutoScroll = evt.newValue);

foreach (var line in m_Lines)
AddLineElement(line);
}

void AddLineElement(AndroidLogcatCommandsWindow.OutputLine line)
{
var label = new Label(line.text);
label.style.color = new StyleColor(line.color);
label.style.whiteSpace = WhiteSpace.Normal;
m_OutputContainer.Add(label);
}

void RefreshOutput()
{
if (m_OutputContainer == null)
return;
m_OutputContainer.Clear();
foreach (var line in m_Lines)
AddLineElement(line);
if (m_AutoScroll)
ScrollToBottom();
}

void ScrollToBottom()
{
if (m_ScrollView == null || m_OutputContainer == null || m_OutputContainer.childCount == 0)
return;
m_ScrollView.schedule.Execute(() => m_ScrollView.ScrollTo(m_OutputContainer[m_OutputContainer.childCount - 1])).StartingIn(10);
}

void CopyAll()
{
var sb = new StringBuilder();
foreach (var line in m_Lines)
sb.AppendLine(line.text);
EditorGUIUtility.systemCopyBuffer = sb.ToString();
}

void OnDestroy()
{
if (s_Instance == this)
s_Instance = null;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading