Skip to content

Commit

Permalink
APL-VH-Android: December 2024 Release of APL 2024.3 compliant Viewhos…
Browse files Browse the repository at this point in the history
…t Code
  • Loading branch information
middendc committed Jan 3, 2025
1 parent 5580994 commit e737deb
Show file tree
Hide file tree
Showing 225 changed files with 9,567 additions and 1,898 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Alexa Presentation Language (APL) ViewHost Android version 2024.2
# Alexa Presentation Language (APL) ViewHost Android version 2024.3

The APL Android target contains 3 modules

Expand Down
6 changes: 3 additions & 3 deletions alexaextjni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ if (NOT ANDROID)
set_target_properties(alexaext
PROPERTIES
IMPORTED_LOCATION
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/extensions/alexaext/libalexaext.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/alexaext/include"
"${APL_HOST_BINARIES}/libalexaext.a"
INTERFACE_INCLUDE_DIRECTORIES "${ALEXAEXT_INCLUDE}"
)

add_library(rapidjson INTERFACE)
target_include_directories(rapidjson INTERFACE
# When we're building against RapidJSON, just use the include directory we discovered above
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/rapidjson/include>
$<BUILD_INTERFACE:${RAPIDJSON_INCLUDE}>
)

target_link_libraries(alexaextjni rapidjson alexaext)
Expand Down
16 changes: 2 additions & 14 deletions alexaextjni/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.library'
apply plugin: com.amazon.apl.android.APLPlugin

ext {
cmakeProjectPath = projectDir.absolutePath
Expand Down Expand Up @@ -69,27 +70,14 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":common")
implementation project(':coreengine')
}

task buildHostJNI(type: com.amazon.apl.android.CMakeTask) {
cmakeArgs aplAndroidCmakeArgs
makeTargets "alexaextjni"
dependsOn ':coreengine:buildHostJNI'
implementation 'com.amazon.apl.android:coreengine:latest.integration'
}

project.afterEvaluate {
// Dump configuration settings
println "APL CMake Args: " + aplAndroidCmakeArgs
println "Android SDK Directory: " + android.sdkDirectory.path
println "Android NDK Directory: " + android.ndkDirectory.path

// We need to make sure the host jni library is built before any debug or release unit testing.
tasks.preDebugUnitTestBuild.dependsOn(buildHostJNI)
tasks.preReleaseUnitTestBuild.dependsOn(buildHostJNI)
tasks.buildHostJNI.dependsOn(':coreengine:buildHostJNI')
tasks.buildHostJNI.dependsOn(':common:buildHostJNI')
}

tasks.build.dependsOn(buildHostJNI)

19 changes: 18 additions & 1 deletion alexaextjni/src/main/cpp/jniextensionexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ namespace alexaext {
env->DeleteGlobalRef(EXTENSIONEXECUTOR_CLASS);
}

/**
* Implements the extension executor contract, acting as a bridge between the C++ extension
* framework and the Java ExtensionExecutor class. The Java ExtensionExecutor class ensures
* that tasks are executed on the appropriate (core) thread.
*
* This class buffers tasks in in a local queue (mPendingTasks) and notifies the Java class
* whenever a new task was added via onTaskAdded(). When the Java ExtensionExecutor instance
* is ready to execute the tasks, it calls executePending() on the appropriate thread.
*/
class ExtensionExecutor : public alexaext::Executor {
public:
ExtensionExecutor(jweak instance) : mWeakInstance(instance) {}
Expand All @@ -71,13 +80,21 @@ namespace alexaext {
env->DeleteWeakGlobalRef(mWeakInstance);
}

/**
* Called by the extension framework when a new task needs to be executed. It adds the
* task to the executor's queue, notifies Java ExtensionExecutor via onTaskAdded() and
* returns immediately (does not block to actually perform the task).
*/
bool enqueueTask(Task task) override {
std::lock_guard<std::recursive_mutex> guard(mTasksMutex);
mPendingTasks.push(std::move(task));
onTaskAdded();
return true;
}

/**
* Called by Java ExtensionExecutor class to execute any queued tasks.
*/
void executePending() {
std::lock_guard<std::recursive_mutex> guard(mTasksMutex);
while (!mPendingTasks.empty()) {
Expand Down Expand Up @@ -124,4 +141,4 @@ namespace alexaext {
}
#endif
} //namespace jni
} //namespace apl
} //namespace apl
18 changes: 6 additions & 12 deletions apl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ add_library(
src/main/cpp/jnistyledtext.cpp
src/main/cpp/jnishadowblur.cpp
src/main/cpp/jninoisefilter.cpp
src/main/cpp/jnipackagemanager.cpp
${SCENEGRAPH_SOURCES}
src/main/cpp/jnitext.cpp
)
Expand All @@ -101,32 +102,25 @@ if (NOT ANDROID)

