Code Requirements

Code Requirements are best practices and code styles that shall be implemented in all FCA applications written for the R1 HU.

Application Code Requirements:

Android™ Version
Kotlin Use
V2C Global API Version
Package Naming
App Versioning
Android™ Manifest Entries
DRM Check sends AppManager intent VERIFY_DRM
On Boot Complete
UI Design Approach
Full Screen Mode

Android™ Version

The R1H and R1L platforms will be launching on the same Android™ version for each model year. All apps shall compile with the Android™ versions shown below.

Model Year Android™ Version
MY22 Android O-MR1 (API level 27)
MY21 Android O-MR1 (API level 27)

Top

Kotlin Use

SD.0A684 - FCA Signed Third Party Android Application Security Requirements Specification

[2.13.7] Second party applications shall be using approved languages for application development. For Android based telematics system/radio shall be using Java and may use C/C++ for native interface. Suppliers shall not use scripting languages like Javascript or Kotlin in their application.

Top

V2C Global API Version

  1. Applications that communicate with the FCA cloud shall use the V2C Global API.

V2C Global API are protocol buffers. Protocol Buffers are a method of serializing structured data. It is useful in developing programs to communicate with each other over a wire or for storing data. The method involves an interface description language that describes the structure of some data and a program that generates source code from that description for generating or parsing a stream of bytes that represents the structured data.

Download Model Year V2C Global API Version
MY21 3.4

As of CAE API 1.3 the dependency on a specific version of protocol buffers has been removed.

Top

Package Naming

Package names for all R1 apps shall be com.fca.uconnect.[app name].[app subpackage]. The package name shall be less than the 50 character limit imposed by the FCA SDP.

The following segments shall follow the Android application ID naming conventions found in the Android™ Developer site at Set the application ID.
[app name] is the application name and must be unique.
[app subpackage] is any sub package names the app requires.

Top

App Versioning

The format for the app versionName in the Android™ manifest for all R1 apps shall be SRXX-YY-MM-DD-Rev.X
where :
XX is the current model year,
YY – Two Digit Year,
MM – Two Digit Month,
DD – Two Digit Date,
X – Letter A, B, C…ish

The purpose of this versioning scheme is to track build dates as well as to provide a versioning scheme that always has a value that is greater than the previous by using the date. Multiple builds in a single day will be tracked by the revision, which uses a capital letter in English ascending alphabetical order.

For example: versionName "SR21-20-03-31-Rev.A"

Top

Android™ Manifest Entries

The following app manifest entries are optional, but required to enable the behaviors described.

ShowConditions, deprecated, controls if an app will be made or not made visible in the App drawer based on the conditions listed. All conditions must be satisfied and the app must have UI to be shown in the apps list. If this entry is not present (default), the app will be visible in the App drawer.

Format:

Standard Value JSON Format:

Standard Value JSON Rules:

  1. CAN Architecture key values shall be one of the following, PNET, PNET2, ATL_M or ATL_H.
  2. CAN Architecture key values that are not present in the JSON value definitions shall be considered the same as the default or true. So, if PNET2 CAN architecture is missing then on a PNET2 vehicle the app will be shown in the app drawer.
  3. With the exception of TBM_Present, LID_x shall be the Logical IDs specified in the FCA R1 Transfer Functions but limited to proxy and configuration values in the VehicleConfigManager. If the LID specified is not in VehicleConfigManager then the app will not be shown.
  4. The comma between JSON key value pairs represents "and".
  5. The comma between an array of CAN signal values indicates "or".
  6. A CAN_Architecture_Key shall be provided for each CAN architecture the app will access. The firmware shall only use the LID value pairs for the CAN architecture the app is current running on.
  7. Any ShowConditions parse errors shall be considered false or conditions not met and the app will not be shown in the app drawer.

Standard Value Example:

PNET CAN Architecture: VC_VEH_LINE = 1(WK) or VC_VEH_LINE = 49(JL) and VC_SRT_PRSNT = 0 and VC_OffRoadPg = 1.
ATL Mid CAN Architecture: VC_VEH_LINE = 93(MP) and VC_SRT_PRSNT = 0 and VC_OffRoadPg = 1.
ATL High CAN Architecture: VC_VEH_LINE = 101(WL) and VC_SRT_PRSNT = 0 and VC_OffRoadPg = 1.

Special Value JSON Format:

Special Value Example:

