# Partner API Demo Application

## Overview

The **Partner API Demo** is an Android application that demonstrates how to integrate with the **Remote Management API**. This Phase 1 release focuses on essential device management capabilities including HDMI CEC control, device information retrieval, network monitoring, and system control functions.

## Features

### Phase 1 API Integration

- **Service Connection Management** - Automatic binding to Remote Management API service with connection status monitoring
- **Essential API Methods** - Implementation of core device management APIs
- **Error Handling** - Robust error handling with user-friendly feedback
- **Async Operations** - All API calls run on background threads to prevent UI blocking
- **Detailed API Logging** - All API requests and responses are logged for debugging (excluding binary data)

### User Interface

- **Tabbed Interface** - Easy navigation between different API categories with equal-width tabs
- **Real-time Status** - Connection status and last API call display
- **Material Design** - Modern UI following Material Design guidelines
- **Keyboard Shortcuts** - Full keyboard navigation support for Signage Stick usage (see [Keyboard Shortcuts Guide](docs/KeyboardShotcuts.md))

## Phase 1 Features

### 1. **Device Information**

- Get Device Info including DSN (Device Serial Number)
- Get System Resources:
  - CPU/GPU Temperature (in Celsius)
  - Available Memory (in MB)
  - Available Storage (in MB)
  - CPU Usage Percentage

### 2. **System Control**

- Restart Device (Reboot) with custom delay
- Reset Device (Factory Reset) with external storage wipe option

### 3. **Display & HDMI CEC**

- HDMI Status monitoring (connected, CEC enabled, power status, audio info)
- HDMI CEC Display Control (On/Off)
- HDMI CEC Volume Control (Up/Down)

### 4. **Network Monitoring**

- Get Network Status
- WiFi Signal Strength (4 levels)
- Ethernet Connection Status
- IP Address and MAC Address information

## Phase 2 Features

### 5. **Screen Capture**

- Capture Screenshot in PNG, JPEG, or WEBP format
- Resolution scaling with configurable max width
- Chunked transfer for large images (>900KB) to stay within Binder limits
- Quality control (1-100)

### 6. **Screen Recording**

- Record screen to MP4 (1-20 seconds, configurable)
- Resolution options: native, 720p, 1080p
- Bitrate control (1-8 Mbps)
- Chunked video transfer with progress tracking
- Orientation-aware recording with rotation hint support

### 7. **OTA Update Management**

- Get update status for CMS and OS (version, progress, state)
- Check for CMS/OS updates with optional force apply
- Download progress tracking

### 8. **Screen Rotation**

- Get current screen rotation
- Set rotation: landscape (0°), portrait (90°), reverse_landscape (180°), reverse_portrait (270°)

### 9. **Timezone Management**

- Get available timezone list
- Set device timezone

### 10. **Additional Controls**

- Restart CMS application
- Wake screen (device + connected TV via CEC)
- Cache management (system cache, app cache, selective clearing)
- Mute toggle and volume level control

## Keyboard Navigation for Signage Sticks

This app is optimized for Signage Stick usage with comprehensive keyboard shortcuts:

### Quick Reference

- **Numbers 1-4**: Jump directly to tabs (Device Info, System Control, Display, Network)
- **Arrow Keys**: Navigate tabs (LEFT/RIGHT) and scroll content (UP/DOWN)
- **Letters A-I**: Trigger button actions on current tab
  - Tab 1: A=Device Info, B=System Info
  - Tab 2: C=Reboot, D=Factory Reset
  - Tab 3: E=HDMI Status, F=HDMI Power, G=Vol Down, H=Vol Up
  - Tab 4: I=Network Status

All buttons display their keyboard shortcut in brackets (e.g., "[A] Get device info").

**Full documentation:** [Keyboard Shortcuts Guide](docs/KeyboardShotcuts.md)

## Technical Architecture

