Skip to content

[MOB-11764] Fix JWT refresh timer race condition on app background #929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ freeline_project_description.json
# MacOS generated files
.DS_Store

# AI assistant configuration
.claude/

# [Maven] ========================
target/
pom.xml.tag
Expand Down
7 changes: 7 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# CLAUDE.md

🤖 **AI Agent Instructions**

Please read the `agent/AGENT_README.md` file for comprehensive project information, development workflow, and testing procedures.

All the information you need to work on this Iterable Android SDK project is documented there.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ message and web push notifications to your customers.

This SDK helps you integrate your Android apps with Iterable.

## For AI Agents & Developers

Looking for quick build and test scripts? Check out the [`agent/`](agent/) folder for:
- **Build script**: `./agent/build.sh` (fast incremental builds)
- **Test script**: `./agent/test.sh` (comprehensive test runner)
- **Documentation**: [`agent/AGENT_README.md`](agent/AGENT_README.md) (detailed guide)

## Supported Android versions

Iterable's Android SDK supports Android versions 5.0 (API level 21) and higher.
Expand Down
196 changes: 196 additions & 0 deletions agent/AGENT_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
# AGENT README - Iterable Android SDK

## Project Overview
This is the **Iterable Android SDK** for Android app integration. The SDK provides:
- Push notification handling (FCM/GCM)
- In-app messaging
- Embedded messaging
- Event tracking
- User management
- Mobile Inbox functionality

## Key Architecture
- **Core SDK**: `iterableapi/` - Main SDK implementation
- **UI Components**: `iterableapi-ui/` - In-app and inbox UI components
- **Sample App**: `app/` - Example integration
- **Sample Apps**: `sample-apps/` - Additional example integrations

## Development Workflow

### 🔨 Building the SDK
```bash
# Fast incremental build (default)
./agent/build.sh

# Clean build (slower, but ensures clean state)
./agent/build.sh --clean
```
- Validates compilation for Android
- Uses incremental builds by default for speed
- Shows build errors with context
- Requires Android SDK and Java/Kotlin

### Listing All Available Tests
```bash
# List all available test suites
./agent/test.sh --list
```

### 🧪 Running Tests
```bash
# Run all tests
./agent/test.sh

# Run specific test class
./agent/test.sh IterableApiTest

# Run specific test method (dot notation - recommended)
./agent/test.sh "IterableKeychainTest.testSaveAndGetEmail"

# Run any specific test with full path
./agent/test.sh ":iterableapi:testDebugUnitTest --tests com.iterable.iterableapi.IterableApiTest.testSetEmail"
```
- Executes unit tests with accurate pass/fail reporting
- Returns exit code 0 for success, 1 for failures
- Shows detailed test counts and failure information
- `--list` shows all test classes with test counts

## Project Structure
```
iterable-android-sdk/
├── iterableapi/ # Main SDK module
│ ├── src/main/java/ # Main SDK source
│ │ └── com/iterable/iterableapi/
│ │ ├── IterableApi.java # Main SDK interface
│ │ ├── IterableConfig.java # Configuration
│ │ ├── IterableInAppManager.java # In-app messaging
│ │ ├── IterableEmbeddedManager.java # Embedded messaging
│ │ └── util/ # Utility classes
│ ├── src/test/java/ # Unit tests
│ └── src/androidTest/java/ # Instrumentation tests
├── iterableapi-ui/ # UI components module
│ ├── src/main/java/ # UI source
│ │ └── com/iterable/iterableapi/ui/
│ │ ├── inbox/ # Mobile Inbox components
│ │ └── embedded/ # Embedded message views
├── app/ # Sample application
├── sample-apps/ # Additional examples
│ └── inbox-customization/ # Inbox customization examples
└── tools/ # Build and development tools
```

