Android App Launch Service

Use AppLaunchService to install and launch applications, such as games, eReader applications, or pre-installed applications, on the Android seatback monitor.

AppLaunchService adds to the PAC Information Bundle, sets up OBBs for applications to mount, and performs other actions, such as cleaning previous games if too many applications are already installed, or pausing game launch if the flight is displaying a Public Announcement (PA).

For more information on the PAC Information Bundle, refer to PAC Information Bundle.

Prerequisites

You will need the following to use AppLaunchService:

  • android_pac_apps — version 01.87.00.00 or higher

  • pacio — version 03.06.0.01 or higher

Setup

For each application, provide CFG, OBB, and APK files as follows.

CFG

The filename of the CFG file must match the filename of the APK.

Example with the required minimum parameters:

{
    "apk": "games_app.apk",
    "launchintent": "com.abc.games.app",
    "obb": [],
    "pacinfobundle": 1
}

The CFG file can contain the following parameters:

  • apk — Required

    Specifies the name of the application's APK.

    Example:

    {
        "apk": "SAMPLE.apk"
    }
  • launchintent — Required

    Specifies the main activity passed to AppLaunchService to launch the application.

    Format: packageName/activityName

    If the ActivityName is not specified, AppLaunchService will query for the launch activity and use that instead.

    Example with ActivityName specified:

    {
        "launchintent": "com.dtisoft.games.candys/com.dtisoft.games.candys.ActivitiyName"
    }

    Example without ActivityName specified:

    {
        "launchintent": "com.dtisoft.games.candys"
    }
  • obb — Required

    Specifies the name of all OBBs that are associated with the application, if any. Set to an empty array if the application contains no OBBs.

    Example with no OBBs:

    {
        "obb": []
    }

    Example with one OBB:

    {
        "obb": ["SAMPLE.APP.obb"]
    }

    Example with multiple OBBs:

    {
        "obb": [
            "SAMPLE.APP1.obb",
            "SAMPLE.APP2.obb",
            "SAMPLE.APP3.obb"
        ]
    }
  • pacinfobundle — Required

    Set this parameter to 1 if you want LRU and configuration information. Otherwise, set this to 0.

    If set to 1, refer to the PAC Information Bundle for LRU and configuration information.

  • extras — Optional

    These are extra commands that AppLaunchService can send to the application.

    Example:

    {
        "extras": {
            "key1": "abc",
            "key2": 123
        }
    }
  • quit — Optional

    This is a command that AppLaunchService sends to quit the application.

    Example:

    {
        "quit": "SAMPLE.APP.quit"
    }
  • DefaultInputMode — Optional

    Specifies how the D-pad is used in handsets.

    Example:

    DefaultInputMode = { { 1, 4, 7, 8 }, 0, 0, 0, 0, 0 };

    Format:

    DefaultInputMode = { { a, b, c, d }, e, f, g, h, i };

    The following values can be set:

    ElementDescription
    a

    Pointer modes.

    Values:

    • 0 — iicore_handset_control_enum_keymap_mode_mouse
    • 1 — iicore_handset_control_enum_keymap_mode_keyboard
    • 2 — iicore_handset_control_enum_keymap_mode_point
    • 5 — iicore_handset_control_enum_keymap_mode_dual_keypad
    b

    Orientation modes.

    Values:

    • 3 — horizontal
    • 4 — vertical
    c

    Handset key enable/disable modes.

    Values:

    • 6 — iicore_handset_control_enum_keymap_mode_enable_key_to_mouse
    • 7 — iicore_handset_control_enum_keymap_mode_disable_key_to_mouse
    d

    Touchpad modes.

    Values:

    • 8 — disable touchpad mouse
    • 9 — enable touchpad mouse
    eAcceleration of the mouse mode pointer.
    fInitial speed of the mouse mode pointer.
    gMax speed of the mouse mode pointer in pixels per second.
    h

    Enable or disable touch screen state.

    Values:

    • 0 — enable
    • 1 — disable
    i

    Specify remote touch screen mode.

    Values:

    • 0 — Touch screen: Requires absolute coordinates.
    • 1 — Touchpad: Acts similar to a trackpad.
    • 2 — Dual mode: Acts similar to a trackpad except when multiple fingers are interacting with the touch screen.
    • 3 — D-pad mode: Recognizes up, down, left and right key events, depending on the swipe gesture.
  • receiver_action, receiver_name — Optional

    This is intended for core applications that need to run in the background.

    This allows preinstalled applications to run in the background as a service on bootup.

    • receiver_name — Represents the BroadcastReceiver that is listening for the action specified in receiver_action.

    • receiver_action — Represents the name of the action that the application's BroadcastReceiver is listening for.

    When an application is installed, it is in an "inactive" state. To start the application for the first time or during bootup, core services send an intent with the receiver action and name indicated in the configuration file. The receiver in your application can then start itself as a background service.

    • If the application is running on Android 8, BroadcastReceiver can call startForegroundService().

    • If the application is running on Android 5.1, BroadcastReceiver can call startService().

    Example:

    {
        "receiver_action": "aero.panasonic.intent.action.test",
        "receiver_name": "aero.pac.simpletestapp3/aero.pac.simpletestapp3.MyReceiver"
    }
  • navigationbutton — Optional

    Specifies the visibility of specific buttons on the navigation bar. This is only available if the system allows the Android navigation bar to display.

    Panasonic Android systems will not display the navigation bar by default. For additional information, contact your Panasonic focal.

    The following values can be set:

    ValueDescription
    0Disable no buttons
    1Disable the Home button
    2Disable the Recent Applications button
    3Disable the Home and Recent Applications buttons
    4Disable the Back button
    5Disable the Back and Home buttons
    6Disable the Back and Recent Applications buttons
    7Disable all buttons

