Skip to content
Merged
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
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ Add entries under **Unreleased** in each pull request. The *Bump version* workfl
- MIT license, code of conduct, and a demo GIF in the README showing each feature's effect in the sample app.
- `NetworkLogger.maxTotalBodyChars` (default 12M characters) caps the bodies kept across all calls; the oldest bodies are dropped first, their calls stay listed.
- `AppActions.clearCacheInBackground()` clears the cache off the main thread.
- `TextInputItem`, `NumberInputItem` and `JsonInputItem` take an optional `subtitle`; feature flags of every type now show *Overridden* and a *Reset to default* action.
- `TextInputItem`, `NumberInputItem` and `JsonInputItem` take an optional `subtitle`.
- While recording the screen, a small floating bar shows the time with pause/resume (Android 7+) and stop, so you don't have to reopen the drawer; the drawer header shows a *Recording* chip with a red stop button that stays in place while the chips scroll (tapping the chip opens the screen capture tools), and the notification has Pause/Resume too.
- A *System language & region* button in the User Interface section opens Android's language and region settings (`LocaleSettingsButton()`; hide it with `AppearancePlugin(localeSettings = false)`).
- The feature flags page has *Restart screen* and *Restart app* buttons, so flag changes that are read once per screen or process take effect.
- After switching endpoints, `EndpointPlugin` shows a *Restart app* button so the app picks up the new endpoint, unless `restartOnChange` or `onChanged` already applies it.
- Share buttons on the Logs and Network activity pages, and share-all / delete-all in the capture gallery.
- Consumer R8 rules for devdeck-okhttp, devdeck-timber and devdeck-appdistribution, so minified builds don't fail when OkHttp, Timber or Firebase isn't on the classpath.