InstallConditions, replaces ShowConditions and if present an app will be installed or not installed based on the conditions listed. All conditions must be satisfied for the app to be installed. If this entry is not present (default), the app will be installed.

If an app is not installed due to the install conditions, then AppManager will return an install condition error. Until a new CAE API spec release, the integer error code shall be 14 as shown below.
public static final int ERROR_INSTALL_CONDITION = ERROR_CODE_BASE + 14;

Priv App Handling:

AppManager shall use "pm hide/unhide" on 2nd party apps which do not meet the "install criteria" but are installed under priv apps folder.

Example, assuming Alexa app should not show up under all regions. In that case, upon reading the app manifest file, AppManager will see that the app should not be "installed" and then run pm hide on the Alexa package.

Format:

Standard Value JSON Format:

Standard Value JSON Rules:

  1. CAN Architecture key values shall be one of the following, PNET, PNET2, ATL_M, or ATL_H.
  2. CAN Architecture key values that are not present in the JSON value definitions shall be considered the same as the default or true. So, if PNET2 CAN architecture is missing then on a PNET2 vehicle the app will be installed.
  3. With the exception of TBM_Present, LID_x shall be the Logical IDs specified in the FCA R1 Transfer Functions but limited to proxy and configuration values in the VehicleConfigManager. If the LID specified is not in VehicleConfigManager then the app will not be installed. The statement “ATL_M”: [] would mean the app is not installed on ATL mid.
  4. The comma between JSON key value pairs represents "and".
  5. The comma between an array of CAN signal values indicates "or".
  6. A CAN_Architecture_Key shall be provided for each CAN architecture the app will access. The firmware shall only use the LID value pairs for the CAN architecture the app is current running on.
  7. Any InstallConditions parse errors shall be considered false or conditions not met and the app will not be installed.

Standard Value Example 1

PNET CAN Architecture: VC_VEH_LINE = 35(WD) or VC_VEH_LINE = 49(LD) and VC_SRT_PRSNT = 1.
ATL Mid CAN Architecture: VC_VEH_LINE = 88(521) and VC_SRT_PRSNT = 1.
ATL High CAN Architecture: VC_VEH_LINE = 89(636VM) and VC_SRT_PRSNT = 1.

Standard Value Example 2

VC_VEH_LINE = RU and Hybrid_Type = PHEV

Special Value JSON Format:

Special Value Example:

Category, is optional and defines what tabbed views an app will be part of. The categories are defined in the HMI App Drawer Content document. The 1st cat in list is highlighted if multiple.

Example

VR Launch, is optional and allows the apps to give VR Names for different languages that the HU's support for use by the VR engine to start the app through VR.

The locales and Names are separated by a ":". Synonyms separated by commas (,) and locales are separated by semi colon (;).

Examples

Top

DRM Check

All applications shall perform a DRM check as the first task in onCreate. The DRM check will verify the Digital Rights of the customer by sending AppManager intent VERIFY_DRM.

The verify DRM intent performs the following sequence of checks.

  1. The requesting app has valid permissions for the intent.
  2. The app package is installed return.
  3. DRM is present on the vehicle.
    Note: if app package is registrationExempt then skip the registration and subscription check.
  4. DRM stage is REGISTERED.
  5. DRM stage is SUBSCRIBED.
  6. The app package is in the DRM grant list.
  7. The current date is within the apps begin time stamp and end date time stamp.

Uconnect® customer's must be registered and subscribe for Uconnect® features. If the customer is not registered and subscribed the app must terminate and start the In-Vehicle Activation (IVA)app.

If the DRM check fails for any reason other than not registered or subscribed the app must terminate.

You can download the intent definition found in AppManager on the Common Interfaces page.

The following code should be used for the DRM check. It can be downloaded here VerifyDRM Reference Code .

private final int MAX_RETRY_VERIFY_DRM_TIMES = 3;
private final int WAIT_VERIFY_DRM_RESP_TIMEOUT = 500; // 500ms
private final int MSG_VERIFY_DRM_RESP = 1;
private final int MSG_VERIFY_DRM_TIMEOUT = 2;
private int mDrmVerifyResult = AppManager.RESULT_UNKNOWN;

/**
 * Handler used for the verify DRM return message.
 */