```
PartnerAPIDemo/
├── api/
│   └── RemoteApiClient.java      # Main API client with connection management and logging
├── fragments/
│   ├── DeviceInfoFragment.java   # Device info and system resources
│   ├── SystemControlFragment.java # Reboot and factory reset
│   ├── DisplayFragment.java      # HDMI status and CEC controls
│   └── NetworkFragment.java      # Network status and WiFi strength
├── adapters/
│   └── TabAdapter.java          # ViewPager2 adapter for tabs
├── utils/
│   └── L.java                   # Logging utility
└── MainActivity.java            # Main activity with tab management
```

## Key Components

### RemoteApiClient

The heart of the integration, managing:

- Service binding lifecycle
- Connection state monitoring
- Thread-safe API calls
- Comprehensive API logging
- Automatic error handling

### API Response Models

All API responses use typed Parcelable models:

- `ApiResponse` - Generic response for control operations
- `DeviceInfo` - Device information response
- `SystemResources` - System resources with memory, storage, CPU, and temperature
- `NetworkStatus` - Network and WiFi status information
- `HdmiStatus` - HDMI CEC status and capabilities

## Building and Running

### Prerequisites

- Android Studio Arctic Fox or later
- Android SDK 28+ (Android 9.0)
- Gradle 7.0+
- Remote Management Agent installed on target device

### Build Steps

1. Clone the repository
2. Open project in Android Studio
3. Sync Gradle dependencies
4. Build the project: `./gradlew assembleDebug`

### Installation

```bash
adb install -r app/build/outputs/apk/debug/ads-partner-api-demo-*.apk
```

### Using on Signage Stick with scrcpy

```bash
# Connect to your Signage Stick via WiFi
scrcpy --tcpip=<device-ip>:5555

# Or via USB
scrcpy
```

Then use keyboard shortcuts for navigation (see [Keyboard Shortcuts Guide](docs/KeyboardShotcuts.md))

## Security Considerations

### Required Permissions

```xml
<uses-permission android:name="com.amazon.ads.ema.permission.DEVICE_MANAGEMENT" />
```

**Important:** The `DEVICE_MANAGEMENT` permission has been changed from a normal permission to a **dangerous permission** by Remote Management Agent. This means:

- The permission must be requested at runtime (Android 6.0+)
- Users will see a permission request dialog on first launch
- The app implements automatic permission handling in `MainActivity`

### Runtime Permission Flow

1. **First Launch**: App automatically checks permission status
2. **Permission Dialog**: If not granted, user sees explanation and permission request
3. **Grant**: App connects to Remote Management API and functions normally
4. **Deny**: User sees informative message; can grant permission later in app settings
5. **Permanent Deny**: If user selects "Don't ask again", app offers direct link to settings

### Permission Handling Implementation

The app implements comprehensive permission handling:

- Checks permission status on app launch
- Shows explanation dialog before requesting permission
- Handles all permission scenarios (grant, deny, permanent deny)
- Updates UI to reflect permission status
- Provides easy access to app settings for manual permission grant

### DEVICE_MANAGEMENT Permission for CMS Providers

**Important for CMS Provider Integration:**

The `DEVICE_MANAGEMENT` permission is **required** for all applications that need to integrate with the Remote Management API, including CMS Provider applications. This permission allows your application to:

- Monitor and control device status (reboot, factory reset)
- Access device information and system resources
- Configure network settings (WiFi, Ethernet, static IP)
- Control display settings (HDMI CEC, power, volume)
- Manage device screenshots and cache clearing

**CMS Provider Requirements:**

1. **Runtime Permission Request**: Your CMS Provider application must implement runtime permission requests for `DEVICE_MANAGEMENT` (dangerous permission level)
2. **Certificate Allowlist**: Your app's signing certificate must be registered in the Remote Management Agent's allowlist
3. **Graceful Handling**: Implement proper handling for permission denial scenarios to ensure user experience is not disrupted
4. **Permission Dialog**: Provide clear explanation to users about why this permission is needed before requesting it

