Skip to content

Commit e737deb

Browse files
committed
APL-VH-Android: December 2024 Release of APL 2024.3 compliant Viewhost Code
1 parent 5580994 commit e737deb

File tree

225 files changed

+9567
-1898
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

225 files changed

+9567
-1898
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Alexa Presentation Language (APL) ViewHost Android version 2024.2
1+
# Alexa Presentation Language (APL) ViewHost Android version 2024.3
22

33
The APL Android target contains 3 modules
44

alexaextjni/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ if (NOT ANDROID)
4747
set_target_properties(alexaext
4848
PROPERTIES
4949
IMPORTED_LOCATION
50-
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/extensions/alexaext/libalexaext.a"
51-
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/alexaext/include"
50+
"${APL_HOST_BINARIES}/libalexaext.a"
51+
INTERFACE_INCLUDE_DIRECTORIES "${ALEXAEXT_INCLUDE}"
5252
)
5353

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

6060
target_link_libraries(alexaextjni rapidjson alexaext)

alexaextjni/build.gradle

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.apache.tools.ant.taskdefs.condition.Os
77

88
apply plugin: 'com.android.library'
9+
apply plugin: com.amazon.apl.android.APLPlugin
910

1011
ext {
1112
cmakeProjectPath = projectDir.absolutePath
@@ -69,27 +70,14 @@ android {
6970
dependencies {
7071
implementation fileTree(dir: 'libs', include: ['*.jar'])
7172
implementation project(":common")
72-
implementation project(':coreengine')
73-
}
74-
75-
task buildHostJNI(type: com.amazon.apl.android.CMakeTask) {
76-
cmakeArgs aplAndroidCmakeArgs
77-
makeTargets "alexaextjni"
78-
dependsOn ':coreengine:buildHostJNI'
73+
implementation 'com.amazon.apl.android:coreengine:latest.integration'
7974
}
8075

8176
project.afterEvaluate {
8277
// Dump configuration settings
8378
println "APL CMake Args: " + aplAndroidCmakeArgs
8479
println "Android SDK Directory: " + android.sdkDirectory.path
8580
println "Android NDK Directory: " + android.ndkDirectory.path
86-
87-
// We need to make sure the host jni library is built before any debug or release unit testing.
88-
tasks.preDebugUnitTestBuild.dependsOn(buildHostJNI)
89-
tasks.preReleaseUnitTestBuild.dependsOn(buildHostJNI)
90-
tasks.buildHostJNI.dependsOn(':coreengine:buildHostJNI')
91-
tasks.buildHostJNI.dependsOn(':common:buildHostJNI')
9281
}
9382

94-
tasks.build.dependsOn(buildHostJNI)
9583

alexaextjni/src/main/cpp/jniextensionexecutor.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ namespace alexaext {
5959
env->DeleteGlobalRef(EXTENSIONEXECUTOR_CLASS);
6060
}
6161

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

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

95+
/**
96+
* Called by Java ExtensionExecutor class to execute any queued tasks.
97+
*/
8198
void executePending() {
8299
std::lock_guard<std::recursive_mutex> guard(mTasksMutex);
83100
while (!mPendingTasks.empty()) {
@@ -124,4 +141,4 @@ namespace alexaext {
124141
}
125142
#endif
126143
} //namespace jni
127-
} //namespace apl
144+
} //namespace apl

apl/CMakeLists.txt

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ add_library(
8484
src/main/cpp/jnistyledtext.cpp
8585
src/main/cpp/jnishadowblur.cpp
8686
src/main/cpp/jninoisefilter.cpp
87+
src/main/cpp/jnipackagemanager.cpp
8788
${SCENEGRAPH_SOURCES}
8889
src/main/cpp/jnitext.cpp
8990
)
@@ -101,32 +102,25 @@ if (NOT ANDROID)
101102

102103
add_library(aplcore STATIC IMPORTED)
103104

104-
if (ENABLE_SCENEGRAPH)
105-
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/aplsgconfig/include")
106-
else()
107-
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/aplconfig/include")
108-
endif()
109-
list(APPEND APL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/apl/include")
110-
111105
set_target_properties(aplcore
112106
PROPERTIES
113107
IMPORTED_LOCATION
114-
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/aplcore/libapl.a"
115-
INTERFACE_INCLUDE_DIRECTORIES "${APL_INCLUDE_DIR}"
108+
"${APL_HOST_BINARIES}/libapl.a"
109+
INTERFACE_INCLUDE_DIRECTORIES "${APL_INCLUDE}"
116110
)
117111

118112
add_library(alexaext STATIC IMPORTED)
119113
set_target_properties(alexaext
120114
PROPERTIES
121115
IMPORTED_LOCATION
122-
"${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/.cxx/cmake/debug/host/_deps/aplcore-build/extensions/alexaext/libalexaext.a"
123-
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/alexaext/include"
116+
"${APL_HOST_BINARIES}/libalexaext.a"
117+
INTERFACE_INCLUDE_DIRECTORIES "${ALEXAEXT_INCLUDE}"
124118
)
125119

126120
add_library(rapidjson INTERFACE)
127121
target_include_directories(rapidjson INTERFACE
128122
# When we're building against RapidJSON, just use the include directory we discovered above
129-
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../coreengine/src/main/cpp/rapidjson/include>
123+
$<BUILD_INTERFACE:${RAPIDJSON_INCLUDE}>
130124
)
131125
if(INCLUDE_ALEXAEXT)
132126
add_library(alexaextjni STATIC IMPORTED)

apl/build.gradle

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6+
7+
import com.amazon.apl.android.EnumGenerator
68
import org.apache.tools.ant.taskdefs.condition.Os
79

810
apply plugin: 'com.android.library'
911
apply plugin: 'jacoco'
1012
apply plugin: 'maven-publish'
13+
apply plugin: com.amazon.apl.android.APLPlugin
1114

1215
jacoco {
1316
toolVersion = '0.8.8'
@@ -46,14 +49,18 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['test']) {
4649
"jacoco/*.exec",
4750
"outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
4851
]))
52+
reports {
53+
xml.required = true
54+
html.required = true
55+
}
4956
}
5057

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