private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_VERIFY_DRM_RESP:
                mHandler.removeMessages(MSG_VERIFY_DRM_TIMEOUT);
                if (AppManager.RESULT_UNKNOWN == mDrmVerifyResult) {
                    handleVerifyDrmResult(msg);
                } // else duplicated, ignore
                break;
            case MSG_VERIFY_DRM_TIMEOUT:
                if (msg.arg1 < MAX_RETRY_VERIFY_DRM_TIMES) {
                    // send verify DRM broadcast again
                    verifyDrm(msg.arg1 + 1);
                } else {
                    handleVerifyDrmTimeout();
                }
                break;
            default:
                break;
        }
    }
};
private Messenger mCallback = new Messenger(mHandler);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    verifyDrm(0);
}

/**
 * verifyDRM sends the AppManager intent and sets up a time out method.
 *
 * @param seq is the sequence of calls to verifyDRM that is checked against the max
 *            count for retries. 1st call should always be zero.
 */
public void verifyDrm(int seq) {
    Intent verifyDRMIntent = new Intent(AppManager.ACTION_VERIFY_DRM);
    verifyDRMIntent.setPackage(AppManager.UCONNECT_SERVICE_PACKAGE);
    verifyDRMIntent.putExtra(AppManager.EXTRA_REQUEST_CODE, MSG_VERIFY_DRM_RESP);
    // The calling app package name must be entered here replacing "com.fca.uconnect.your app".
    verifyDRMIntent.putExtra(android.content.Intent.EXTRA_PACKAGE_NAME, "com.fca.uconnect.yourapppackage");
    verifyDRMIntent.putExtra(AppManager.EXTRA_CALLBACK, mCallback);
    mAppContext.sendBroadcast(verifyDRMIntent);

    mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_VERIFY_DRM_TIMEOUT, seq, 0),
            WAIT_VERIFY_DRM_RESP_TIMEOUT);
}

/**
 * Handles the returned verifyDRM message. This method will either terminate the app
 * or allow it to run.
 *
 * @param msg returned from AppManager verifyDRM intent.
 */
private void handleVerifyDrmResult(Message msg) {
    mDrmVerifyResult = msg.arg1;

    // If verify DRM results are RESULT_OK then the app should continue running.
    if (mDrmVerifyResult == AppManager.RESULT_NOK) {
        // IVA will only handle Registration and Subscription.
        if (msg.arg2 == AppManager.ERROR_VEH_NOT_REGISTERED || msg.arg2 == AppManager.ERROR_NO_ACTIVE_SUBSCRIPTION) {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.fca.uconnect.iva", "com.fca.uconnect.iva.ExpiredConnectionActivity"));
            if (intent != null) {
                intent.putExtra(AppManager.ERROR_CODE, msg.arg2);
                try {
                    startActivity(intent);
                } catch (Exception e) {
                    // For some regions IVA will not be installed. The subscription in these regions is controlled
                    // using DRM. In these cases allow the app to run.
                    Log.d("VerifyDRM", "IVA is not availble, launch intent failed");
                }
            } else {
                Log.d("VerifyDRM", "IVA is not availble, launch intent is null");
                finish();
            }
        } else {
            Log.d("VerifyDRM", "App failed DRM check with return code " + msg.arg2);
            finish();
        }
    }
}

/**
 * handleVerifyDrmTimeout is called after the max number of retries. There was no response from AppManager
 * so the app must exit.
 */
private void handleVerifyDrmTimeout() {
    Log.d("VerifyDRM","verify DRM timed out.");
    finish();
}
				

Top

On Boot Complete

Applications shall not use BOOT_COMPLETED broadcast to autostart.

The Android™ BOOT_COMPLETED broadcast is sent after the system has finished booting. At this point not all services are available to an app. Using this broadcast in a production app may cause thrashing.

The BOOT_COMPLETED broadcast can be used to test an app and should be removed after unit testing. See how to Auto Start and app.

Top

UI Design Approach

UI design approach should use responsive layout design first, if unable to be responsive then map PDO template to HU size.

Responsive Layout Design guidance can be found at Constrain Layout, Screen Sizes and Responsive Layout

Hardcoded display size examples:

Display display = getWindowManager().getDefaultDisplay();
String displayName = display.getName();  // minSdkVersion=17+

// display size in pixels
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

// pixels, dpi
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int heightPixels = metrics.heightPixels;
int widthPixels = metrics.widthPixels;
int densityDpi = metrics.densityDpi;
float xdpi = metrics.xdpi;
float ydpi = metrics.ydpi;
				

Top

Full Screen Mode

Applications shall not use full screen mode.

Full screen mode hides the status bar and shall not be used in our apps.

Top

Updated: 09/21/2020, Android is a trademark of Google LLC