Skip to content

Commit 179863e

Browse files
committed
APL-VH-Android: July 2023 Release of APL 2023.2 compliant Viewhost Code
1 parent d2ad4bc commit 179863e

File tree

8,445 files changed

+190742
-1525401
lines changed

Some content is hidden

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

8,445 files changed

+190742
-1525401
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 2023.1
1+
# Alexa Presentation Language (APL) ViewHost Android version 2023.2
22

33
APLViewHostAndroid is a view host implementation for the Android Platform. It consists of
44
a thin JNI layer that interacts with APL Core Engine for component inflation and command

apl/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ add_library(
4343
src/main/cpp/jniaudioplayer.cpp
4444
src/main/cpp/jniaudioplayerfactory.cpp
4545
src/main/cpp/jnicontent.cpp
46+
src/main/cpp/jnidocumentcontext.cpp
47+
src/main/cpp/jnidocumentmanager.cpp
4648
src/main/cpp/jnidocumentsession.cpp
49+
src/main/cpp/jniembeddeddocumentrequest.cpp
4750
src/main/cpp/jniextensionclient.cpp
4851
src/main/cpp/jniextensioncommand.cpp
4952
src/main/cpp/jniextensioncomponent.cpp
@@ -66,6 +69,7 @@ add_library(
6669
src/main/cpp/jnitextmeasurecallback.cpp
6770
src/main/cpp/jnishadowblur.cpp
6871
src/main/cpp/jninoisefilter.cpp
72+
src/main/cpp/jnitext.cpp
6973
)
7074

7175
# Specifies a path to native header files.

apl/build.gradle

Lines changed: 24 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,173 +1,42 @@
11
/*
2-
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3-
* SPDX-License-Identifier: Apache-2.0
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
43
*/
54

6-
apply plugin: 'com.android.library'
7-
apply plugin: 'jacoco'
8-
apply plugin: 'maven-publish'
5+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
96

10-
jacoco {
11-
toolVersion = '0.8.2'
12-
}
13-
14-
tasks.withType(Test) {
15-
jacoco.includeNoLocationClasses = true
16-
jacoco.excludes = ['jdk.internal.*']
17-
}
7+
def version = "1.10.0";
188

19-
task jacocoTestReport(type: JacocoReport, dependsOn: ['test']) {
20-
def mainSrc = "$project.projectDir/src/main/java"
9+
project.buildDir = "build"
2110

22-
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', '**/AutoValue_*.*']
23-
def debugTree = fileTree(dir: "$project.buildDir/intermediates/javac/release/", excludes: fileFilter)
11+
buildscript {
2412

25-
sourceDirectories.from(files([mainSrc]))
26-
classDirectories.from(files(debugTree))
27-
28-
executionData.from(fileTree(dir: "$buildDir", includes: [
29-
"jacoco/*.exec"
30-
]))
31-
reports {
32-
xml.enabled = true
33-
html.enabled = true
13+
repositories {
14+
google()
15+
jcenter()
3416
}
35-
}
36-
37-
ext {
38-
aplAndroidCmakeArgs = " -DCMAKE_VERBOSE_MAKEFILE=ON"
39-
aplCoreDirCmakeArg = "-DAPL_CORE_DIR=" + projectDir + "/../../APLCoreEngine"
40-
if (project.hasProperty('aplCoreDir')) {
41-
aplCoreDirCmakeArg = "-DAPL_CORE_DIR=" + aplCoreDir
42-
} else {
17+
dependencies {
18+
classpath 'com.android.tools.build:gradle:4.1.2'
19+
classpath 'org.jacoco:org.jacoco.core:0.8.2'
4320

21+
// NOTE: Do not place your application dependencies here; they belong
22+
// in the individual module build.gradle files
4423
}
4524
}
4625

47-
android {
48-
compileSdkVersion 28
49-
ndkVersion "23.0.7599858"
50-
buildToolsVersion "30.0.2"
51-
defaultConfig {
52-
minSdkVersion 22
53-
targetSdkVersion 28
54-
versionCode 1
55-
versionName "1.0"
56-
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
57-
testInstrumentationRunnerArguments clearPackageData: 'true'
58-
renderscriptTargetApi 22
59-
externalNativeBuild {
60-
cmake {
61-
// Sets optional flags for the C++ compiler.
62-
// Enables RTTI (RunTime Type Information) support and C++ exceptions.
63-
cppFlags "-std=c++11", "-frtti", "-fexceptions", "-DBUILD_ALEXAEXTENSIONS=On", "-DALEXAEXTENSIONS=1"
64-
// Build the APL Core JNI library (excludes all other targets)
65-
targets "apl", "apl-jni"
66-
// Enable APL Core JNI build, and be verbose.
67-
arguments aplCoreDirCmakeArg, aplAndroidCmakeArgs
68-
}
69-
}
70-
ndk {
71-
// Specifies the ABI configurations for the native libraries
72-
// that Gradle will build and package with the APK.
73-
abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a'
74-
}
75-
}
76-
compileOptions {
77-
sourceCompatibility JavaVersion.VERSION_1_8
78-
targetCompatibility JavaVersion.VERSION_1_8
79-
}
80-
buildTypes {
81-
release {
82-
// minifyEnabled true
83-
// proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
84-
buildConfigField("long", "VERSION_CODE", "${defaultConfig.versionCode}")
85-
buildConfigField("String","VERSION_NAME","\"${defaultConfig.versionName}-core\"")
86-
}
87-
debug {
88-
testCoverageEnabled true
89-
debuggable true
90-
aplAndroidCmakeArgs += " -DDEBUG_MEMORY_USE=ON"
91-
buildConfigField("long", "VERSION_CODE", "${defaultConfig.versionCode}")
92-
buildConfigField("String","VERSION_NAME","\"${defaultConfig.versionName}-core\"")
93-
}
94-
}
95-
// Temporary fix until alpha10 - "More than one file was found with OS independent path 'META-INF/proguard/androidx-annotations.pro"
96-
packagingOptions {
97-
exclude 'META-INF/proguard/androidx-annotations.pro'
98-
}
99-
100-
externalNativeBuild {
101-
cmake {
102-
version "3.10.2"
103-
104-
// Tells Gradle to find the root CMake APL build script. path is relative to
105-
// the directory containing the module's build.gradle file. Gradle requires this
106-
// build script to designate a CMake project as a build dependency and
107-
// pull native sources into the Android project.
108-
path "CMakeLists.txt"
109-
}
110-
}
111-
lintOptions {
112-
// If set to true, turns off analysis progress reporting by lint.
113-
quiet false
114-
// if set to true (default), stops the build if errors are found.
115-
abortOnError true
116-
// if true, only report errors.
117-
ignoreWarnings false
118-
// flag code marked for unreleasable
119-
fatal 'StopShip'
120-
disable 'LongLogTag'
26+
allprojects {
27+
if (System.getenv("MAINLINE_BUILD")) {
28+
project.version = "${version}-SNAPSHOT"
29+
} else {
30+
project.version = "${version}." + (System.getenv("CODEBUILD_BUILD_NUMBER") ?: "0")
12131
}
32+
project.group = "APLViewhostAndroid"
12233

123-
testOptions {
124-
animationsDisabled true
125-
126-
unitTests {
127-
includeAndroidResources = true
128-
}
34+
repositories {
35+
google()
36+
jcenter()
12937
}
13038
}
13139

132-
dependencies {
133-
implementation fileTree(include: ['*.jar'], dir: 'libs')
134-
implementation 'androidx.annotation:annotation:1.0.0'
135-
implementation 'androidx.core:core:1.0.0'
136-
implementation 'androidx.appcompat:appcompat:1.0.0'
137-
implementation 'com.github.bumptech.glide:glide:4.6.1'
138-
implementation project(':common')
139-
implementation (project(':discovery')) { transitive = false }
140-
testImplementation 'junit:junit:4.12'
141-
testImplementation 'org.robolectric:robolectric:4.2'
142-
testImplementation 'org.robolectric:shadows-httpclient:4.2'
143-
testImplementation 'androidx.test:core:1.1.0'
144-
testImplementation 'org.mockito:mockito-core:2.25.0'
145-
androidTestImplementation 'org.mockito:mockito-core:2.25.0'
146-
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
147-
androidTestImplementation 'androidx.annotation:annotation:1.0.0'
148-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
149-
androidTestImplementation 'androidx.test:runner:1.1.1'
150-
androidTestImplementation 'androidx.test:rules:1.1.1'
151-
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
152-
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
153-
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.25.0'
154-
androidTestImplementation project(":commonTest")
155-
androidTestUtil 'androidx.test:orchestrator:1.1.1'
156-
api "com.google.auto.value:auto-value-annotations:1.7"
157-
api 'com.google.guava:guava:27.0.1-jre'
158-
annotationProcessor "com.google.auto.value:auto-value:1.7"
159-
}
160-
161-
project.afterEvaluate {
162-
// Dump configuration settings
163-
println "APL CMake Args: " + aplAndroidCmakeArgs
164-
println "APL Core Directory: " + aplCoreDirCmakeArg
165-
println "Android SDK Directory: " + android.sdkDirectory.path
166-
println "Android NDK Directory: " + android.ndkDirectory.path
167-
168-
// enforce native tools build runs first for enum dependencies
169-
compileDebugJavaWithJavac.dependsOn externalNativeBuildDebug
170-
compileReleaseJavaWithJavac.dependsOn externalNativeBuildRelease
171-
172-
tasks.test.finalizedBy(jacocoTestReport)
40+
task clean(type: Delete) {
41+
delete rootProject.buildDir
17342
}

apl/src/androidTest/java/com/amazon/apl/android/component/TextViewTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
import org.junit.Before;
2727
import org.junit.Test;
2828

29+
import java.text.ParseException;
30+
import java.text.SimpleDateFormat;
31+
import java.time.LocalDateTime;
32+
import java.time.format.DateTimeFormatter;
33+
import java.util.Calendar;
34+
import java.util.Date;
2935
import java.util.HashMap;
3036
import java.util.Map;
3137

@@ -410,4 +416,64 @@ public void testView_resizingText_RTL_anyWidth_usesNewLayout() {
410416

411417
assertNotEquals(actualLayout, originalLayout);
412418
}
419+
420+
@Test
421+
public void testView_updateTime_localTime_format() throws ParseException {
422+
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
423+
String beforeDateString = formatter.format(new Date());
424+
Date before = formatter.parse(beforeDateString);
425+
onView(withId(com.amazon.apl.android.test.R.id.apl))
426+
.perform(inflate("\"text\": \"${Time.format('DD-MM-YYYY hh:mm:ss', localTime)}\"", CHILD_LAYOUT_PROPERTIES))
427+
.check(hasRootContext());
428+
429+
Layout originalLayout = getTestView().getLayout();
430+
Date after = new Date();
431+
Date actualDate = formatter.parse(originalLayout.getText().toString());
432+
assertTrue(before.getTime() <= actualDate.getTime());
433+
assertTrue(actualDate.getTime() <= after.getTime());
434+
}
435+
436+
@Test
437+
public void testView_updateTime_utcTime() {
438+
Date before = new Date();
439+
onView(withId(com.amazon.apl.android.test.R.id.apl))
440+
.perform(inflate("\"text\": \"${utcTime}\"", CHILD_LAYOUT_PROPERTIES))
441+
.check(hasRootContext());
442+
Date after = new Date();
443+
444+
Layout originalLayout = getTestView().getLayout();
445+
assertTrue(before.getTime() <= Long.parseLong(originalLayout.getText().toString()));
446+
assertTrue(Long.parseLong(originalLayout.getText().toString()) <= after.getTime());
447+
}
448+
449+
@Test
450+
public void testView_updateTime_localTime() {
451+
Date before = new Date();
452+
onView(withId(com.amazon.apl.android.test.R.id.apl))
453+
.perform(inflate("\"text\": \"${localTime}\"", CHILD_LAYOUT_PROPERTIES))
454+
.check(hasRootContext());
455+
456+
Layout originalLayout = getTestView().getLayout();
457+
Date after = new Date();
458+
Date actualDate = new Date(Long.parseLong(originalLayout.getText().toString()));
459+
Calendar now = Calendar.getInstance();
460+
long offset = now.get(Calendar.ZONE_OFFSET) + now.get(Calendar.DST_OFFSET);
461+
assertTrue(before.getTime() <= actualDate.getTime() - offset);
462+
assertTrue(actualDate.getTime() - offset <= after.getTime());
463+
}
464+
465+
@Test
466+
public void testView_updateTime_elapsedTime() {
467+
onView(withId(com.amazon.apl.android.test.R.id.apl))
468+
.perform(inflate("\"text\": \"${elapsedTime}\"", CHILD_LAYOUT_PROPERTIES))
469+
.check(hasRootContext());
470+
471+
Layout originalLayout = getTestView().getLayout();
472+
assertEquals("0", originalLayout.getText().toString());
473+
onView(isRoot())
474+
.perform(waitFor(500));
475+
Layout newLayout = getTestView().getLayout();
476+
assertTrue( 400 <= Integer.parseInt(newLayout.getText().toString()));
477+
assertTrue(Integer.parseInt(newLayout.getText().toString()) <= 600);
478+
}
413479
}

apl/src/androidTest/java/com/amazon/apl/android/component/VideoViewTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ private void verifySettersAndGetters(final FakeMediaPlayer fakeMediaPlayer,
270270
fakeMediaPlayer.seek(currentSeekPosition);
271271
assertEquals(currentTrackIndex, fakeMediaPlayer.getCurrentTrackIndex());
272272
assertEquals(currentSeekPosition, fakeMediaPlayer.getCurrentSeekPosition());
273+
274+
fakeMediaPlayer.seekTo(currentSeekPosition);
275+
assertEquals(currentSeekPosition, fakeMediaPlayer.getCurrentSeekPosition());
273276
}
274277

275278
private void verifyAddMediaStateListener(FakeMediaPlayer fakeMediaPlayer,
@@ -370,6 +373,11 @@ public void seek(int msec) {
370373
mCurrentSeekPosition = msec;
371374
}
372375

376+
@Override
377+
public void seekTo(int msec) {
378+
seek(msec);
379+
}
380+
373381
@Override
374382
public void rewind() {
375383

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*/
4+
5+
#ifndef APLVIEWHOSTANDROID_JNIDOCUMENTCONTEXT_H
6+
#define APLVIEWHOSTANDROID_JNIDOCUMENTCONTEXT_H
7+
#include "apl/apl.h"
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
namespace apl {
14+
namespace jni {
15+
/**
16+
* Given a core DocumentContext, return a unique identifier for the underlying object.
17+
* @param document The DocumentContext
18+
* @return an opaque identifier or 0 if the provided document context is null
19+
*/
20+
jlong getDocumentContextId(const DocumentContextPtr document);
21+
22+
} // namespace jni
23+
} // namespace apl
24+
25+
#ifdef __cplusplus
26+
}
27+
#endif
28+
#endif //APLVIEWHOSTANDROID_JNIDOCUMENTCONTEXT_H
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*/
4+
5+
#ifndef APLVIEWHOSTANDROID_JNIDOCUMENTMANAGER_H
6+
#define APLVIEWHOSTANDROID_JNIDOCUMENTMANAGER_H
7+
#include "apl/apl.h"
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
/**
13+
* Initialize and cache java class and method handles for callback to the rendering layer.
14+
*/
15+
jboolean documentmanager_OnLoad(JavaVM *vm, void *reserved __attribute__((__unused__)));
16+
17+
/**
18+
* Release the class and method cache.
19+
*/
20+
void documentmanager_OnUnload(JavaVM *vm, void *reserved __attribute__((__unused__)));
21+
22+
namespace apl {
23+
namespace jni {
24+
class AndroidDocumentManager : public DocumentManager {
25+
public:
26+
AndroidDocumentManager() {}
27+
28+
virtual ~AndroidDocumentManager();
29+
void setInstance(jobject instance);
30+
31+
void request(const std::weak_ptr<EmbedRequest>& request,
32+
EmbedRequestSuccessCallback success,
33+
EmbedRequestFailureCallback error) override;
34+
private:
35+
jweak mInstance;
36+
};
37+
} // namespace jni
38+
} // namespace apl
39+
40+
#ifdef __cplusplus
41+
}
42+
#endif
43+
#endif //APLVIEWHOSTANDROID_JNIDOCUMENTMANAGER_H

0 commit comments

Comments
 (0)