PVR_ERROR CPVRClients::GetTimerTypes(CPVRTimerTypes& results) const { PVR_ERROR error(PVR_ERROR_NO_ERROR); PVR_CLIENTMAP clients; GetConnectedClients(clients); for (const auto &clientEntry : clients) { CPVRTimerTypes types; PVR_ERROR currentError = clientEntry.second->GetTimerTypes(types); if (currentError != PVR_ERROR_NOT_IMPLEMENTED && currentError != PVR_ERROR_NO_ERROR) { CLog::Log(LOGERROR, "PVR - %s - cannot get timer types from client '%d': %s",__FUNCTION__, clientEntry.first, CPVRClient::ToString(currentError)); error = currentError; } else { for (const auto &typesEntry : types) results.push_back(typesEntry); } } return error; }
bool CPVRClient::GetAddonProperties(void) { std::string strBackendName, strConnectionString, strFriendlyName, strBackendVersion, strBackendHostname; PVR_ADDON_CAPABILITIES addonCapabilities; CPVRTimerTypes timerTypes; /* get the capabilities */ memset(&addonCapabilities, 0, sizeof(addonCapabilities)); PVR_ERROR retVal = m_struct.GetAddonCapabilities(&addonCapabilities); if (retVal != PVR_ERROR_NO_ERROR) { CLog::Log(LOGERROR, "PVR - couldn't get the capabilities for add-on '%s'. Please contact the developer of this add-on: %s", GetFriendlyName().c_str(), Author().c_str()); return false; } /* get the name of the backend */ strBackendName = m_struct.GetBackendName(); /* get the connection string */ strConnectionString = m_struct.GetConnectionString(); /* display name = backend name:connection string */ strFriendlyName = StringUtils::Format("%s:%s", strBackendName.c_str(), strConnectionString.c_str()); /* backend version number */ strBackendVersion = m_struct.GetBackendVersion(); /* backend hostname */ strBackendHostname = m_struct.GetBackendHostname(); /* timer types */ if (addonCapabilities.bSupportsTimers) { std::unique_ptr<PVR_TIMER_TYPE[]> types_array(new PVR_TIMER_TYPE[PVR_ADDON_TIMERTYPE_ARRAY_SIZE]); int size = PVR_ADDON_TIMERTYPE_ARRAY_SIZE; PVR_ERROR retval = m_struct.GetTimerTypes(types_array.get(), &size); if (retval == PVR_ERROR_NOT_IMPLEMENTED) { // begin compat section CLog::Log(LOGWARNING, "%s - Addon %s does not support timer types. It will work, but not benefit from the timer features introduced with PVR Addon API 2.0.0", __FUNCTION__, strFriendlyName.c_str()); // Create standard timer types (mostly) matching the timer functionality available in Isengard. // This is for migration only and does not make changes to the addons obsolete. Addons should // work and benefit from some UI changes (e.g. some of the timer settings dialog enhancements), // but all old problems/bugs due to static attributes and values will remain the same as in // Isengard. Also, new features (like epg search) are not available to addons automatically. // This code can be removed once all addons actually support the respective PVR Addon API version. size = 0; // manual one time memset(&types_array[size], 0, sizeof(types_array[size])); types_array[size].iId = size + 1; types_array[size].iAttributes = PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE | PVR_TIMER_TYPE_SUPPORTS_CHANNELS | PVR_TIMER_TYPE_SUPPORTS_START_TIME | PVR_TIMER_TYPE_SUPPORTS_END_TIME | PVR_TIMER_TYPE_SUPPORTS_PRIORITY | PVR_TIMER_TYPE_SUPPORTS_LIFETIME | PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS; ++size; // manual timer rule memset(&types_array[size], 0, sizeof(types_array[size])); types_array[size].iId = size + 1; types_array[size].iAttributes = PVR_TIMER_TYPE_IS_MANUAL | PVR_TIMER_TYPE_IS_REPEATING | PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE | PVR_TIMER_TYPE_SUPPORTS_CHANNELS | PVR_TIMER_TYPE_SUPPORTS_START_TIME | PVR_TIMER_TYPE_SUPPORTS_END_TIME | PVR_TIMER_TYPE_SUPPORTS_PRIORITY | PVR_TIMER_TYPE_SUPPORTS_LIFETIME | PVR_TIMER_TYPE_SUPPORTS_FIRST_DAY | PVR_TIMER_TYPE_SUPPORTS_WEEKDAYS | PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS; ++size; if (addonCapabilities.bSupportsEPG) { // One-shot epg-based memset(&types_array[size], 0, sizeof(types_array[size])); types_array[size].iId = size + 1; types_array[size].iAttributes = PVR_TIMER_TYPE_SUPPORTS_ENABLE_DISABLE | PVR_TIMER_TYPE_REQUIRES_EPG_TAG_ON_CREATE | PVR_TIMER_TYPE_SUPPORTS_CHANNELS | PVR_TIMER_TYPE_SUPPORTS_START_TIME | PVR_TIMER_TYPE_SUPPORTS_END_TIME | PVR_TIMER_TYPE_SUPPORTS_PRIORITY | PVR_TIMER_TYPE_SUPPORTS_LIFETIME | PVR_TIMER_TYPE_SUPPORTS_RECORDING_FOLDERS; ++size; } retval = PVR_ERROR_NO_ERROR; // end compat section } if (retval == PVR_ERROR_NO_ERROR) { timerTypes.reserve(size); for (int i = 0; i < size; ++i) { if (types_array[i].iId == PVR_TIMER_TYPE_NONE) { CLog::Log(LOGERROR, "PVR - invalid timer type supplied by add-on '%s'. Please contact the developer of this add-on: %s", GetFriendlyName().c_str(), Author().c_str()); continue; } if (strlen(types_array[i].strDescription) == 0) { int id; if (types_array[i].iAttributes & PVR_TIMER_TYPE_IS_REPEATING) { id = (types_array[i].iAttributes & PVR_TIMER_TYPE_IS_MANUAL) ? 822 // "Timer rule" : 823; // "Timer rule (guide-based)" } else { id = (types_array[i].iAttributes & PVR_TIMER_TYPE_IS_MANUAL) ? 820 // "One time" : 821; // "One time (guide-based) } std::string descr(g_localizeStrings.Get(id)); strncpy(types_array[i].strDescription, descr.c_str(), descr.size()); } timerTypes.push_back(CPVRTimerTypePtr(new CPVRTimerType(types_array[i], m_iClientId))); } } else { CLog::Log(LOGERROR, "PVR - couldn't get the timer types for add-on '%s'. Please contact the developer of this add-on: %s", GetFriendlyName().c_str(), Author().c_str()); return false; } } /* update the members */ m_strBackendName = strBackendName; m_strConnectionString = strConnectionString; m_strFriendlyName = strFriendlyName; m_strBackendVersion = strBackendVersion; m_addonCapabilities = addonCapabilities; m_strBackendHostname = strBackendHostname; m_timertypes = timerTypes; return true; }