**Best Practices for CMS Providers:**

- Request permission when the user first attempts to use a feature that requires it, rather than on app launch
- Provide detailed explanation of what device management capabilities your CMS will use
- Implement fallback behavior for scenarios where permission is denied
- Monitor permission status and prompt users to re-enable if they revoke it later

### Certificate Requirements

- App must be signed with a certificate registered in Remote Management Agent allowlist
- Contact your device administrator to register your app's certificate

## API Usage Examples

### Permission Check and Connection

The app automatically handles permission requests, but you can also check manually:

```java
// Check if permission is granted
if (ContextCompat.checkSelfPermission(this, 
        "com.amazon.ads.ema.permission.DEVICE_MANAGEMENT") 
        == PackageManager.PERMISSION_GRANTED) {
    // Permission granted, connect to API
    connectToRemoteManagementApi();
} else {
    // Request permission
    ActivityCompat.requestPermissions(this,
            new String[]{"com.amazon.ads.ema.permission.DEVICE_MANAGEMENT"},
            REQUEST_CODE);
}
```

### Connect to Remote Management API

```java
RemoteApiClient apiClient = new RemoteApiClient(context);
apiClient.connect(new RemoteApiClient.ConnectionListener() {
    @Override
    public void onConnected() {
        // API ready to use
    }
});
```

### Get Device Information with DSN

```java
DeviceInfo response = apiClient.getDeviceInfo();
if (response.code == 200 && response.data != null) {
    String dsn = response.data.dsn; // Device Serial Number
}
```

### Control HDMI Display Power

```java
// Turn display on
ApiResponse response = apiClient.setDisplayPower(true);

// Adjust volume
ApiResponse volResponse = apiClient.adjustVolume(true); // true for up, false for down
```

### Get System Resources

```java
SystemResources response = apiClient.getSystemResources();
if (response.code == 200 && response.data != null) {
    // Temperature in Celsius
    float cpuTemp = response.data.temperature.cpuCelsius;
    float gpuTemp = response.data.temperature.gpuCelsius;

    // Memory in MB
    long availableMemoryMB = response.data.memory.free / (1024 * 1024);

    // Storage in MB  
    long availableStorageMB = response.data.storage.free / (1024 * 1024);
}
```

## Debugging Tips

### Check Logs

```bash
adb logcat | grep "ADS_API_DEMO\|RemoteApiClient"
```

API calls are logged with the following format:

- Request: `[API Request] methodName() - param1: value1`
- Response: `[API Response] methodName() - Code: 200 Message: Success Data: {...}`

### Common Issues

1. **Connection Failed** - Ensure Remote Management Agent is installed and running
2. **Permission Denied (Runtime)** - Grant DEVICE_MANAGEMENT permission in app or system settings
3. **Permission Denied (Certificate)** - Verify app certificate is registered in Remote Management Agent allowlist
4. **API Call Failed** - Check device permissions and system state
5. **Permission Dialog Not Showing** - User may have selected "Don't ask again"; go to app settings to enable

## Best Practices

1. **Always check connection status** before making API calls
2. **Run API calls on background threads** to avoid ANR
3. **Handle all error cases** with appropriate user feedback
4. **Implement proper lifecycle management** for service connections
5. **Use the provided Response model** for consistent error handling

## License

This demo application is provided as-is for reference purposes. Contact your Amazon representative for licensing information.

---

**Version:** 1.2.0 (Phase 1,2 + Miracast + Network/Timezone)
**Last Updated:** 2026-05-10
**Compatibility:** Remote Management API v1.0+ (Miracast tab requires EMA Plus v1.8.6-302 or later)

## Changelog

### Version 1.2.0-12 (2026-05-10)