add_library(aplcore STATIC IMPORTED)

if (ENABLE_SCENEGRAPH)
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/aplsgconfig/include")
else()
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/aplconfig/include")
endif()
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/apl/include")

set_target_properties(aplcore
PROPERTIES
IMPORTED_LOCATION
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/aplcore/libapl.a"
INTERFACE_INCLUDE_DIRECTORIES "${APL_INCLUDE_DIR}"
"${APL_HOST_BINARIES}/libapl.a"
INTERFACE_INCLUDE_DIRECTORIES "${APL_INCLUDE}"
)

add_library(alexaext STATIC IMPORTED)
set_target_properties(alexaext
PROPERTIES
IMPORTED_LOCATION
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/extensions/alexaext/libalexaext.a"
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/alexaext/include"
"${APL_HOST_BINARIES}/libalexaext.a"
INTERFACE_INCLUDE_DIRECTORIES "${ALEXAEXT_INCLUDE}"
)

add_library(rapidjson INTERFACE)
target_include_directories(rapidjson INTERFACE
# When we're building against RapidJSON, just use the include directory we discovered above
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/rapidjson/include>
$<BUILD_INTERFACE:${RAPIDJSON_INCLUDE}>
)
if(INCLUDE_ALEXAEXT)
add_library(alexaextjni STATIC IMPORTED)
Expand Down
117 changes: 95 additions & 22 deletions apl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/


import com.amazon.apl.android.EnumGenerator
import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.library'
apply plugin: 'jacoco'
apply plugin: 'maven-publish'
apply plugin: com.amazon.apl.android.APLPlugin

jacoco {
toolVersion = '0.8.8'
Expand Down Expand Up @@ -46,14 +49,18 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['test']) {
"jacoco/*.exec",
"outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
]))
reports {
xml.required = true
html.required = true
}
}