## Key Classes
- **IterableApi**: Main SDK interface (singleton)
- **IterableConfig**: Configuration management
- **IterableInAppManager**: In-app message handling
- **IterableEmbeddedManager**: Embedded message handling
- **IterableApiClient**: Network communication
- **IterableAuthManager**: Authentication management

## Common Tasks

### Adding New Features
1. Build first: `./agent/build.sh` (fast incremental)
2. Implement in `iterableapi/src/main/java/com/iterable/iterableapi/`
3. Add tests in `iterableapi/src/test/java/`
4. Verify: `./agent/test.sh` (all tests) or `./agent/test.sh IterableKeychainTest` (specific class)
5. For final verification: `./agent/build.sh --clean` (ensures clean state)

### Debugging Build Issues
- Build script shows compilation errors with file paths
- Check Gradle dependencies in `build.gradle` files
- Verify Android SDK and build tools are installed
- Check for Kotlin/Java compatibility issues

### Test Failures
- Test script shows specific failures with line numbers and detailed error messages
- Run failing tests individually: `./agent/test.sh "TestClass.testMethod"`
- Mock classes available in test directories
- Update method signatures when refactoring APIs

## Requirements
- **Android SDK**: API level 21+ (Android 5.0+)
- **Java**: JDK 17 or newer
- **Gradle**: 8.0+ (managed by wrapper)
- **Android Build Tools**: Latest stable version

## Quick Start for AI Agents
1. Run `./agent/build.sh` to verify project builds (fast incremental)
2. Run `./agent/test.sh` to check test health (or `./agent/test.sh TestClass` for specific class)
3. Make changes to source files
4. Re-run both scripts to validate (incremental builds are fast)
5. Debug failing tests: `./agent/test.sh "IterableKeychainTest.testSaveAndGetEmail"`
6. Before committing: `./agent/build.sh --clean` to ensure clean state
7. Commit when both pass ✅

## Test Filtering Examples
```bash
# Debug specific failing tests
./agent/test.sh "IterableKeychainTest.testSaveAndGetEmail"

# Run a problematic test class
./agent/test.sh IterableInAppManagerTest

# Check auth-related tests
./agent/test.sh IterableAuthManagerTest
```

## AI Agent Memory System

### 🧠 Update Instructions for AI Agents
**IMPORTANT**: When you discover something useful while working on this codebase, update this README to help future AI agents. Add learnings to the sections below.