- **Miracast Tab** — New tab that demonstrates the 15 Miracast Sink APIs added in EMA Plus v1.8.6-302. Init → SetWfdInfo → EnableSink → WaitConnection → (cast from phone) → Disconnect → Destroy, driven end-to-end from the demo UI.
- **Fullscreen Sink Activity** — Added `MiracastSinkActivity` (`Theme.Black.NoTitleBar.Fullscreen`, `singleInstance`) hosting the SurfaceView that receives the video stream. The embedded `MiracastFragment` launches the activity rather than rendering in-tab — the WFD framework requires an overlay surface owned by a foreground fullscreen Activity.
- **WiFi Configuration** — Restored WiFi config UI in Network tab (SSID, security type, password, hidden network, priority) with `configureWifi()` API.
- **Timezone Tab** — Restored timezone get/set tab with searchable timezone list and `getTimezoneList()` / `setTimezone()` APIs.
- **RemoteApiClient** — 15 Miracast wrappers + `configureWifi()`, `getTimezoneList()`, `setTimezone()` methods.
- **AIDL Sync** — `IDeviceManagement.aidl` synced with EMA Plus v1.8.6-302 (15 miracast methods + `Surface` import).

### Version 1.0.8-11 (2026-04-02)

- **Screen Rotation UI** — Moved rotation controls above reboot/factory reset in System Control tab
- **Display Focus Fix** — Fixed focus jumping to bottom spacer after screenshot/recording completes
- **Screenshot Default** — Changed default format from PNG to JPEG
- **Portrait Screenshot** — Fixed screenshot not visible when device is in portrait orientation
- **Activity Rotation** — Added configChanges to prevent Activity destroy on screen rotation (TET-4415)

### Version 1.0.7-9 (2026-03-26)

- **OTA Update Tab** — Added OTA update status, check/force CMS and OS updates with progress tracking
- **Screen Recording** — Record screen (1-20s) with resolution/bitrate options, chunked video download
- **Timezone Tab** — Get/set timezone with searchable timezone list
- **Screen Rotation** — Get/set screen rotation in System Control tab
- **Restart CMS** — Added CMS app restart button in System Control tab
- **Chunked Screenshot** — Support large screenshot transfer via getScreenshotChunk/clearScreenshot

### Version 1.0.6-8 (2026-03-19)

- **WebP Screenshot** — Added WEBP format support with quality control
- **Scaled Screenshot** — Added max width parameter for resolution scaling
- **Screenshot Format Selector** — Dropdown to choose PNG/JPEG/WEBP

### Version 1.0.5-5 (2025-12-10)

- **Cache Management Feature**

  - Added cache clearing functionality with granular control
  - New system cache and app cache checkboxes for selective clearing
  - Keyboard shortcut [E] for quick cache clear access
  - Smart default behavior: clears demo app cache when no options selected
  - Custom visual selector for improved focus state visibility
- **System Control Improvements**

  - Removed "Wipe external storage" checkbox from UI
  - Factory reset now defaults to preserving external storage for safety
  - Updated confirmation dialogs with clearer messaging
- **Display Controls Enhancement**

  - Improved volume control functionality
  - Enhanced HDMI CEC control interface
  - Better visual feedback for button states
- **UI/UX Improvements**

  - Fixed button focus selector colors for better accessibility
  - Added descriptive text for cache management behavior
  - Improved keyboard navigation flow
- **Dependencies Update**

  - Updated OkHttp from 5.2.1 to 5.3.2

### Version 1.0.3-4 (2025-11-21)

- **Support Screenshot**
- **Enhanced UX**

### Version 1.0.2-3 (2025-11-20)

- **Permission Update**: Added runtime permission handling for `DEVICE_MANAGEMENT` permission
  - Remote Management Agent changed permission from normal to dangerous
  - Implemented automatic permission request flow on app launch
  - Added explanation dialogs and user-friendly error messages
  - Provides direct link to app settings if permission is permanently denied
- **Enhanced UX**: Improved connection status feedback based on permission state
