How to Enable Picture-in-Picture (PiP) Mode in SmartTube: A Complete Developer Guide

SmartTube enables Picture-in-Picture mode through a combination of manifest declarations in AndroidManifest.xml, runtime checks via Helpers.isPictureInPictureSupported(), and the enterPipMode() method in PlaybackActivity, which triggers when users select PiP as the background playback mode.

Picture-in-Picture (PiP) allows users to continue watching videos in a floating window while navigating other applications on their Android TV or mobile device. According to the yuliskov/SmartTube source code, implementing this feature requires coordinating Android system capabilities with the app's playback engine and activity lifecycle. The implementation spans manifest declarations, runtime permission checks, and UI state management across multiple components.

Manifest Configuration for PiP Support

Before SmartTube can enter PiP mode, the Android system requires explicit declaration in the app manifest. This informs the OS that the playback activity supports floating window behavior.

In smarttubetv/src/main/AndroidManifest.xml, the PlaybackActivity declaration includes the crucial android:supportsPictureInPicture attribute:

<activity
    android:name=".tv.ui.playback.PlaybackActivity"
    android:label="@string/app_name"
    android:supportsPictureInPicture="true"
    android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|smallestScreenSize"
    ... />

Setting android:supportsPictureInPicture="true" is mandatory for Android N (API 24) and above. Without this flag, calls to enterPictureInPictureMode() will fail silently or throw exceptions.

Runtime Capability Verification

SmartTube defensively checks device capabilities before attempting to enter PiP mode. The helper method Helpers.isPictureInPictureSupported() performs runtime validation to ensure the device runs Android N (API 24) or higher and that the activity properly declares PiP support in its manifest.

This check guards against crashes on older devices or incompatible Android TV implementations. The method returns true only when the system can safely enter PiP mode, allowing the app to fall back to standard background audio playback on unsupported devices.

Implementing the PiP Entry Point

The core logic for entering PiP mode resides in PlaybackActivity.java. The enterPipMode() method orchestrates the transition, handling version-specific API differences and user preference checks.

Located in smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/playback/PlaybackActivity.java, this method demonstrates the complete flow:

@TargetApi(24)
private void enterPipMode() {
    if (Helpers.isPictureInPictureSupported(this) && wannaEnterToPip()) {
        try {
            if (Build.VERSION.SDK_INT >= 26) {
                PictureInPictureParams.Builder params = new PictureInPictureParams.Builder();
                // Optional: set aspect ratio, custom actions, or source rect hint
                enterPictureInPictureMode(params.build());
            } else {
                // Legacy API for Android N (API 24-25)
                enterPictureInPictureMode();
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }
}

Key implementation details include:

  • The wannaEnterToPip() guard: This internal check verifies that PlayerData has BACKGROUND_MODE_PIP selected and confirms the activity is not already in PiP mode.
  • Version branching: Android O (API 26) introduced PictureInPictureParams for customizing the PiP window aspect ratio and actions. Older versions use the parameterless enterPictureInPictureMode() method.
  • Exception safety: The try-catch block prevents crashes if the system denies PiP entry due to memory constraints or policy restrictions.

Configuring Background Playback Mode

PiP activation depends on the user's background playback preference stored in PlayerData. The app must explicitly set the background mode to PlayerEngine.BACKGROUND_MODE_PIP to allow the wannaEnterToPip() check to succeed.

To programmatically enable PiP as the default background behavior:

PlayerData playerData = PlayerData.instance(context);
playerData.setBackgroundMode(PlayerEngine.BACKGROUND_MODE_PIP);

This setting persists across sessions and controls whether the app enters PiP mode automatically when the user presses the home button or triggers the back action during playback. Users can also toggle this manually via Settings → Background playback → PiP in the SmartTube interface.

Handling PiP Lifecycle Events

When the system transitions to or from PiP mode, SmartTube must adapt its UI components. The PlaybackActivity overrides onPictureInPictureModeChanged() to propagate state changes to the playback fragment:

@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    super.onPictureInPictureModeChanged(isInPictureInPictureMode);
    if (mPlaybackFragment != null) {
        mPlaybackFragment.onPIPChanged(isInPictureInPictureMode);
    }
}

The fragment's onPIPChanged() method then adjusts the visibility of controls, hiding full-screen overlays and displaying minimal playback controls suitable for the smaller window:

@Override
public void onPIPChanged(boolean isInPip) {
    if (isInPip) {
        hideFullScreenOverlay();
        showMinimalControls();
    } else {
        showFullScreenOverlay();
    }
}

Key Source Files for PiP Implementation

Understanding the complete PiP architecture requires familiarity with these specific files in the yuliskov/SmartTube repository:

Summary

Enabling Picture-in-Picture in SmartTube requires coordination across the Android manifest, runtime system checks, and user preference management:

  • Declare android:supportsPictureInPicture="true" in AndroidManifest.xml for the playback activity.
  • Verify device compatibility using Helpers.isPictureInPictureSupported() before attempting entry.
  • Set the background mode to PlayerEngine.BACKGROUND_MODE_PIP via PlayerData to permit PiP activation.
  • Implement enterPipMode() in PlaybackActivity with version-specific logic for Android O+ versus older versions.
  • Handle lifecycle changes through onPictureInPictureModeChanged() to adapt the UI for floating window constraints.

Frequently Asked Questions

What is the minimum Android version required for PiP in SmartTube?

SmartTube requires Android N (API 24) or higher for Picture-in-Picture functionality. The Helpers.isPictureInPictureSupported() method explicitly checks for this API level, and the enterPipMode() method uses the @TargetApi(24) annotation to prevent compilation errors on older SDKs.

Why doesn't PiP activate when I press the home button?

PiP only activates when the background playback mode is explicitly set to BACKGROUND_MODE_PIP in PlayerData. If the mode is set to background audio only (BACKGROUND_MODE_SOUND) or disabled, the wannaEnterToPip() check returns false. Verify the setting in the app's preferences or programmatically set it using playerData.setBackgroundMode(PlayerEngine.BACKGROUND_MODE_PIP).

How do I customize the PiP window aspect ratio on Android O and above?

For Android O (API 26) and higher, modify the PictureInPictureParams.Builder in enterPipMode() before calling enterPictureInPictureMode(). You can set the aspect ratio using params.setAspectRatio(new Rational(width, height)) and add custom actions using params.setActions(actionsList).

Where does SmartTube handle UI changes when entering PiP mode?

UI adaptations occur in the onPIPChanged() method of the playback fragment, triggered via PlaybackActivity.onPictureInPictureModeChanged(). This pattern ensures that full-screen overlays hide and minimal controls appear immediately when the activity enters PiP mode, and reverse when returning to full screen.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →