Skip to content

Commit

Permalink
APL-VH-Android: October 2022 Release of APL 2022.2 compliant Viewhost…
Browse files Browse the repository at this point in the history
… Code
  • Loading branch information
pranavsu1997 committed Oct 18, 2022
1 parent d9ea34d commit bcb4462
Show file tree
Hide file tree
Showing 3,551 changed files with 780,029 additions and 11,410 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
41 changes: 0 additions & 41 deletions Config

This file was deleted.

117 changes: 79 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,86 @@
# Alexa Presentation Language (APL) ViewHost Android
#README: APL Android

APLViewHostAndroid is a view host implementation for the Android Platform. It consists of
a thin JNI layer that interacts with APL Core Engine for component inflation and command
handling, and a native Android layout that maps APL Components to Android Views and ViewGroups.
The APL Android target contains 3 modules

The APL Android Viewhost consists of two elements:

- APL JNI adapter: 'libaplcore-jni.so' allows in process communication between the
- APL jni adapter: 'libaplcore-jni.so' allows in process communication between the
core C++ and Java Android layers.

- APL Android Library: .aar library exposing functionality of the APL spec, for use by Android
applications. This library embeds the Core and JNI libraries. The aar build targets SDK 28 and
supports a minimum SDK 22, it has 2 flavors:
- APL Android Library: .aar library exposing functionality of the APL spec, for use by Android
applications. This library embeds the core and jni libraries. The aar build targets SDK 28 and
supports a minimum SDK 22, it has 4 flavors:

- apl-core-release.aar - The release library
- apl-demo-release.aar - The release library with sample APL layout assets included.
- apl-core-debug.aar - The debug library
- apl-demo-debug.aar - The debug library with sample APL layout assets included.

- APL Android Sample App: A simple sample application that uses the demo library sample assets.

- apl-release.aar - The release library
- apl-debug.aar - The debug library
The Android library and Sample application are built with gradle. The Gradle cmake integration plugin
will build the the APL core library and core jni dependencies.

The Android library is built with Gradle. The Gradle CMake integration plugin
will build the APL Core Library and Core JNI dependencies.

### Prerequisites

