Migration Guide: 6.13 to 6.15

We’re excited to bring you You.i Platform version 6.15. As part of this release, there are some changes that may affect your application. For simplicity, the steps below are organized by the type of application you’re developing.

C++ Applications

C++ Behavior Changes

Elementary Stream video player name changes

We’ve updated our castLabs-based PlayStation, Tizen NaCl elementary stream, and LG webOS elementary stream video player names to be more consistent and clearly reflect the different technologies in use.

  • PlayStation
    • Before: You.i Labs castLabs
    • After: You.i castLabs PlayStation
  • LG webOS
    • Before: You.i castLabs LG ES
    • After: You.i castLabs webOS ES
  • Tizen NaCl
    • Before: Samsung::NaClPlayer::MediaPlayer
    • After: You.i castLabs Tizen NaCl ES

More audio track details on Android

We’ve added the following audio track details on Android so that you can differentiate between tracks in the same language tracks with different audio encodings. Note that these fields are only populated for Android devices.

CYICodecType::Audio - The codec type of the audio track.

  CYIOptional<CYICodecType::Audio> codecType;

CYICodecProfile::Audio - The codec profile of the audio track.

  CYIOptional<CYICodecProfile::Audio> codecProfile;

bitrateKbps - The audio track bitrate, in Kbps.

  CYIOptional<float> bitrateKbps;

channelCount - The audio track channel count.

  CYIOptional<int32_t> channelCount;

C++ Breaking Changes

CYIAppLifeCycleBridge removed

We’ve removed the previously deprecated CYIAppLifeCycleBridge and CYIAppLifeCycleBridgeLocator. This functionality was moved to CYIApp in a previous release. This change affects application code that listens for lifecycle events as well as platform code that sends lifecycle event notifications.

Application code prior to 6.15
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
    pAppLifeCycleBridge->BackgroundEntered.Connect(*this, &MySignalHandler::OnBackgroundEntered);
    pAppLifeCycleBridge->ForegroundEntered.Connect(*this, &MySignalHandler::OnForegroundEntered);
}
Application code now in 6.15
CYIApp *pApp = CYIAppContext::GetInstance()->GetApp();
if (pApp)
{
    pApp->BackgroundEntered.Connect(*this, &MySignalHandler::OnBackgroundEntered);
    pApp->ForegroundEntered.Connect(*this, &MySignalHandler::OnForegroundEntered);
}
Platform code prior to 6.15
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
    pAppLifeCycleBridge->OnBackgroundEntered();
}
...
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
    pAppLifeCycleBridge->OnForegroundEntered();
}
Platform code now in 6.15
CYIApp *g_pApp; // Assuming the CYIApp is accessible in a global context
if (g_pApp)
{
    g_pApp->OnBackgroundEntered();
}
...
if (g_pApp)
{
    g_pApp->OnForegroundEntered();
}

Crash Handler changes

We changed the way you modify CrashReport::PostData. Previously, you needed to directly modify the PostData. Now, you need to use setters and getters.

We’ve added setters and getters as follows:

PostData &CYICrashHandler::GetCrashReportPostData();
PostData &CYICrashHandler::GetMinidumpPostData();

void CYICrashHandler::SetCrashReportPostData(const PostData &postData);
void CYICrashHandler::SetMinidumpPostData(const PostData &postData);
Prior to 6.15
CYICrashHandler::crashReportPostData.url = myUrl;
Now in 6.15
CYICrashHandler::PostData postData = CYICrashHandler::GetCrashReportPostData();
postData.url = myUrl;
CYICrashHandler::SetCrashReportPostData(postData);

Changes to closed captioning methods

We’ve moved GetDefaultFontFamilyForFontType, GetFontIdForFontType, and SetFontIdForFontType methods to CYIClosedCaptionsStyleManager. This change affects all applications that use closed caption font utilities.

Prior to 6.15
CYIString fontFamily = CYIClosedCaptionsStylingBridge::GetDefaultFontFamilyForFontType(fontType);
ssize_t fontId = CYIClosedCaptionsStylingBridge::GetFontIdForFontType(fontType);
bool success = CYIClosedCaptionsStylingBridge::SetFontIdForFontType(fontType, fontId);
Now in 6.15
CYIString fontFamily = CYIClosedCaptionsStyleManager::GetDefaultFontFamilyForFontType(fontType);
ssize_t fontId = CYIClosedCaptionsStyleManager::GetFontIdForFontType(fontType);
bool success = CYIClosedCaptionsStyleManager::SetFontIdForFontType(fontType, fontId);