### 📍 Code Location Map
- **Main API**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java` (public interface)
- **Auth Logic**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableAuthManager.java` (auth manager)
- **API Client**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableApiClient.java` (network calls)
- **In-App Messages**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java`
- **Embedded Messages**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableEmbeddedManager.java`
- **Models**: `iterableapi/src/main/java/com/iterable/iterableapi/` (CommerceItem, IterableInAppMessage, etc.)
- **UI Components**: `iterableapi-ui/src/main/java/com/iterable/iterableapi/ui/`
- **Constants**: `iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java`

### 🛠️ Common Task Recipes

**Add New API Endpoint:**
1. Add endpoint constant to `IterableConstants.java`
2. Add method to `IterableApiClient.java`
3. Create request method in `IterableRequestTask.java`
4. Add public method to `IterableApi.java`

**Modify Auth Logic:**
- Main logic: `IterableAuthManager.java`
- Token storage: `IterableKeychain.java`
- Auth failures: Handle in API client response processing

**Add New Model:**
- Create in `iterableapi/src/main/java/com/iterable/iterableapi/YourModel.java`
- Implement `Parcelable` if it needs to be passed between components
- Add JSON serialization if it needs to be sent over network

### 🐛 Common Failure Solutions

**"Test X failed"** → Check test file in `iterableapi/src/test/java/` - often method signature mismatches after refactoring

**"Build failed: package not found"** → Check import statements and ensure all dependencies are in `build.gradle`

**"Auth token issues"** → Check `IterableAuthManager.java` and ensure JWT format is correct in tests

**"Network request fails"** → Check endpoint in `IterableConstants.java` and request creation in `IterableRequestTask.java`

**"UI component not found"** → Check if `iterableapi-ui` module is included in your dependencies

### 📱 Android-Specific Notes
- SDK supports Android API level 21+ (Android 5.0+)
- Uses AndroidX libraries for compatibility
- Push notifications require FCM setup
- In-app messages use WebView for rendering
- Embedded messages support custom UI components
- Mobile Inbox requires `iterableapi-ui` dependency

## Notes
- Always test builds after refactoring
- Method signature changes require test file updates
- Gradle sync may be needed after dependency changes
- Sample apps demonstrate SDK usage patterns
- UI components are in separate module for optional inclusion
81 changes: 81 additions & 0 deletions agent/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash

# This script is to be used by LLMs and AI agents to build the Iterable Android SDK.
# It uses Gradle to build the project and shows errors in a clean format.
# It also checks if the build is successful and exits with the correct status.
#
# Usage: ./agent/build.sh [--clean]
# --clean: Force a clean build (slower, but ensures clean state)

# Note: Not using set -e because we need to handle build failures gracefully

echo "Building Iterable Android SDK..."

# Create a temporary file for the build output
TEMP_OUTPUT=$(mktemp)

# Function to clean up temp file on exit
cleanup() {
rm -f "$TEMP_OUTPUT"
}
trap cleanup EXIT

# Check if we have Android SDK
if [ -z "$ANDROID_HOME" ] && [ -z "$ANDROID_SDK_ROOT" ]; then
echo "⚠️ Warning: ANDROID_HOME or ANDROID_SDK_ROOT not set. Build may fail if Android SDK is not in PATH."
fi

# Parse command line arguments for clean build option
CLEAN_BUILD=false
if [[ "$1" == "--clean" ]]; then
CLEAN_BUILD=true
echo "🧹 Clean build requested"
fi

# Run the build and capture all output
if [ "$CLEAN_BUILD" = true ]; then
echo "🔨 Clean building all modules..."
./gradlew clean build -x test --no-daemon --console=plain > "$TEMP_OUTPUT" 2>&1
BUILD_STATUS=$?
else
echo "🔨 Building all modules (incremental)..."
./gradlew build -x test --no-daemon --console=plain > "$TEMP_OUTPUT" 2>&1
BUILD_STATUS=$?
fi

# Show appropriate output based on build result
if [ $BUILD_STATUS -eq 0 ]; then
echo "✅ Iterable Android SDK build succeeded!"
echo ""
echo "📦 Built modules:"
echo " • iterableapi (core SDK)"
echo " • iterableapi-ui (UI components)"
echo " • app (sample app)"
else
echo "❌ Iterable Android SDK build failed with status $BUILD_STATUS"
echo ""
echo "🔍 Build errors:"

# Extract and show compilation errors with file paths and line numbers
grep -E "\.java:[0-9]+: error:|\.kt:[0-9]+: error:|error:|Error:|FAILURE:|Failed|Exception:" "$TEMP_OUTPUT" | head -20

echo ""
echo "⚠️ Build warnings:"
grep -E "\.java:[0-9]+: warning:|\.kt:[0-9]+: warning:|warning:|Warning:" "$TEMP_OUTPUT" | head -10

# If no specific errors found, show the failure section
if ! grep -q -E "\.java:[0-9]+: error:|\.kt:[0-9]+: error:|error:" "$TEMP_OUTPUT"; then
echo ""
echo "📋 Build failure details:"
grep -A 10 -B 2 "FAILURE\|BUILD FAILED" "$TEMP_OUTPUT" | head -15
fi

echo ""
echo "💡 Common solutions:"
echo " • Check Java version (JDK 17+ required)"
echo " • Verify ANDROID_HOME is set correctly"
echo " • Run './gradlew --stop' to kill daemon processes"
echo " • Check dependencies in build.gradle files"
fi

exit $BUILD_STATUS
Loading
Loading