Make sure you have installed:
- [Install NDK](https://developer.android.com/ndk/guides/#download-ndk) version 20
- Higher versions of NDK are not currently compatible with the current gradle plugin.
- [Install Android SDK](https://developer.android.com/studio/intro/update) version 28 or higher
- Install Ninja (Needed for APLCoreEngine when building from APLViewhostAndroid)
- Setup a workspace with the APL Android, and (optionally) APL Core code
```bash
$ ls
APLCoreEngine
APLViewhostAndroid
```
> The APL Core code is required for building the APL Android project. The Gradle build
> assumes it is in a sibling folder to the APLAndroidViewhost project. If the APL Core
> code is located elsewhere gradle commands must be augmented with `-PaplCoreDir=<path.to.core>`
> or set the value in the `gradle.properties` file.
- [Android SDK](https://developer.android.com/studio/intro/update) version 28 or higher
- [Android NDK](https://developer.android.com/ndk/guides/#download-ndk) version 22 or higher
- APL Core build dependencies (e.g. one of supported C++ compilers, CMake)
- Ninja (Needed for APLCoreEngine when building from APLViewhostAndroid)
## Android Studio

Setup a directory with the APL Android and APL Core - https://github.com/alexa/apl-core-library
The APL Android sample application is used to test and demo the APL Android functionality. It has a fixed
build dependency on apl-demo-debug.aar . The sample app targets Android SDK 28 and can be run with
an emulator for desktop display and projection.

```bash
$ ls
apl-core-library
apl-viewhost-android
To run the project in Android Studio:

- Launch the latest Android Studio (3.3.0+)
- Import the gradle project located at <workspace>/APLAndroidViewhost/
- You will see Android Studio Modules for "apl" and "app"
- Open file app/com/amazon/apl/examples/AplSampleActivity and select your preferred demo data, or add your own
- Run AplSampleActivity

> To debug the project configure Android Studio to find the debug symbols.
> "Run"->"Edit Configuration"->"Debugger"->"Symbol Directories" add the APL
> Android target root directory <workspace>/APLViewhostAndroid
## Building the APL Core for the Android APL Library

The APL Core library is a required dependency of the Android Viewhost and must be built using the CMAKE defines for Android.

To compile 'libaplcore.a' and 'libaplcore-jni.so' for armeabi-v7a devices, do the following, from the APL Core Library project:
```
The APL Core code is required for building the APL Android project. The Gradle build
assumes it is in a sibling folder to the `apl-viewhost-android` project. If the APL Core
code is located elsewhere, Gradle commands must be augmented with `-PaplCoreDir=<path.to.core>`
or you can set the value in the `gradle.properties` file.
$ mkdir build
$ cd build
$ cmake -DANDROID_ABI="armeabi-v7a" -DANDROID_PLATFORM=android-28 -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake -DAPL_JNI=ON ..
$ make -j4
```
For other architectures, the ANDROID_ABI flag should be set appropriately:
for example, -DANDROID_ABI="x86" for an x86 build

## Building the Android APL Library

Set the Android SDK root environment variable:

To build the Android APL library and the Sample application:
```bash
$ export ANDROID_SDK_ROOT=/Users/YOUR-LOGIN-HERE/Library/Android/sdk/
$ ./gradlew build
```

Build the Android APL library:
To install the `APL Sample App` connect your device or emulator:
```bash
$ ./gradlew build
$ ./gradlew app:installDebug
```

This step will also build the APL Core Library as a dependency.

To see a full list of Gradle tasks:
To see a full list of gradle tasks:
```bash
$ ./gradlew tasks
```
Expand All @@ -64,7 +89,23 @@ To see a full list of Gradle tasks:

### CMake Error
```
CMake Error at ...APLCoreEngine/thirdparty/thirdparty.cmake:120 (message):
CMake Error at /Volumes/workplace/APLAndroid/src/APLCoreEngine/thirdparty/thirdparty.cmake:120 (message):
CMake step for googletest failed: 1
```
The `ninja` build tool needs to be available on the `PATH`.

### Gradle Error
```
> Could not get unknown property 'externalNativeBuildCoreDebug' for project ':apl' of type org.gradle.api.Project.
```

The current android gradle version (3.3.0) requires a NDK install that includes a `platforms` folder.
Starting with NDK 22.x, the `platforms` folder no longer exists. Additionally,
the default ndk location for 3.3.0 is `$ANDROID_SDK_HOME/ndk-bundle`, but the current version of
Android Studio (4.1.2) is no longer capable of installing the NDK to that location.

To work around this error (on a mac), you should download a compatible ndk version (< 22.x) and then
symbolic link it to the `ndk-bundle` folder:
```
ln -s /Users/$USER/Library/Android/sdk/ndk/20.0.5594570/ /Users/$USER/Library/Android/sdk/ndk-bundle
```
10 changes: 10 additions & 0 deletions apl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,18 @@ add_library(
# Provides a relative path to source file(s).
src/main/cpp/jniapl.cpp
src/main/cpp/jniaction.cpp
src/main/cpp/jniaudioplayer.cpp
src/main/cpp/jniaudioplayerfactory.cpp
src/main/cpp/jnicontent.cpp
src/main/cpp/jnidocumentsession.cpp
src/main/cpp/jniextensionclient.cpp
src/main/cpp/jniextensioncommand.cpp
src/main/cpp/jniextensioncomponent.cpp
src/main/cpp/jniextensioneventhandler.cpp
src/main/cpp/jniextensionfilter.cpp
src/main/cpp/jniextensionmediator.cpp
src/main/cpp/jnimediaplayer.cpp
src/main/cpp/jnimediaplayerfactory.cpp
src/main/cpp/jnirootcontext.cpp
src/main/cpp/jnirootconfig.cpp
src/main/cpp/jnisession.cpp
Expand Down Expand Up @@ -119,6 +124,7 @@ include_directories(../common/src/main/cpp/include)
add_custom_target(generate-android-enums ALL
COMMAND cd ${APL_CORE_DIR} && ${ENUMGEN_BIN}
-f "AnimationQuality"
-f "AudioPlayerEventType"
-f "BlendMode"
-f "ComponentType"
-f "ContainerDirection"
Expand Down Expand Up @@ -159,6 +165,7 @@ add_custom_target(generate-android-enums ALL
-f "ImageScale"
-f "KeyHandlerType"
-f "LayoutDirection"
-f "MediaPlayerEventType"
-f "Navigation"
-f "NoiseFilterKind"
-f "ObjectType"
Expand All @@ -172,6 +179,7 @@ add_custom_target(generate-android-enums ALL
-f "SpanAttributeName"
-f "SpanType"
-f "Snap"
-f "SpeechMarkType"
-f "TextAlign"
-f "TextAlignVertical"
-f "TokenType"
Expand All @@ -190,13 +198,15 @@ add_custom_target(generate-android-enums ALL
-l java -p com.amazon.apl.enums -o ${CMAKE_CURRENT_SOURCE_DIR}/src/main/java/com/amazon/apl/enums
${APL_CORE_DIR}/aplcore/include/action/*.h
${APL_CORE_DIR}/aplcore/include/animation/*.h
${APL_CORE_DIR}/aplcore/include/apl/audio/*.h
${APL_CORE_DIR}/aplcore/include/apl/command/*.h
${APL_CORE_DIR}/aplcore/include/apl/component/*.h
${APL_CORE_DIR}/aplcore/include/apl/content/*.h
${APL_CORE_DIR}/aplcore/include/apl/datagrammar/*.h
${APL_CORE_DIR}/aplcore/include/apl/document/*.h
${APL_CORE_DIR}/aplcore/include/apl/engine/*.h
${APL_CORE_DIR}/aplcore/include/apl/graphic/*.h
${APL_CORE_DIR}/aplcore/include/apl/media/*.h
${APL_CORE_DIR}/aplcore/include/apl/primitives/*.h
${APL_CORE_DIR}/aplcore/include/apl/time/*.h
${APL_CORE_DIR}/aplcore/include/apl/utils/*.h
Expand Down
17 changes: 6 additions & 11 deletions apl/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,16 @@ ext {
aplCoreDirCmakeArg = "-DAPL_CORE_DIR=" + projectDir + "/../../apl-core-library"
if (project.hasProperty('aplCoreDir')) {
aplCoreDirCmakeArg = "-DAPL_CORE_DIR=" + aplCoreDir
} else {

}
}

android {
compileSdkVersion 28
compileSdkVersion 31
ndkVersion "23.0.7599858"
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 22
targetSdkVersion 28
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -67,11 +65,6 @@ android {
arguments aplCoreDirCmakeArg, aplAndroidCmakeArgs
}
}
ndk {
// Specifies the ABI configurations for the native libraries
// that Gradle will build and package with the APK.
abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand Down Expand Up @@ -130,10 +123,11 @@ android {
}

dependencies {
compileOnly 'org.projectlombok:lombok:1.18.12'
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.annotation:annotation:1.0.0'
implementation 'androidx.core:core:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.github.bumptech.glide:glide:4.6.1'
implementation project(':common')
implementation (project(':discovery')) { transitive = false }
Expand All @@ -156,6 +150,7 @@ dependencies {
api "com.google.auto.value:auto-value-annotations:1.7"
api 'com.google.guava:guava:27.0.1-jre'
annotationProcessor "com.google.auto.value:auto-value:1.7"
annotationProcessor 'org.projectlombok:lombok:1.18.12'
}

project.afterEvaluate {
Expand All @@ -172,4 +167,4 @@ project.afterEvaluate {
tasks.test.finalizedBy(jacocoTestReport)
}

tasks.build.dependsOn(assembleAndroidTest)
tasks.build.dependsOn(assembleAndroidTest)
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
package com.amazon.apl.android;

import android.content.Context;
import android.view.TextureView;
import android.view.View;

import com.amazon.apl.android.dependencies.IMediaPlayer;
import com.amazon.apl.android.media.RuntimeMediaPlayerFactory;
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.enums.RootProperty;
Expand All @@ -21,6 +25,7 @@
import androidx.test.platform.app.InstrumentationRegistry;

import static junit.framework.TestCase.fail;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -60,6 +65,7 @@ public class APLTestContext {
// The view context bv
private IAPLViewPresenter mPresenter = mock(IAPLViewPresenter.class);

private IMediaPlayer mMockMediaPlayer = mock(IMediaPlayer.class);

public Content buildContent() {
if (mContent == null) {
Expand Down Expand Up @@ -113,18 +119,32 @@ public ViewportMetrics buildMetrics() {


public RootConfig buildRootConfig() {
if (mRootConfig == null)
if (mRootConfig == null) {
mRootConfig = RootConfig.create("Unit Test", "1.0")
.registerDataSource("dynamicIndexList")
// On heavy load, the speed of the Espresso `swipeLeft` and `swipeRight` actions
// can fall below the threshold and not register as swipes to core.
// We need to lower the threshold so that the swipes get detected properly.
.set(RootProperty.kTapOrScrollTimeout, 50) // Half of the Fast swipe speed.
.pagerChildCache(3)
.sequenceChildCache(3);
.sequenceChildCache(3)
.mediaPlayerFactory(new RuntimeMediaPlayerFactory(new MediaPlayerProvider()));
}
return mRootConfig;
}

private class MediaPlayerProvider extends AbstractMediaPlayerProvider<View> {

@Override
public IMediaPlayer createPlayer(Context context, View view) {
return mMockMediaPlayer;
}

@Override
public View createView(Context context) {
return new TextureView(context);
}
}

public IAPLViewPresenter buildPresenter() {
when(mPresenter.getContext()).thenReturn(InstrumentationRegistry.getInstrumentation().getContext());
Expand All @@ -145,7 +165,6 @@ public APLTestContext buildRootContextDependencies() {


public RootContext buildRootContext() {

APLController.setRuntimeConfig(RuntimeConfig.builder().build());
buildRootContextDependencies();

Expand Down

0 comments on commit bcb4462

Please sign in to comment.