Removal of CYIAbstractVideoPlayer::m_maxResolution

The CYIAbstractVideoPlayer m_maxResolution protected member variable has been removed. If you need to store this value, add this variable to your custom player implementation instead.

Cache path no longer defaults to Data path

CYIApp::SetCachePath must now be called with a path appropriate for storing cached network requests. Prior to 6.15, if CYIApp::SetCachePath wasn’t set, the value provided to CYIApp::SetDataPath was used.

Prior to 6.15
CYIApp *pApp;
...
pApp->SetDataPath(dataPath);
Now in 6.15
CYIApp *pApp;
...
pApp->SetDataPath(dataPath);
pApp->SetCachePath(dataPath);

Removal of CYIKeyboardInputBridge::InputType values

We’ve removed the previously deprecated input types CYIKeyboardInputBridge::InputType::TextWithoutSuggestions and CYIKeyboardInputBridge::InputType::Password.

We’ve replaced these input types with the input modifiers CYIKeyboardInputBridge::InputModifiers::MaskInput and CYIKeyboardInputBridge::InputModifiers::NoSuggestions, respectively. You can specify these input modifiers for a CYITextEditView with any input type using CYITextEditView::SetInputModifiers.

Prior to 6.15: Mask input
CYITextEditView *pTextEditView;
pTextEditView->SetInputType(CYIKeyboardInputBridge::InputType::Password);
Now in 6.15: Mask input
CYITextEditView *pTextEditView;
pTextEditView->SetInputModifiers(CYIKeyboardInputBridge::InputModifiers::MaskInput);
Prior to 6.15: Text without suggestions
CYITextEditView *pTextEditView;
pTextEditView->SetInputType(CYIKeyboardInputBridge::InputType::TextWithoutSuggestions);
Now in 6.15: Text without suggestions
CYITextEditView *pTextEditView;
pTextEditView->SetInputModifiers(CYIKeyboardInputBridge::InputModifiers::NoSuggestions);

Removal of CYIPasswordTextEditView

We’ve removed the previously deprecated CYIPasswordTextEditView. Prior to 6.15, CYIPasswordTextEditView allowed you to specify a CYITextEditView whose input is masked in the Engine view (as opposed to on any device on-screen keyboard). We’ve removed this functionality. You now need to call CYITextEditView::EnablePasswordMode.

Prior to 6.15
CYIPasswordTextEditView *pPasswordTextEditView;
Now in 6.15
CYITextEditView *pTextEditView;
pTextEditView->EnablePasswordMode(true);

Removal of YiMakeDirectory

We’ve removed the deprecated function YiMakeDirectory. You now need to call CYIDir::CreateDirectory instead. Note that CYIDir::CreateDirectory doesn’t support creating directories from relative paths.

Prior to 6.15
#include <deprecated/YiUtilities.h>

if (YiMakeDirectory(path))
{
    ...
}
Now in 6.15
#include <utility/YiDir.h>

if (CYIDir::CreateDirectory(path))
{
    ...
}

Changes to CYIDir::AreDirectoryOperationsSupported

We’ve renamed the function CYIDir::AreDirectoryOperationsSupported to CYIDir::AreDirectoryOperationsSupportedIn. This function now provides better granularity. Previously, the function was called without arguments, but now the function takes a path to check as input.

Prior to 6.15
if (CYIDir::AreDirectoryOperationsSupported())
{
    ...
}
Now in 6.15
if (CYIDir::AreDirectoryOperationsSupportedIn(path))
{
    ...
}

Changes to CYIApp::GetDataPath

We’ve renamed the function CYIApp::GetDataPath() to CYIApp::GetPersistentPath(). The path’s purpose and requirements are now better reflected in the name. Starting with 6.15, avoid writing to the persistent path too often. Writing too often wears out the storage medium of some platforms supported by You.i Platform. If frequent writes are required, consider using CYIApp::GetCachePath() instead.

Prior to 6.15
CYIString persistentPath = CYIAppContext::GetInstance()->GetDataPath();
Now in 6.15
CYIString persistentPath = CYIAppContext::GetInstance()->GetPersistentPath();
// OR
CYIString cachePath = CYIAppContext::GetInstance()->GetCachePath();

Changes to CYIFocusSearchOptions::SearchPredicate