7582
// Exclude Android and Androidx Support libraries
76-
'**/android/**',
7783
'**/androidx/**',
7884
'**/com/android/**',
7985
'**com/google/**'
@@ -86,8 +92,12 @@ task jacocoAutomationTestReport(type: JacocoReport) {
8692
classDirectories.from(files([debugFilter]))
8793
executionData.from(fileTree(dir: "$buildDir", includes: [
8894
"jacoco/*.exec",
89-
"outputs/coverage/coverage-data.exec"
95+
"outputs/coverage.exec"
9096
]))
97+
reports {
98+
xml.required = true
99+
html.required = true
100+
}
91101
}
92102

93103
ext {
@@ -128,7 +138,7 @@ android {
128138
main {
129139
// Changes the directory for Java sources. The default directory is
130140
// 'src/main/java'.
131-
java.srcDirs = ['src/main/java', '../coreengine/src/main/java']
141+
java.srcDirs = ['src/main/java']
132142
}
133143
}
134144
publishing {
@@ -244,7 +254,7 @@ dependencies {
244254
implementation 'androidx.appcompat:appcompat:1.2.0'
245255
implementation 'com.github.bumptech.glide:glide:4.11.0'
246256
implementation 'org.java-websocket:Java-WebSocket:1.5.2'
247-
compileOnly project(':coreengine')
257+
compileOnly 'com.amazon.apl.android:coreengine:latest.integration'
248258
compileOnly project(':alexaextjni')
249259
implementation project(':common')
250260
implementation(project(':discovery')) { transitive = false }
@@ -264,8 +274,8 @@ dependencies {
264274
androidTestImplementation 'androidx.test:runner:1.4.0'
265275
androidTestImplementation 'androidx.test:rules:1.4.0'
266276
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
267-
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
268-
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.25.0'
277+
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:2.28.3'
278+
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.28.3'
269279
androidTestImplementation project(":commonTest")
270280
androidTestImplementation 'com.squareup.leakcanary:leakcanary-android-instrumentation:2.9.1'
271281
androidTestImplementation 'com.squareup.leakcanary:leakcanary-object-watcher-android:2.9.1'
@@ -276,12 +286,6 @@ dependencies {
276286
annotationProcessor 'org.projectlombok:lombok:1.18.30'
277287
}
278288

279-
task buildHostJNI(type: com.amazon.apl.android.CMakeTask) {
280-
cmakeArgs aplAndroidCmakeArgs
281-
makeTargets 'apl-jni'
282-
dependsOn ':coreengine:buildHostJNI',':alexaextjni:buildHostJNI'
283-
}
284-
285289
tasks.whenTaskAdded { theTask ->
286290
if (theTask.name.startsWith("test")) {
287291
theTask.outputs.upToDateWhen { false }
@@ -294,14 +298,6 @@ project.afterEvaluate {
294298
println "Android SDK Directory: " + android.sdkDirectory.path
295299
println "Android NDK Directory: " + android.ndkDirectory.path
296300

297-
// We need to make sure the host jni library is built before any debug or release unit testing.
298-
tasks.preDebugUnitTestBuild.dependsOn(buildHostJNI)
299-
tasks.preReleaseUnitTestBuild.dependsOn(buildHostJNI)
300-
tasks.buildHostJNI.dependsOn(':coreengine:buildHostJNI')
301-
tasks.buildHostJNI.dependsOn(':alexaextjni:buildHostJNI')
302-
tasks.buildHostJNI.dependsOn(':discovery:buildHostJNI')
303-
tasks.buildHostJNI.dependsOn(':common:buildHostJNI')
304-
305301
tasks.test.finalizedBy(jacocoTestReport)
306302
}
307303

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

348344
copy {
349-
from 'build/reports'
345+
from 'build/reports/jacoco/jacocoTestReport'
350346
into '../build/apl/reports/'
351347
rename 'jacocoTestReport.xml', 'coverage.xml'
352348
}
@@ -378,3 +374,80 @@ tasks.whenTaskAdded {
378374
task.enabled = false
379375
}
380376
}
377+
378+
task generateEnums(type: EnumGenerator) {
379+
importedEnums "AnimationQuality",
380+
"AudioPlayerEventType",
381+
"AudioTrack",
382+
"BlendMode",
383+
"ComponentType",
384+
"ContainerDirection",
385+
"DimensionType",
386+
"Display",
387+
"DisplayState",
388+
"EventAudioTrack",
389+
"EventControlMediaCommand",
390+
"EventDirection",
391+
"EventHighlightMode",
392+
"EventMediaType",
393+
"EventProperty",
394+
"EventReason",
395+
"EventScrollAlign",
396+
"EventType",
397+
"ExtensionComponentResourceState",
398+
"FilterProperty",
399+
"FilterType",
400+
"FlexboxAlign",
401+
"FlexboxJustifyContent",
402+
"FocusDirection",
403+
"FontStyle",
404+
"GradientProperty",
405+
"GradientSpreadMethod",
406+
"GradientType",
407+
"GradientUnits",
408+
"GraphicElementType",
409+
"GraphicFilterProperty",
410+
"GraphicFilterType",
411+
"GraphicLayoutDirection",
412+
"GraphicLineCap",
413+
"GraphicLineJoin",
414+
"GraphicPropertyKey",
415+
"GraphicScale",
416+
"GraphicScale",
417+
"GraphicTextAnchor",
418+
"ImageAlign",
419+
"ImageCount",
420+
"ImageScale",
421+
"KeyHandlerType",
422+
"KeyboardType",
423+
"LayoutDirection",
424+
"MediaPlayerEventType",
425+
"Navigation",
426+
"NoiseFilterKind",
427+
"PointerEventType",
428+
"PointerType",
429+
"Position",
430+
"PropertyKey",
431+
"Role",
432+
"RootProperty",
433+
"ScreenMode",
434+
"ScreenShape",
435+
"ScrollDirection",
436+
"Snap",
437+
"SpeechMarkType",
438+
"SpanAttributeName",
439+
"SpanType",
440+
"SubmitKeyType",
441+
"TextAlign",
442+
"TextAlignVertical",
443+
"TextTrackType",
444+
"TokenType",
445+
"TrackState",
446+
"UpdateType",
447+
"VectorGraphicAlign",
448+
"VectorGraphicScale",
449+
"VideoScale",
450+
"ViewportMode"
451+
}
452+
453+
tasks.preBuild.dependsOn(generateEnums)

apl/src/androidTest/java/com/amazon/apl/android/APLTestContext.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.amazon.apl.android.providers.AbstractMediaPlayerProvider;
1717
import com.amazon.apl.android.scaling.ViewportMetrics;
1818
import com.amazon.apl.android.utils.APLTrace;
19+
import com.amazon.apl.android.utils.FluidityIncidentReporter;
1920
import com.amazon.apl.enums.RootProperty;
2021
import com.amazon.apl.enums.ScreenShape;
2122
import com.amazon.apl.enums.ViewportMode;
@@ -72,6 +73,8 @@ public class APLTestContext {
7273

7374
private IMetricsRecorder mMetricsRecorder = mock(IMetricsRecorder.class);
7475

76+
private FluidityIncidentReporter mFluidityIncidentReporter = mock(FluidityIncidentReporter.class);
77+
7578
public Content buildContent() {
7679
if (mContent == null) {
7780
try {
@@ -180,7 +183,7 @@ public RootContext buildRootContext() {
180183
buildRootContextDependencies();
181184

182185
if (mRootContext == null)
183-
mRootContext = RootContext.create(mMetrics, mContent, mRootConfig, mAplOptions, mPresenter, mMetricsRecorder);
186+
mRootContext = RootContext.create(mMetrics, mContent, mRootConfig, mAplOptions, mPresenter, mMetricsRecorder, mFluidityIncidentReporter);
184187

185188
return mRootContext;
186189
}

0 commit comments

Comments
 (0)