OBB

OBBs are optional. Assign OBBs with the permission 666. OBBs must be placed in the apps directory through an NBD content push.

OBB Listener

This is for preinstalled applications that contain OBBs and are launched on bootup.

When an application is unable to mount, it is recommend to incorporate retry logic that triggers at regular intervals to retry mounting, such as every ten seconds. Once OBBs are linked to the application, AppLaunchService will send a broadcast intent with the following values:

  • action: "aero.panasonic.intent.action.OBB_LINKED"

  • extra: "package_name", package name

The application can also listen for this broadcast intent when remounting OBBs.

APK Placement for Specific Behaviors

APK Placement Through a Software Loadable

To install an application on bootup, place the APK, CFG, and checksum files in /tmp/pluginshare/sw_apps.

All required OBBs must still be pushed through NBD to /tmp/pluginshare/nbd/vfs/apps with the cd_apk tag.

APK Placement with NBD

Another way to install an application on bootup is to push application files to the seat through NBD.

To do so, register all required files with NBD with the cd_apk tag and push the APK, CFG, and checksum files to /tmp/pluginshare/nbd/vfs/install_apps.

All required OBBs must be pushsed to /tmp/pluginshare/nbd/vfs/apps with the cd_apk tag.

To ensure an application gets preinstalled or is able to have its content updated during a flight, it is critical to register all relevant files with the cd_apk tag to information AppLaunchService through PACIO messages to process the pushed NBD files accordingly.

Software Loadables Installed on Bootup Using NBD

For software loadables that are installed on bootup with NBD to push its OBB:

  • Create a folder in /tmp/pluginshare/sw_apps with the APK and CFG files.

  • Use NBD to push the OBB to /tmp/pluginshare/nbd/vfs/apps.

  • Register all files with a cd_apk tag.

  • Specify the OBB root names in the configuration file. The full path is not required.

Services in Android 8.1

This is intended for core service applications that need to run in the background.

For a long running background service, the application must specify the BroadcastReceiver name with receiver_name.

Once the application receives the broadcast intent, the application must start as a foreground service. For additional information, refer to Foreground Services.

When creating a notification, silence any sounds that would normally play. Silencing sounds also prevents notifications from appearing in the notification bar.

Example:

Intent notificationIntent = new Intent(this, QtActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
if (android.os.Build.VERSION.SDK_INT >=
    android.os.Build.VERSION_CODES.O) {
    Notification notification = new Notification.Builder(this, CHANNEL_ID)
        .setContentTitle("forcevideo")
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentIntent(pendingIntent)
        .setPriority(Notification.PRIORITY_LOW)
        .setOnlyAlertOnce(true)
        .setSound(null, null)
        .build();
    context.startForeground(1, notification);
} else {
    Intent serviceIntent = new Intent(context, YourService.class);
    context.startService(serviceIntent);
}
Android Manifest

The manifest must include the following:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
SDK Compatibility in Android 8.1

For Android 8.1 applications, compile the SDK and target SDK using version 27.

For additional information refer to Migrating to Android 8.0.

Example:

android {
    compileSdkVersion 27
    buildToolsVersion "28.0.3"
}
compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
}
defaultConfig {
    minSdkVersion 19
    targetSdkVersion 27
    versionCode 1
    versionName "1.0"
}
lintOptions {
    abortOnError false
}

Manage VFS Applications

Install and launch Virtual File System (VFS) applications installed on the system with VfsAppManager. The interactive does not need to manually uninstall applications.

The following diagram details the process of launching an application with VfsAppManager.

Process of launching an application with VfsAppManager
Process of launching an application with VfsAppManager

When installing or launching an application, you can optionally set the queue_size extra parameter, which specifies the maximum number of installed VFS applications allowed.

If queue_size is specified and the number of installed VFS applications is equal to queue_size, then VfsAppManager will uninstall all VFS applications first before installing or launching a new application.

If queue_size is not specified, its value will be set to -1 by default. This means VfsAppManager will install the application without verifying if other VFS applications are installed.

