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.
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.
You.i Labs castLabs
You.i castLabs PlayStation
You.i castLabs LG ES
You.i castLabs webOS ES
Samsung::NaClPlayer::MediaPlayer
You.i castLabs Tizen NaCl ES
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;
CYIAppLifeCycleBridge
removedWe’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.
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
pAppLifeCycleBridge->BackgroundEntered.Connect(*this, &MySignalHandler::OnBackgroundEntered);
pAppLifeCycleBridge->ForegroundEntered.Connect(*this, &MySignalHandler::OnForegroundEntered);
}
CYIApp *pApp = CYIAppContext::GetInstance()->GetApp();
if (pApp)
{
pApp->BackgroundEntered.Connect(*this, &MySignalHandler::OnBackgroundEntered);
pApp->ForegroundEntered.Connect(*this, &MySignalHandler::OnForegroundEntered);
}
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
pAppLifeCycleBridge->OnBackgroundEntered();
}
...
CYIAppLifeCycleBridge *pAppLifeCycleBridge = CYIAppLifeCycleBridgeLocator::GetAppLifeCycleBridge();
if (pAppLifeCycleBridge)
{
pAppLifeCycleBridge->OnForegroundEntered();
}
CYIApp *g_pApp; // Assuming the CYIApp is accessible in a global context
if (g_pApp)
{
g_pApp->OnBackgroundEntered();
}
...
if (g_pApp)
{
g_pApp->OnForegroundEntered();
}
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);
CYICrashHandler::crashReportPostData.url = myUrl;
CYICrashHandler::PostData postData = CYICrashHandler::GetCrashReportPostData();
postData.url = myUrl;
CYICrashHandler::SetCrashReportPostData(postData);
We’ve moved GetDefaultFontFamilyForFontType
, GetFontIdForFontType
, and SetFontIdForFontType
methods to CYIClosedCaptionsStyleManager
.
This change affects all applications that use closed caption font utilities.
CYIString fontFamily = CYIClosedCaptionsStylingBridge::GetDefaultFontFamilyForFontType(fontType);
ssize_t fontId = CYIClosedCaptionsStylingBridge::GetFontIdForFontType(fontType);
bool success = CYIClosedCaptionsStylingBridge::SetFontIdForFontType(fontType, fontId);
CYIString fontFamily = CYIClosedCaptionsStyleManager::GetDefaultFontFamilyForFontType(fontType);
ssize_t fontId = CYIClosedCaptionsStyleManager::GetFontIdForFontType(fontType);
bool success = CYIClosedCaptionsStyleManager::SetFontIdForFontType(fontType, fontId);
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.
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.
CYIApp *pApp;
...
pApp->SetDataPath(dataPath);
CYIApp *pApp;
...
pApp->SetDataPath(dataPath);
pApp->SetCachePath(dataPath);
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
.
CYITextEditView *pTextEditView;
pTextEditView->SetInputType(CYIKeyboardInputBridge::InputType::Password);
CYITextEditView *pTextEditView;
pTextEditView->SetInputModifiers(CYIKeyboardInputBridge::InputModifiers::MaskInput);
CYITextEditView *pTextEditView;
pTextEditView->SetInputType(CYIKeyboardInputBridge::InputType::TextWithoutSuggestions);
CYITextEditView *pTextEditView;
pTextEditView->SetInputModifiers(CYIKeyboardInputBridge::InputModifiers::NoSuggestions);
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
.
CYIPasswordTextEditView *pPasswordTextEditView;
CYITextEditView *pTextEditView;
pTextEditView->EnablePasswordMode(true);
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.
#include <deprecated/YiUtilities.h>
if (YiMakeDirectory(path))
{
...
}
#include <utility/YiDir.h>
if (CYIDir::CreateDirectory(path))
{
...
}
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.
if (CYIDir::AreDirectoryOperationsSupported())
{
...
}
if (CYIDir::AreDirectoryOperationsSupportedIn(path))
{
...
}
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.
CYIString persistentPath = CYIAppContext::GetInstance()->GetDataPath();
CYIString persistentPath = CYIAppContext::GetInstance()->GetPersistentPath();
// OR
CYIString cachePath = CYIAppContext::GetInstance()->GetCachePath();
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.
static bool Predicate(const CYISceneView *pView)
{
...
}
pView->RequestFocus(CYIFocus::Direction::Forward, CYIFocus::FocusRootRule::DescendantsUpdateContext, CYIAABB(), Predicate);
static bool Predicate(const CYISceneView *pView)
{
...
}
pView->RequestFocus(CYIFocus::Direction::Forward, CYIFocus::FocusRootRule::DescendantsUpdateContext, CYIAABB(), CYIFocusSearchOptions(Predicate));
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.
CYITextureView.postToEngineQueue(new Runnable() {
public void run() {
// Do something with priority asynchronously on the You.i Platform main thread.
}
}, CYITextureView.EnginePriority.High);
CYIThreadUtilities.runAsyncOnYouiEngineMainThread(new Runnable() {
public void run() {
// Do something with priority asynchronously on the You.i Platform main thread.
}
}, CYIThreadUtilities.EnginePriority.High);
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
.
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:
div
elements instead of a textarea
to mitigate logging-related performance issues.tizennaclloaded
, tizenerroroverlayvisible
, and tizenerroroverlayhidden
events.styles.css
stylesheet, since all styles are now set programmatically.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.
auto pPlayReadyConfig = std::make_unique<CYIPlayReadyDRMConfiguration>();
pPlayReadyConfig->SetLicenseAcquisitionCustomData("customdataasset");
#include <utility/YiStringEncoding.h> // for YiBase64Encode used below
auto pPlayReadyConfig = std::make_unique<CYIPlayReadyDRMConfiguration>();
pPlayReadyConfig->SetLicenseAcquisitionCustomData(YiBase64Encode("customdataasset"));
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.
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);
});
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);
});
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
)
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
.
<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>
"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.