Expand All @@ -22,6 +26,16 @@ Add entries under **Unreleased** in each pull request. The *Bump version* workfl
- The device & app snapshot shows share, save and copy as small icons on the card; they are not part of the shared image.
- The deep link launcher opens links from a send icon inside the field, leaving more room on small phones.
- The sample app is named DevDeck.
- Permissions open on their own page instead of expanding inside the System section.
- The update chip in the header reads *New version* and opens the App section at *Test build updates*.
- Drawer text is a little smaller, list rows use Material's 48dp minimum height, and section titles and dividers take less space, so more fits on small phones.
- The header's settings and close buttons sit closer together.
- *Device info* moved from the System section to the Info section, next to *App info*; hide either with `InfoPlugin(appInfo = false, deviceInfo = false)`. `DevicePlugin(deviceInfo = …)` still compiles but no longer has an effect.
- The app version shows under the drawer subtitle (*Version 1.0.0 (10000)*) instead of as a chip.
- *Take a screenshot*, *Record a video*, *Open the gallery* and deep link suggestions use the standard button and page rows instead of bullet points.
- The floating button stays where you drag it, across screens, opening the drawer and app restarts.
- The Info section starts with *App info*: version, package, build type and flavor (from the app's `BuildConfig` when it exists), whether the build is debuggable or R8 obfuscated or shrunk, and target and min SDK. `AppInfo()` and the device & app snapshot show the same details; the snapshot no longer lists install and update times, and shows *Debuggable* rather than a guessed build type when the app has no `BuildConfig`.
- Toggle flags no longer show an *Overridden* subtitle.
- Clearing logs, crash logs, breadcrumbs, requests, console lines, captures or shared preferences, and resetting all feature flags, now ask for a second tap.
- Network request actions (*Copy URL*, *Copy cURL*, *Share*) and label rows wrap on narrow screens instead of overflowing.
- Category, level and status colors have dark-theme variants, and labels on colored fills pick a readable text color.
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ OkHttpClient.Builder().apply { DebugTools.interceptors().forEach(::addIntercepto
|---|---|---|
| Two-finger swipe toward the drawer, anywhere on screen | On | `gestures = DeckGestures(twoFingerSwipe = false)` |
| **Ctrl + Shift + D** (emulator or hardware keyboard) | On | `DeckGestures(keyboardShortcut = DeckShortcut(keyCode = KeyEvent.KEYCODE_F12, ctrl = false, shift = false))`, or `null` to turn off |
| Floating bug button (draggable) | On | `trigger = DeckTrigger.None` |
| Floating bug button (draggable; it stays where you leave it) | On | `trigger = DeckTrigger.None` |
| Code | — | `DevDeck.open()`, `DevDeck.close()`, `DevDeck.toggle()` |

- DevDeck never covers your controls. The swipe is detected by watching touches without taking them, so taps, scrolls and system back keep working.
Expand Down Expand Up @@ -162,9 +162,9 @@ DevDeck.install(
| `AppearancePlugin` | User Interface | Dark mode (Android 12+) and app language (Android 13+) override | ✓ |
| `PerformancePlugin` | System | FPS / jank / memory overlay and memory details | ✓ |
| `StoragePlugin` | System | SharedPreferences browser/editor and storage usage | ✓ |
| `DevicePlugin` | System | Device info, permissions (request, revoke, open settings), developer options | ✓ |
| `DevicePlugin` | System | Permissions (request, revoke, open settings), developer options | ✓ |
| `UpdatesPlugin` | App | New test build check, release notes and install (module `devdeck-appdistribution` for Firebase) | — needs a source |
| `InfoPlugin` | Info | Device & app snapshot image, bug report, version | ✓ |
| `InfoPlugin` | Info | App info (version, build type, R8, SDK levels), device info, device & app snapshot image, bug report, version | ✓ |

Every plugin takes a `section` (or `null` for no header) and switches to hide individual rows, e.g. `UiToolsPlugin(screenCapture = false)`.

Expand Down Expand Up @@ -243,7 +243,7 @@ The memory rows under **Simulate 🧪** reproduce what the app sees on a low-mem

### Test build updates

`UpdatesPlugin` tells testers when a newer test build is available. It shows a green *Update · v1.4.0 (412)* chip in the drawer header and a dot on the floating button. The plugin row shows the release notes, an *Install latest* button with download progress, a refresh icon to check again, and tester sign-in.
`UpdatesPlugin` tells testers when a newer test build is available. It shows a green *New version · v1.4.0 (412)* chip in the drawer header, which jumps to the plugin row, and a dot on the floating button. The plugin row shows the release notes, an *Install latest* button with download progress, a refresh icon to check again, and tester sign-in.

With Firebase App Distribution:

Expand Down Expand Up @@ -306,11 +306,12 @@ The last 50 steps are saved with every crash and shown as *Steps before the cras

### Screen capture, bug reports and device info

- **Screenshot / screen recording / gallery:** under User Interface. Recording asks for Android's screen-capture permission and shows a Stop notification.
- **Screenshot / screen recording / gallery:** under User Interface. Recording asks for Android's screen-capture permission. While it runs, a small floating bar shows the time with pause/resume (Android 7+) and stop, the drawer header shows a *Recording* chip and a red stop button, and the notification has the same controls. The floating bar is drawn in your app's window, so it appears in the video.
- **App info and device info:** under Info. App info shows the version, package, build type and flavor (read from your app's `BuildConfig` when it exists and R8 hasn't removed it), whether the build is debuggable, R8 state and SDK levels.
- **Device & app snapshot:** under Info. One image with app version, build type, SDKs, device, Android version, screen and locale, plus your `buildInfo`. Share it, save it, or copy it as text from the icons on the card; the icons are left out of the image.
- **App settings:** the ⚙ button next to the drawer's close button opens the app's system settings page.
- **Bug report:** a description, recent steps, your logs, recent logcat, device info and chosen captures, sent through the share sheet.
- **Permissions:** under System. Each permission shows Granted or Denied with what you can do about it. *Request* shows the system dialog, or opens the app's settings once Android stops asking. *Revoke* (Android 13+) removes a runtime permission when the app closes; until then the row shows *Revoked when the app restarts*. The list refreshes when you come back from a permission dialog or settings screen. *Open settings* handles special permissions such as drawing over other apps. Install-time permissions can't change, so they are only listed. To grant or revoke silently, use `adb shell pm grant` / `pm revoke`.
- **Permissions:** under System, on their own page. Each permission shows Granted or Denied with what you can do about it. *Request* shows the system dialog, or opens the app's settings once Android stops asking. *Revoke* (Android 13+) removes a runtime permission when the app closes; until then the row shows *Revoked when the app restarts*. The list refreshes when you come back from a permission dialog or settings screen. *Open settings* handles special permissions such as drawing over other apps. Install-time permissions can't change, so they are only listed. To grant or revoke silently, use `adb shell pm grant` / `pm revoke`.

---

Expand Down
11 changes: 9 additions & 2 deletions devdeck/api/devdeck.api
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ public final class io/devdeck/actions/DeepLinkLauncherKt {
public final class io/devdeck/appearance/AppearanceKt {
public static final fun DisplaySettingsButton (Landroidx/compose/ui/Modifier;Ljava/lang/String;Landroidx/compose/runtime/Composer;II)V
public static final fun LanguageSelector (Ljava/util/List;Landroidx/compose/ui/Modifier;Ljava/lang/String;Landroidx/compose/runtime/Composer;II)V
public static final fun LocaleSettingsButton (Landroidx/compose/ui/Modifier;Ljava/lang/String;Landroidx/compose/runtime/Composer;II)V
public static final fun NightModeSelector (Landroidx/compose/ui/Modifier;Ljava/lang/String;Landroidx/compose/runtime/Composer;II)V
}

Expand Down Expand Up @@ -347,6 +348,8 @@ public final class io/devdeck/capture/ScreenRecordButtonKt {

public final class io/devdeck/capture/ScreenRecordingService : android/app/Service {
public static final field $stable I
public static final field ACTION_PAUSE Ljava/lang/String;
public static final field ACTION_RESUME Ljava/lang/String;
public static final field ACTION_START Ljava/lang/String;
public static final field ACTION_STOP Ljava/lang/String;
public static final field EXTRA_DATA Ljava/lang/String;
Expand Down Expand Up @@ -969,8 +972,10 @@ public final class io/devdeck/plugin/AppActionsPlugin : io/devdeck/plugin/DeckPl
public final class io/devdeck/plugin/AppearancePlugin : io/devdeck/plugin/DeckPlugin {
public static final field $stable I
public fun <init> ()V
public fun <init> (ZLjava/util/List;ZLjava/lang/String;)V
public synthetic fun <init> (ZLjava/util/List;ZLjava/lang/String;)V
public synthetic fun <init> (ZLjava/util/List;ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (ZLjava/util/List;ZLjava/lang/String;Z)V
public synthetic fun <init> (ZLjava/util/List;ZLjava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun Content (Landroidx/compose/runtime/Composer;I)V
public fun getId ()Ljava/lang/String;
public fun getSection ()Ljava/lang/String;
Expand Down Expand Up @@ -1084,8 +1089,10 @@ public final class io/devdeck/plugin/FeatureFlagsPlugin : io/devdeck/plugin/Deck
public final class io/devdeck/plugin/InfoPlugin : io/devdeck/plugin/DeckPlugin {
public static final field $stable I
public fun <init> ()V
public fun <init> (ZZZLjava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;)V
public synthetic fun <init> (ZZZLjava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;)V
public synthetic fun <init> (ZZZLjava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (ZZZLjava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;ZZ)V
public synthetic fun <init> (ZZZLjava/lang/String;Lkotlin/jvm/functions/Function0;Ljava/lang/String;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun Content (Landroidx/compose/runtime/Composer;I)V
public fun getId ()Ljava/lang/String;
public fun getSection ()Ljava/lang/String;
Expand Down
3 changes: 3 additions & 0 deletions devdeck/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# DevDeck needs no keep rules: it doesn't use reflection on its own classes, and its
# components (file provider, screen recording service) are kept through the manifest.
#
# Don't add a blanket -keep for io.devdeck: App info detects R8 by checking whether
# io.devdeck.device.R8Probe was renamed or stripped.
Loading
Loading