/**
* Task to generate coverage report for automationapp after
* APLComplianceTests have completed.
*/
task jacocoAutomationTestReport(type: JacocoReport) {
def emulator_proc = "adb pull /storage/emulated/0/coverage-data.exec $buildDir/outputs/coverage/coverage-data.exec".execute()
def emulator_proc = "adb pull /data/user/0/com.amazon.apl.automation/cache/coverage.exec $buildDir/outputs/coverage.exec".execute()
doFirst {
emulator_proc.waitForProcessOutput(System.out, System.err)
}
Expand All @@ -73,7 +80,6 @@ task jacocoAutomationTestReport(type: JacocoReport) {
'**/*Test*.*',

// Exclude Android and Androidx Support libraries
'**/android/**',
'**/androidx/**',
'**/com/android/**',
'**com/google/**'
Expand All @@ -86,8 +92,12 @@ task jacocoAutomationTestReport(type: JacocoReport) {
classDirectories.from(files([debugFilter]))
executionData.from(fileTree(dir: "$buildDir", includes: [
"jacoco/*.exec",
"outputs/coverage/coverage-data.exec"
"outputs/coverage.exec"
]))
reports {
xml.required = true
html.required = true
}
}

ext {
Expand Down Expand Up @@ -128,7 +138,7 @@ android {
main {
// Changes the directory for Java sources. The default directory is
// 'src/main/java'.
java.srcDirs = ['src/main/java', '../coreengine/src/main/java']
java.srcDirs = ['src/main/java']
}
}
publishing {
Expand Down Expand Up @@ -244,7 +254,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'org.java-websocket:Java-WebSocket:1.5.2'
compileOnly project(':coreengine')
compileOnly 'com.amazon.apl.android:coreengine:latest.integration'
compileOnly project(':alexaextjni')
implementation project(':common')
implementation(project(':discovery')) { transitive = false }
Expand All @@ -264,8 +274,8 @@ dependencies {
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.25.0'
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.28.3'
androidTestImplementation project(":commonTest")
androidTestImplementation 'com.squareup.leakcanary:leakcanary-android-instrumentation:2.9.1'
androidTestImplementation 'com.squareup.leakcanary:leakcanary-object-watcher-android:2.9.1'
Expand All @@ -276,12 +286,6 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

task buildHostJNI(type: com.amazon.apl.android.CMakeTask) {
cmakeArgs aplAndroidCmakeArgs
makeTargets 'apl-jni'
dependsOn ':coreengine:buildHostJNI',':alexaextjni:buildHostJNI'
}

tasks.whenTaskAdded { theTask ->
if (theTask.name.startsWith("test")) {
theTask.outputs.upToDateWhen { false }
Expand All @@ -294,14 +298,6 @@ project.afterEvaluate {
println "Android SDK Directory: " + android.sdkDirectory.path
println "Android NDK Directory: " + android.ndkDirectory.path

// We need to make sure the host jni library is built before any debug or release unit testing.
tasks.preDebugUnitTestBuild.dependsOn(buildHostJNI)
tasks.preReleaseUnitTestBuild.dependsOn(buildHostJNI)
tasks.buildHostJNI.dependsOn(':coreengine:buildHostJNI')
tasks.buildHostJNI.dependsOn(':alexaextjni:buildHostJNI')
tasks.buildHostJNI.dependsOn(':discovery:buildHostJNI')
tasks.buildHostJNI.dependsOn(':common:buildHostJNI')

tasks.test.finalizedBy(jacocoTestReport)
}

Expand Down Expand Up @@ -346,7 +342,7 @@ task release(dependsOn: ['build', 'publish']) {
}

copy {
from 'build/reports'
from 'build/reports/jacoco/jacocoTestReport'
into '../build/apl/reports/'
rename 'jacocoTestReport.xml', 'coverage.xml'
}
Expand Down Expand Up @@ -378,3 +374,80 @@ tasks.whenTaskAdded {
task.enabled = false
}
}

task generateEnums(type: EnumGenerator) {
importedEnums "AnimationQuality",
"AudioPlayerEventType",
"AudioTrack",
"BlendMode",
"ComponentType",
"ContainerDirection",
"DimensionType",
"Display",
"DisplayState",
"EventAudioTrack",
"EventControlMediaCommand",
"EventDirection",
"EventHighlightMode",
"EventMediaType",
"EventProperty",
"EventReason",
"EventScrollAlign",
"EventType",
"ExtensionComponentResourceState",
"FilterProperty",
"FilterType",
"FlexboxAlign",
"FlexboxJustifyContent",
"FocusDirection",
"FontStyle",
"GradientProperty",
"GradientSpreadMethod",
"GradientType",
"GradientUnits",
"GraphicElementType",
"GraphicFilterProperty",
"GraphicFilterType",
"GraphicLayoutDirection",
"GraphicLineCap",
"GraphicLineJoin",
"GraphicPropertyKey",
"GraphicScale",
"GraphicScale",
"GraphicTextAnchor",
"ImageAlign",
"ImageCount",
"ImageScale",
"KeyHandlerType",
"KeyboardType",
"LayoutDirection",
"MediaPlayerEventType",
"Navigation",
"NoiseFilterKind",
"PointerEventType",
"PointerType",
"Position",
"PropertyKey",
"Role",
"RootProperty",
"ScreenMode",
"ScreenShape",
"ScrollDirection",
"Snap",
"SpeechMarkType",
"SpanAttributeName",
"SpanType",
"SubmitKeyType",
"TextAlign",
"TextAlignVertical",
"TextTrackType",
"TokenType",
"TrackState",
"UpdateType",
"VectorGraphicAlign",
"VectorGraphicScale",
"VideoScale",
"ViewportMode"
}

tasks.preBuild.dependsOn(generateEnums)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.amazon.apl.android.providers.AbstractMediaPlayerProvider;
import com.amazon.apl.android.scaling.ViewportMetrics;
import com.amazon.apl.android.utils.APLTrace;
import com.amazon.apl.android.utils.FluidityIncidentReporter;
import com.amazon.apl.enums.RootProperty;
import com.amazon.apl.enums.ScreenShape;
import com.amazon.apl.enums.ViewportMode;
Expand Down Expand Up @@ -72,6 +73,8 @@ public class APLTestContext {

private IMetricsRecorder mMetricsRecorder = mock(IMetricsRecorder.class);

private FluidityIncidentReporter mFluidityIncidentReporter = mock(FluidityIncidentReporter.class);

public Content buildContent() {
if (mContent == null) {
try {
Expand Down Expand Up @@ -180,7 +183,7 @@ public RootContext buildRootContext() {
buildRootContextDependencies();

if (mRootContext == null)
mRootContext = RootContext.create(mMetrics, mContent, mRootConfig, mAplOptions, mPresenter, mMetricsRecorder);
mRootContext = RootContext.create(mMetrics, mContent, mRootConfig, mAplOptions, mPresenter, mMetricsRecorder, mFluidityIncidentReporter);

return mRootContext;
}
Expand Down
Loading

0 comments on commit e737deb

Please sign in to comment.