We’ve changed the type definition for CYIFocusSearchOptions::SearchPredicate from a function pointer to std::function. This changes allows more flexibility when providing a SearchPredicate for focus searches. In most cases, no code changes are required. However, if a function pointer was previously being converted to CYIFocusSearchOptions automatically, it must now be wrapped in a constructor call.

Prior to 6.15
static bool Predicate(const CYISceneView *pView)
{
    ...
}

pView->RequestFocus(CYIFocus::Direction::Forward, CYIFocus::FocusRootRule::DescendantsUpdateContext, CYIAABB(), Predicate);
Now in 6.15
static bool Predicate(const CYISceneView *pView)
{
    ...
}

pView->RequestFocus(CYIFocus::Direction::Forward, CYIFocus::FocusRootRule::DescendantsUpdateContext, CYIAABB(), CYIFocusSearchOptions(Predicate));

Changes to CYITextureView Android thread processing API

We’ve protected a few Java public APIs on CYITextureView related to thread processing. We’ve replaced them with new public APIs available in CYIThreadUtilities. The changed APIs and their replacements are:

API prior to 6.15 API in 6.15
CYITextureView.postToEngineQueue(Runnable) CYIThreadUtilities.runAsyncOnYouiEngineMainThread(Runnable)
CYITextureView.postToEngineQueue(Runnable, EnginePriority) CYIThreadUtilities.runAsyncOnYouiEngineMainThread(Runnable, EnginePriority)
CYITextureView.processEngineQueue(Runnable runnable) CYIThreadUtilities.runSyncOnYouiEngineMainThread(Runnable)

These replacements provide identical behavior to the previous APIs on CYITextureView.

In some cases, we recommend changing CYITextureView.postToEngineQueue calls to CYIThreadUtilities.runOnYouiEngineMainThread(Runnable) instead of CYIThreadUtilities.runAsyncOnYouiEngineMainThread(Runnable).

CYIThreadUtilities.runOnYouiEngineMainThread executes Runnable synchronously on the current thread if the thread is the main You.i Platform thread, and CYIThreadUtilities.runAsyncOnYouiEngineMainThread runs Runnable asynchronously, regardless of the calling thread.

Prior to 6.15
CYITextureView.postToEngineQueue(new Runnable() {
    public void run() {
        // Do something with priority asynchronously on the You.i Platform main thread.
    }
}, CYITextureView.EnginePriority.High);
Now in 6.15
CYIThreadUtilities.runAsyncOnYouiEngineMainThread(new Runnable() {
    public void run() {
        // Do something with priority asynchronously on the You.i Platform main thread.
    }
}, CYIThreadUtilities.EnginePriority.High);

Tizen application multi-tasking support disabled

Because the new Tizen NaCl elementary stream video player doesn’t currently support backgrounding and foregrounding, we’ve temporarily disabled Tizen application multi-tasking support by default. You can re-enable multi-tasking support at generation time with the CMake argument YI_TIZEN_MULTITASKING_ENABLED.

Changes to Tizen logging

In previous releases, logging to an HTML textarea element caused load times on low-end Tizen devices to be in the range of minutes. This release provides an improved on-screen logging system for Tizen. We now provide on-screen logging only during the initial startup process, before the C++ code has loaded. Note the following additional changes to logging behavior for Tizen apps:

  • We’ve removed the Tizen log window Dev Panel widget. We recommend using the network logger instead.
  • We’ve removed the Tizen log sink so that C++ log messages are no longer transmitted to the Tizen web context.
  • We’ve added a progress bar to debug builds at the top of the screen to show the NaCl module loading progress, rather than logging it.
  • The on-screen logs area now uses div elements instead of a textarea to mitigate logging-related performance issues.
  • The logs area is now destroyed once the NaCl module loads successfully.
  • The on-screen logs area is now scrollable with the up and down buttons on your remote control.
  • A new app config script for Tizen applications allows customization of some configuration parameters.
  • We’ve added global tizennaclloaded, tizenerroroverlayvisible, and tizenerroroverlayhidden events.
  • We’ve removed the default Tizen app styles.css stylesheet, since all styles are now set programmatically.
  • Running a Tizen application with the wrong architecture now displays the error screen, rather than just logging a message.

Changes to PlayReady custom data string encoding on Universal Windows Platform (UWP)

The UWP video player no longer Base64-encodes the custom data string for PlayReady license acquisition. If you’re implementing PlayReady DRM on UWP and the license server requires Base64-encoded custom data, you must Base64-encode the string prior to calling the CYIPlayReadyDRMConfiguration::SetLicenseAcquisitionCustomData method.