Install

You can install single or multiple applications without launching the applications. You can also directly launch applications without installing beforehand because launching automatically installs the application.

If a VFS application is already installed, continue with launching the application.

Install Single Application

To install a single application, create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_LAUNCH_APP"

  • extra: "launch_app", root CFG filename

    Example of a root CFG filename: dtigames_minepatr

  • extra: "install_only", "true"

  • extra: "queue_size", integer value

    This is optional.

Install Multiple Applications

To install multiple applications at once, create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_INSTALL_APP"

  • extra: "install_apps", ArrayList of applications

    Use putStringArrayListExtra with the ArrayList.

  • extra: "queue_size", integer value

    This is optional.

Launch

Launch Normally

Create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_LAUNCH_APP"

  • extra: "launch_app", root CFG filename

    Example of a root CFG filename: dtigames_minepatr

  • extra: "queue_size", integer value

    This is optional.

  • extra: "extras"

    This is a bundle with any additional parameters to pass to VfsAppManager.

Example:

val intent = Intent("aero.panasonic.intent.action.VFS_LAUNCH_APP")
intent.putExtra("launch_app", appName)
val bundle = Bundle()
intent.putExtra("extras", bundle)
context.sendBroadcast(intent)

Launch Using Custom Launch Intent

You can launch applications specified from your own launch intent Specify the class name and add the Intent.FLAG_RECEIVER_FOREGROUND flag. This may allow an application to launch more quickly.

Example:

Intent intent = Intent("aero.panasonic.intent.action.LAUNCH_APP") 
intent.setClassName("aero.panasonic.applaunchservice", "aero.panasonic.applaunchservice. AppLaunchReceiver") 
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND) 
intent.putExtra("launch_intent", appIntent); // appIntent is the intent to launch your application. 
sendBroadcast(intent);

Get Status Updates

To receive status updates, create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_LAUNCH_APP_STATUS"

  • extra: "return_code", integer value

    Create return_code variables and set to the following integer values:

    return_code variableSet to
    ERROR_CANT_CREATE_LINK-2
    ERROR_OBB_FILE_NOT_FOUND-3
    ERROR_CONFIG_FILE-4
    ERROR_TIMEOUT-10
    ERROR_CODE_NOT_RETURNED-999
    RETURN_CODE_INSTALLING-50
    ERROR_NO_LAUNCH_INTENT_FOR_PACKAGE-51
    RETURN_CODE_INSTALLATION_DONE-52
    RETURN_CODE_LAUNCH_CANCELED-60
    RETURN_CODE_LAUNCHING-100

package_name and launch_app will be returned as extras with the package name and application's root CFG filename for the following status return_code variables:

  • RETURN_CODE_INSTALLING

  • RETURN_CODE_INSTALLATION_DONE

  • RETURN_CODE_LAUNCHING

  • RETURN_CODE_LAUNCH_CANCELED

Uninstall

You can uninstall a single application or all applications at the same time.

When the application is uninstalled, listen for the android.intent.action.PACKAGE_REMOVED action, which signals the action for Android package removal.

Uninstall Single Application

To uninstall a single application, create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_UNINSTALL"

  • extra: "delete_data", "true" or "false"

    This is to indicate if application data should be deleted. By default, this is set to true.

    This is optional. By default, this is set to true.

  • extra: "uninstall_pkg", package name

    or

    extra: "launch_app", root CFG filename

    Example of a root CFG filename: dtigames_tetris

Uninstall All Applications

You can uninstall all VFS applications, such as games. Preinstalled applications are not uninstalled and are located in the following directories:

  • /tmp/pluginshare/sw_apps

  • /tmp/pluginshare/nbd/vfs/installs_apps

  • /tmp/pluginshare/nbd/vfs/resource_apps

Create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_REMOVE_ALL"

  • flag: "Intent.FLAG_INCLUDE_STOPPED_PACKAGES"

Intent intent = Intent("aero.panasonic.intent.action.VFS_REMOVE_ALL") 
intent.setAction("aero.panasonic.intent.action.VFS_LAUNCH_APP") intent.setClassName("aero.panasonic.applaunchservice", "aero.panasonic.applaunchservice. UninstallReceiver") 
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)

Clear User Data

You can clear user data from an application. Android will force the application to stop after data is cleared.

Create an intent as follows:

  • action: "aero.panasonic.intent.action.CLEAR_USER_DATA"

  • extra: "package_list", StringArrayList of package names to clear user data

Cancel Pending Launch

You can stop an application from launching if it's in the process of being installed bu has not been launched.

An example of this situation is when a pending application is trying to launch but must be canceled from launching due to a closed flight event.

Create an intent as follows:

  • action: "aero.panasonic.intent.action.VFS_CANCEL_LAUNCH_APP"
Intent vfsIntent = Intent ("aero.panasonic.intent.action.VFS_CANCEL_LAUNCH_APP")
vfsIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)