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
31 changes: 27 additions & 4 deletions examples/tv-casting-app/android/App/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ plugins {
id 'com.android.application'
}

// Read the size optimization flag passed from the build system.
// When true, enables R8 shrinking and allows .so stripping in debug builds.
def optimizeApkSize = project.hasProperty('optimizeApkSize') && project.property('optimizeApkSize') == 'true'

android {
// Namespace (required for AGP 8.0+)
namespace 'com.chip.casting'
Expand All @@ -28,13 +32,22 @@ android {

buildTypes {
release {
minifyEnabled false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

debug {
packagingOptions{
doNotStrip "**/*.so"
if (optimizeApkSize) {
// Size-optimized debug: enable R8 to remove unused Java/Kotlin code
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// Do NOT add doNotStrip — let the build system strip .so files
} else {
// Normal debug: keep everything for debugging
minifyEnabled false
packagingOptions {
doNotStrip "**/*.so"
}
}
}
}
Expand Down Expand Up @@ -73,7 +86,17 @@ android {
}

dependencies {
implementation fileTree(dir: "libs", include: ["*.jar","*.so"])
if (optimizeApkSize) {
// When R8 is enabled, the compat source files (src/compat/jni) are compiled
// by Gradle AND also present in TvCastingApp.jar from the GN build.
// Exclude the JAR to avoid "defined multiple times" R8 errors; the Gradle-
// compiled classes are identical and sufficient.
implementation fileTree(dir: "libs", include: ["*.so"])
implementation fileTree(dir: "libs", include: ["*.jar"], exclude: ["TvCastingApp.jar"])
compileOnly files("libs/TvCastingApp.jar")
} else {
implementation fileTree(dir: "libs", include: ["*.jar","*.so"])
}
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
Expand Down
95 changes: 75 additions & 20 deletions examples/tv-casting-app/android/App/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -1,21 +1,76 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# ProGuard / R8 rules for the Matter TV Casting App
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# The native library (libTvCastingApp.so) calls back into Java via JNI.
# R8 cannot trace these references, so we must explicitly keep all classes
# and members that are accessed from native code.

# ============================================================================
# 1. App-level JNI classes (called from libTvCastingApp.so via FindClass/GetMethodID)
# ============================================================================

# Casting core classes — constructed and field-accessed from native code
-keep class com.matter.casting.core.** { *; }

# Casting support classes — fields read/written from native code
-keep class com.matter.casting.support.** { *; }

# Compat JNI layer — legacy API surface also called from native code
-keep class com.chip.casting.** { *; }

# ============================================================================
# 2. CHIP SDK classes (from dependency JARs, called via JNI from libTvCastingApp.so
# and the CHIP platform native code)
# ============================================================================

# Platform layer — JNI bridge between native CHIP stack and Android
-keep class chip.platform.** { *; }

# App server — CHIP application server Java bindings
-keep class chip.appserver.** { *; }

# Interaction model — cluster/command/attribute Java bindings
-keep class chip.clusterinfo.** { *; }

# Device controller — used by the interaction model layer
-keep class chip.devicecontroller.** { *; }

# Setup payload (QR code / manual pairing code parsing)
-keep class chip.setuppayload.** { *; }

# TLV codec — used by interaction model serialization
-keep class chip.tlv.** { *; }

# ============================================================================
# 3. Keep native method declarations so the JNI linkage works
# ============================================================================
-keepclasseswithmembernames class * {
native <methods>;
}

# ============================================================================
# 4. Keep the Android Application subclass (entry point)
# ============================================================================
-keep class com.matter.casting.ChipTvCastingApplication { *; }

# ============================================================================
# 5. Standard Android keep rules
# ============================================================================

# Keep Parcelable implementations
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}

# Keep enum values (used by reflection in some Android APIs)
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}

# ============================================================================
# 6. Suppress warnings for annotations not present at runtime
# ============================================================================

# javax.annotation.* annotations (Nonnull, Nullable) are compile-time only
# and not included in the Android runtime. They are safe to ignore.
-dontwarn javax.annotation.**
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ using namespace chip;

#define JNI_METHOD(RETURN, METHOD_NAME) extern "C" JNIEXPORT RETURN JNICALL Java_com_matter_casting_core_CastingApp_##METHOD_NAME

jint JNI_OnLoad(JavaVM * jvm, void * reserved)
jint JNIEXPORT JNI_OnLoad(JavaVM * jvm, void * reserved)
{
return AndroidAppServerJNI_OnLoad(jvm, reserved);
}

void JNI_OnUnload(JavaVM * jvm, void * reserved)
void JNIEXPORT JNI_OnUnload(JavaVM * jvm, void * reserved)
{
return AndroidAppServerJNI_OnUnload(jvm, reserved);
}
Expand Down
22 changes: 21 additions & 1 deletion examples/tv-casting-app/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import("//build_overrides/chip.gni")
import("${build_root}/config/android_abi.gni")
import("${chip_root}/build/chip/java/rules.gni")
import("${chip_root}/build/chip/tools.gni")
import("${chip_root}/examples/tv-casting-app/tv-casting-common/tv-casting-common.gni")

shared_library("jni") {
output_name = "libTvCastingApp"
Expand Down Expand Up @@ -58,6 +59,21 @@ shared_library("jni") {
output_dir = "${root_out_dir}/lib/jni/${android_abi}"

ldflags = [ "-Wl,--gc-sections" ]

if (optimize_apk_size) {
# Identical Code Folding: merge functions with identical machine code.
ldflags += [ "-Wl,--icf=safe" ]

# Thin LTO at link time (must match cflags).
ldflags += [ "-flto=thin" ]

# Static libc++: fold libc++ into libTvCastingApp.so so we don't ship
# the 7.5 MB libc++_shared.so as a separate file. The linker's
# --gc-sections + LTO will strip unused libc++ code.
if (use_static_libcxx) {
ldflags += [ "-static-libstdc++" ]
}
}
}

android_library("java") {
Expand All @@ -73,9 +89,13 @@ android_library("java") {

data_deps = [
":jni",
"${chip_root}/build/chip/java:shared_cpplib",
]

# When using static libc++, we don't need the shared libc++ library.
if (!use_static_libcxx) {
data_deps += [ "${chip_root}/build/chip/java:shared_cpplib" ]
}

sources = [
"App/app/src/compat/jni/com/chip/casting/AppParameters.java",
"App/app/src/compat/jni/com/chip/casting/CommissioningCallbacks.java",
Expand Down
26 changes: 17 additions & 9 deletions examples/tv-casting-app/android/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ chip_project_config_include_dirs =
[ "${chip_root}/examples/tv-casting-app/tv-casting-common/include" ]
chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ]

chip_build_libshell = true
import("${chip_root}/examples/tv-casting-app/tv-casting-common/tv-casting-common.gni")

chip_enable_additional_data_advertising = true

Expand All @@ -36,12 +36,20 @@ chip_max_discovered_ip_addresses = 20

enable_rtti = true

# Build Configuration: Fast Development Mode
optimize_for_size = false # -O2 (speed) vs -Os (size) - faster compilation
symbol_level =
0 # -g0 (no debug symbols) - fastest compilation, no stack traces

#is_debug = false # Release mode: faster execution, removes safety checks
if (optimize_apk_size) {
# Size-optimized build: smaller APK, fewer debug features
# NOTE: matter_enable_tracing_support and matter_trace_config are
# passed as GN build args from android.py to properly override
# their declare_args() defaults in tracing_args.gni.
chip_build_libshell = false
optimize_for_size = true # -Os (size) instead of -O2 (speed)
symbol_level = 0 # -g0: no debug symbols
} else {
# Default development build: full debug features, fast compilation
chip_build_libshell = true
optimize_for_size = false # -O2 (speed) - faster compilation
symbol_level = 0 # -g0 (no debug symbols) - fastest compilation
}

# Symbol Level Options:
# 0 = No debug symbols (-g0): Fastest build, smallest binary, no crash stack traces
Expand All @@ -53,5 +61,5 @@ symbol_level =
# false = Release mode: Removes assert() checks, bounds checking, extra logging
# true = Debug mode: Keeps all safety checks, slower execution but catches bugs
# Default: true (if not specified, GN defaults to debug mode)

# For Release Builds: Use optimize_for_size=true, symbol_level=1
# Note: In size-optimized builds, is_debug=false is set by android.py as a
# GN build arg to properly override the declare_args() default.
5 changes: 5 additions & 0 deletions examples/tv-casting-app/darwin/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ chip_project_config_include_dirs = [
"${chip_root}/examples/tv-casting-app/tv-casting-common",
]

import("${chip_root}/examples/tv-casting-app/tv-casting-common/tv-casting-common.gni")

# Use slim cluster-objects: only the ~36 clusters a casting client needs.
chip_cluster_objects_source_override = "${chip_root}/examples/tv-casting-app/tv-casting-common/casting-cluster-objects.cpp"

chip_build_libshell = true

# Example Credentials like ExampleDAC.h/cpp are not required for the tv-casting-app
Expand Down
5 changes: 5 additions & 0 deletions examples/tv-casting-app/linux/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ chip_project_config_include_dirs =
[ "${chip_root}/examples/tv-casting-app/tv-casting-common/include" ]
chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ]

import("${chip_root}/examples/tv-casting-app/tv-casting-common/tv-casting-common.gni")

# Use slim cluster-objects: only the ~36 clusters a casting client needs.
chip_cluster_objects_source_override = "${chip_root}/examples/tv-casting-app/tv-casting-common/casting-cluster-objects.cpp"

chip_build_libshell = true

chip_enable_additional_data_advertising = true
Expand Down
Loading
Loading