Prior to 6.15: Player API’s caller code
auto pPlayReadyConfig = std::make_unique<CYIPlayReadyDRMConfiguration>();
pPlayReadyConfig->SetLicenseAcquisitionCustomData("customdataasset");
Now in 6.15: Player API’s caller code
#include <utility/YiStringEncoding.h> // for YiBase64Encode used below

auto pPlayReadyConfig = std::make_unique<CYIPlayReadyDRMConfiguration>();
pPlayReadyConfig->SetLicenseAcquisitionCustomData(YiBase64Encode("customdataasset"));

React Native Applications

React Native Breaking Changes

We’ve made changes to the FairPlayerDrmHandler module for React Native applications. FairPlay content may require multiple DRM requests, so a unique identifier is now supplied to tie the responses to the native player, since the order of requests and responses aren’t guaranteed to be in sequential order.

Calls into DRM_REQUEST_URL_AVAILABLE and SPC_MESSAGE_AVAILABLE now contain a unique drmRequestId, which must be sent back in the responses to the FairPlayDrmHandler methods.

Prior to 6.15
FairPlayDrmHandler.addEventListener('DRM_REQUEST_URL_AVAILABLE', (args) => {
    const drmRequestUrl = args.drmRequestUrl;
    const tag = args.tag;

    // On successful creation of the applicationIdentifier and  contentIdentifier.
    FairPlayDrmHandler.requestSPCMessage(tag, applicationIdentifier, contentIdentifier);

    // Or on a failure.
    FairPlayDrmHandler.notifyFailure(tag);
});

FairPlayDrmHandler.addEventListener('SPC_MESSAGE_AVAILABLE', (args) => {
    const spcMessage = base64.decode(args.spcMessage);
    const tag = args.tag;

    // On successful creation of the ckcMessage.
    FairPlayDrmHandler.provideCKCMessage(tag, ckcMessage);

    // Or on a failure.
    FairPlayDrmHandler.notifyFailure(tag);
});
Now in 6.15
FairPlayDrmHandler.addEventListener('DRM_REQUEST_URL_AVAILABLE', (args) => {
    const drmRequestUrl = args.drmRequestUrl;
    const tag = args.tag;
    const drmRequestId = args.drmRequestId;

    // On successful creation of the applicationIdentifier and  contentIdentifier.
    FairPlayDrmHandler.requestSPCMessage(tag, drmRequestId, applicationIdentifier, contentIdentifier);

    // Or on a failure.
    FairPlayDrmHandler.notifyFailure(tag, drmRequestId);
});

FairPlayDrmHandler.addEventListener('SPC_MESSAGE_AVAILABLE', (args) => {
    const spcMessage = base64.decode(args.spcMessage);
    const tag = args.tag;
    const drmRequestId = args.drmRequestId;

    // On successful creation of the ckcMessage.
    FairPlayDrmHandler.provideCKCMessage(tag, drmRequestId, ckcMessage);

    // Or on a failure.
    FairPlayDrmHandler.notifyFailure(tag, drmRequestId);
});

Roku Cloud Applications

Roku Cloud Breaking Changes

Changes to the Crash Handler

We’ve made changes to crash handling on Roku Cloud, as part of ongoing work to improve crash handling support in You.i Platform. Previously, you had to handle crashes in the application. Now, crashes are handled within You.i Platform. If you want to handle crashes in your app, you must add the YI_PLATFORM_CRASHHANDLER_LEGACY definition to your application. For example:

target_compile_definitions(${PROJECT_NAME}
    PUBLIC YI_PLATFORM_CRASHHANDLER_LEGACY
)

Client message definitions are now in JSON format

We’ve changed the format for error and information dialog definitions from XML to JSON format. Previously, these dialogs were defined in resource/messages.xml. Now, they’re defined in resource/dialogDefs.json.

The example below shows a message in messages.xml that has been converted to JSON format in dialogDefs.json.

Prior to 6.15
  <sessionTimeoutMessage>
    <description>Because of inactivity, your session has timed out and is no longer active.</description>
    <title>Session Timeout</title>
    <button>OK</button>
    <instruction>Click OK to return to the home screen</instruction>
  </sessionTimeoutMessage>
Now in 6.15
  "sessionTimeoutMessage": {
    "description": "Because of inactivity, your session has timed out and is no longer active.",
    "title": "Session Timeout",
    "buttons": [ "OK" ],
    "details": ["Click OK to return to the home screen"]
  },

To learn more, see Customizing Error and Info Dialogs.