size_t IDispatchAPI::getMemberCount() const { if (!host->isMainThread()) { return host->CallOnMainThread(boost::bind(&IDispatchAPI::getMemberCount, this)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->getMemberCount(); else return 0; } HRESULT hr; DISPID dispid; size_t count(0); CComQIPtr<IDispatchEx> dispex(m_obj); if (!dispex) { return -1; } hr = dispex->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid); while (SUCCEEDED(hr)) { count++; hr = dispex->GetNextDispID(fdexEnumAll, dispid, &dispid); } return count; }
void IDispatchAPI::getMemberNames(std::vector<std::string> &nameVector) const { if (!host->isMainThread()) { typedef void (FB::JSAPI::*getMemberNamesType)(std::vector<std::string> *nameVector) const; host->CallOnMainThread(boost::bind((getMemberNamesType)&FB::JSAPI::getMemberNames, this, &nameVector)); return; } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->getMemberNames(nameVector); return; } CComQIPtr<IDispatchEx> dispatchEx(m_obj); if (!dispatchEx) { throw FB::script_error("Cannot enumerate members; IDispatchEx not supported"); } DISPID dispid = DISPID_STARTENUM; while (dispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid) != S_FALSE) { if (dispid < 0) { continue; } CComBSTR memberName; if (SUCCEEDED(dispatchEx->GetMemberName(dispid, &memberName))) { std::wstring name(memberName); nameVector.push_back(FB::wstring_to_utf8(name)); } } }
void IDispatchAPI::getMemberNames(std::vector<std::string> &nameVector) const { if (!host->isMainThread()) { typedef void (FB::JSAPI::*getMemberNamesType)(std::vector<std::string> *nameVector) const; host->CallOnMainThread(boost::bind((getMemberNamesType)&FB::JSAPI::getMemberNames, this, &nameVector)); return; } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->getMemberNames(nameVector); return; } HRESULT hr; DISPID dispid; CComQIPtr<IDispatchEx> dispex(m_obj); if (!dispex) { throw FB::script_error("Cannot enumerate members; IDispatchEx not supported"); } hr = dispex->GetNextDispID(fdexEnumAll, DISPID_STARTENUM, &dispid); while (SUCCEEDED(hr) && dispid > -1) { CComBSTR curName; hr = dispex->GetMemberName(dispid, &curName); std::wstring wStr(curName); nameVector.push_back(FB::wstring_to_utf8(wStr)); hr = dispex->GetNextDispID(fdexEnumAll, dispid, &dispid); } }
// Methods to manage properties on the API FB::variant NPObjectAPI::GetProperty(const std::string& propertyName) { if (m_browser.expired()) return FB::FBVoid(); NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind((FB::GetPropertyType)&JSAPI::GetProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->GetProperty(propertyName); else return false; } NPVariant retVal; if (!browser->GetProperty(obj, browser->GetStringIdentifier(propertyName.c_str()), &retVal)) { browser->ReleaseVariantValue(&retVal); throw script_error(propertyName.c_str()); } else { FB::variant ret = browser->getVariant(&retVal); browser->ReleaseVariantValue(&retVal); return ret; } }
size_t IDispatchAPI::getMemberCount() const { if (!host->isMainThread()) { return host->CallOnMainThread(boost::bind(&IDispatchAPI::getMemberCount, this)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (!tmp) { // TODO: check if this should be -1 return 0; } return tmp->getMemberCount(); } CComQIPtr<IDispatchEx> dispatchEx(m_obj); if (!dispatchEx) { return -1; } size_t count = 0; DISPID dispid = DISPID_STARTENUM; while (dispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid) != S_FALSE) { if (dispid >= 0) { ++count; } } return count; }
// Methods to manage properties on the API FB::variant IDispatchAPI::GetProperty(const std::string& propertyName) { if (!host->isMainThread()) { return host->CallOnMainThread(boost::bind((FB::GetPropertyType)&IDispatchAPI::GetProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->GetProperty(propertyName); else return false; } DISPPARAMS params; params.cArgs = 0; params.cNamedArgs = 0; VARIANT res; EXCEPINFO eInfo; HRESULT hr = E_NOTIMPL; CComQIPtr<IDispatchEx> dispex(m_obj); if (dispex) { hr = dispex->InvokeEx(getIDForName(FB::utf8_to_wstring(propertyName)), LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &res, &eInfo, NULL); } else { hr = m_obj->Invoke(getIDForName(FB::utf8_to_wstring(propertyName)), IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &res, NULL, NULL); } if (SUCCEEDED(hr)) { return m_browser->getVariant(&res); } else { throw FB::script_error("Could not get property"); } }
void NPObjectAPI::getMemberNames(std::vector<std::string> &nameVector) const { if (m_browser.expired()) return; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { typedef void (FB::JSAPI::*getMemberNamesType)(std::vector<std::string> *nameVector) const; browser->CallOnMainThread(boost::bind((getMemberNamesType)&FB::JSAPI::getMemberNames, this, &nameVector)); return; } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->getMemberNames(nameVector); return; } NPIdentifier *idArray(NULL); uint32_t count; browser->Enumerate(obj, &idArray, &count); for (uint32_t i = 0; i < count; i++) { nameVector.push_back(browser->StringFromIdentifier(idArray[i])); } browser->MemFree(idArray); }
FB::variant FB::JSFunction::exec( const std::vector<variant>& args ) { FB::JSAPIPtr api = m_apiWeak.lock(); if (!api) throw new FB::script_error("Invalid JSAPI object"); // Force calls to use the zone this function was created with FB::scoped_zonelock _l(api, getZone()); return api->Invoke(m_methodName, args); }
void IDispatchAPI::SetProperty(const std::string& propertyName, const FB::variant& value) { if (m_browser.expired() || m_obj.expired()) return; ActiveXBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { browser->CallOnMainThread(boost::bind((FB::SetPropertyType)&IDispatchAPI::SetProperty, this, propertyName, value)); return; } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->SetProperty(propertyName, value); return; } DISPID dispId = getIDForName(FB::utf8_to_wstring(propertyName)); if (dispId == DISPID_UNKNOWN) { throw FB::script_error("Could not set property"); } CComVariant arg[1]; VARIANTARG rawArg[1]; DISPID namedArg[1]; DISPPARAMS params; params.cArgs = 1; params.cNamedArgs = 1; params.rgdispidNamedArgs = namedArg; params.rgvarg = rawArg; browser->getComVariant(&arg[0], value); rawArg[0] = arg[0]; namedArg[0] = DISPID_PROPERTYPUT; HRESULT hr; CComVariant result; CComExcepInfo exceptionInfo; CComQIPtr<IDispatchEx> dispatchEx(getIDispatch()); if (dispatchEx) { hr = dispatchEx->InvokeEx(dispId, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF, ¶ms, &result, &exceptionInfo, NULL); if (hr == DISP_E_MEMBERNOTFOUND) { hr = dispatchEx->InvokeEx(dispId, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, NULL, &exceptionInfo, NULL); } } else { hr = getIDispatch()->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, &result, &exceptionInfo, NULL); } if (FAILED(hr)) { throw FB::script_error("Could not set property"); } }
void IDispatchAPI::SetProperty(int idx, const FB::variant& value) { if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->SetProperty(idx, value); } FB::variant sIdx(idx); SetProperty(sIdx.convert_cast<std::string>(), value); }
void RemoteMediaStream::AddTrack(FB::JSAPIPtr pTrack) { if("video" == pTrack->GetProperty("kind").convert_cast<std::string>()) { m_videoTracks.push_back(FB::variant(pTrack)); } else if("audio" == pTrack->GetProperty("kind").convert_cast<std::string>()) { m_audioTracks.push_back(FB::variant(pTrack)); } }
// Methods to manage properties on the API FB::variant IDispatchAPI::GetProperty(const std::string& propertyName) { if (m_browser.expired() || m_obj.expired()) return FB::FBVoid(); ActiveXBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind((FB::GetPropertyType)&IDispatchAPI::GetProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (!tmp) { return false; } return tmp->GetProperty(propertyName); } DISPID dispId = getIDForName(FB::utf8_to_wstring(propertyName)); if (dispId == DISPID_UNKNOWN && propertyName != "toString") { throw FB::script_error("Could not get property"); } // TODO: how can toString == DISPID_UNKNOWN work? DISPPARAMS params; params.cArgs = 0; params.cNamedArgs = 0; HRESULT hr; CComVariant result; CComExcepInfo exceptionInfo; try { CComQIPtr<IDispatchEx> dispatchEx(getIDispatch()); if (dispatchEx) { hr = dispatchEx->InvokeEx(dispId, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &result, &exceptionInfo, NULL); } else { hr = getIDispatch()->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &result, &exceptionInfo, NULL); } if (FAILED(hr)) { throw FB::script_error("Could not get property"); } return browser->getVariant(&result); } catch (...) { throw FB::script_error("Could not get property"); } }
FB::variant NPObjectAPI::GetProperty(int idx) { if (m_browser.expired()) return FB::FBVoid(); NpapiBrowserHostPtr browser(getHost()); std::string strIdx(boost::lexical_cast<std::string>(idx)); if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->GetProperty(idx); } return GetProperty(strIdx); }
void NPObjectAPI::RemoveProperty(int idx) { if (m_browser.expired()) return; NpapiBrowserHostPtr browser(getHost()); std::string strIdx(boost::lexical_cast<std::string>(idx)); if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->RemoveProperty(idx); } return RemoveProperty(strIdx); }
bool NPObjectAPI::HasProperty(int idx) const { if (m_browser.expired()) return false; NpapiBrowserHostPtr browser(getHost()); if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->HasProperty(idx); else return false; } return browser->HasProperty(obj, browser->GetIntIdentifier(idx)); }
boost::shared_ptr<FB::JSAPISecureProxy> FB::JSAPISecureProxy::create( const FB::SecurityZone zone, const FB::JSAPIPtr &inner ) { boost::shared_ptr<FB::JSAPISecureProxy> ptr(new FB::JSAPISecureProxy(zone, inner)); inner->registerProxy(ptr); // This is necessary because you can't use shared_from_this in the constructor return ptr; }
void GCPAPI::set_source(const FB::JSAPIPtr& stream) { m_srcStream = stream; if(NULL != stream.get()) { std::string msg = m_htmlId.convert_cast<std::string>(); msg += ": Setting video track renderer..."; FBLOG_INFO_CUSTOM("GCAPAPI::set_source", msg); if("localPlayer" == m_htmlId.convert_cast<std::string>()) { if(NULL != getPlugin()->Renderer()) { getPlugin()->Renderer()->SetPreviewMode(true); (GoCast::RtcCenter::Instance())->SetLocalVideoTrackRenderer(getPlugin()->Renderer()); } } else { if(NULL != getPlugin()->Renderer()) { (GoCast::RtcCenter::Instance())->SetRemoteVideoTrackRenderer(m_htmlId.convert_cast<std::string>(), getPlugin()->Renderer()); } } } }
// Methods to manage methods on the API FB::variant NPObjectAPI::Invoke(const std::string& methodName, const std::vector<FB::variant>& args) { if (m_browser.expired()) return false; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind((FB::InvokeType)&NPObjectAPI::Invoke, this, methodName, args)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->Invoke(methodName, args); else return false; } NPVariant retVal; // Convert the arguments to NPVariants boost::scoped_array<NPVariant> npargs(new NPVariant[args.size()]); for (unsigned int i = 0; i < args.size(); i++) { browser->getNPVariant(&npargs[i], args[i]); } bool res = false; // Invoke the method ("" means invoke default method) if (methodName.size() > 0) { res = browser->Invoke(obj, browser->GetStringIdentifier(methodName.c_str()), npargs.get(), args.size(), &retVal); } else { res = browser->InvokeDefault(obj, npargs.get(), args.size(), &retVal); } // Free the NPVariants that we earlier allocated for (unsigned int i = 0; i < args.size(); i++) { browser->ReleaseVariantValue(&npargs[i]); } if (!res) { // If the method call failed, throw an exception browser->ReleaseVariantValue(&retVal); // Always release the return value! throw script_error(methodName.c_str()); } else { FB::variant ret = browser->getVariant(&retVal); browser->ReleaseVariantValue(&retVal); // Always release the return value! return ret; } }
bool IDispatchAPI::HasMethod(const std::string& methodName) const { if (!host->isMainThread()) { typedef bool (IDispatchAPI::*curtype)(const std::string&) const; return host->CallOnMainThread(boost::bind((curtype)&IDispatchAPI::HasMethod, this, methodName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->HasMethod(methodName); else return false; } // This will actually just return true if the specified member exists; IDispatch doesn't really // differentiate further than that return getIDForName(FB::utf8_to_wstring(methodName)) != -1 && !HasProperty(methodName); }
bool IDispatchAPI::HasProperty(const std::string& propertyName) const { if (m_browser.expired() || m_obj.expired()) return false; ActiveXBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { typedef bool (IDispatchAPI::*HasPropertyType)(const std::string&) const; return browser->CallOnMainThread(boost::bind((HasPropertyType)&IDispatchAPI::HasProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (!tmp) { return false; } return tmp->HasProperty(propertyName); } DISPID dispId = getIDForName(FB::utf8_to_wstring(propertyName)); if (dispId == DISPID_UNKNOWN && propertyName != "toString") { return false; } DISPPARAMS params; params.cArgs = 0; params.cNamedArgs = 0; // the only way to find out if the property actually exists or not is to try to get it HRESULT hr; CComVariant result; CComExcepInfo exceptionInfo; try { CComQIPtr<IDispatchEx> dispatchEx(getIDispatch()); if (dispatchEx) { hr = dispatchEx->InvokeEx(dispId, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &result, &exceptionInfo, NULL); } else { hr = getIDispatch()->Invoke(dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &result, &exceptionInfo, NULL); } return SUCCEEDED(hr); } catch (...) { return false; } }
bool IDispatchAPI::HasEvent(const std::string& eventName) const { if (!host->isMainThread()) { typedef bool (IDispatchAPI::*HasEventType)(const std::string&) const; return host->CallOnMainThread(boost::bind((HasEventType)&IDispatchAPI::HasEvent, this, eventName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (!tmp) { return false; } return tmp->HasEvent(eventName); } // This will actually just return true if the specified member exists; IDispatch doesn't really // differentiate further than that return getIDForName(FB::utf8_to_wstring(eventName)) != -1; }
bool NPObjectAPI::HasProperty(const std::string& propertyName) const { if (m_browser.expired()) return false; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { typedef bool (NPObjectAPI::*curtype)(const std::string&) const; return browser->CallOnMainThread(boost::bind((curtype)&NPObjectAPI::HasProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->HasProperty(propertyName); else return false; } return browser->HasProperty(obj, browser->GetStringIdentifier(propertyName.c_str())); }
void NPObjectAPI::RemoveProperty(const std::string& propertyName) { if (m_browser.expired()) return; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind((FB::RemovePropertyType)&JSAPI::RemoveProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->RemoveProperty(propertyName); else return /*false*/; } if (!browser->RemoveProperty(obj, browser->GetStringIdentifier(propertyName.c_str()))) { throw script_error(propertyName.c_str()); } }
FB::variant NPObjectAPI::Construct( const FB::VariantList& args ) { if (m_browser.expired()) return false; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind((FB::ConstructType)&NPObjectAPI::Construct, this, args)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->Construct(args); else return false; } NPVariant retVal; // Convert the arguments to NPVariants boost::scoped_array<NPVariant> npargs(new NPVariant[args.size()]); for (unsigned int i = 0; i < args.size(); i++) { browser->getNPVariant(&npargs[i], args[i]); } bool res = false; // construct res = browser->Construct(obj, npargs.get(), args.size(), &retVal); // Free the NPVariants that we earlier allocated for (unsigned int i = 0; i < args.size(); i++) { browser->ReleaseVariantValue(&npargs[i]); } if (!res) { // If the method call failed, throw an exception throw script_error("constructor"); } else { FB::variant ret = browser->getVariant(&retVal); browser->ReleaseVariantValue(&retVal); // Always release the return value! return ret; } }
bool IDispatchAPI::HasProperty(const std::string& propertyName) const { if (!host->isMainThread()) { typedef bool (IDispatchAPI::*HasPropertyType)(const std::string&) const; return host->CallOnMainThread(boost::bind((HasPropertyType)&IDispatchAPI::HasProperty, this, propertyName)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->HasProperty(propertyName); else return false; } DISPID id = getIDForName(FB::utf8_to_wstring(propertyName)); if (id == -1 && propertyName != "toString") return false; DISPPARAMS params; params.cArgs = 0; params.cNamedArgs = 0; // The only way to find out if the property actually exists or not is to try to get it; VARIANT res; EXCEPINFO eInfo; HRESULT hr = E_NOTIMPL; CComQIPtr<IDispatchEx> dispex(m_obj); if (dispex) { hr = dispex->InvokeEx(id, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &res, &eInfo, NULL); } else { hr = m_obj->Invoke(getIDForName(FB::utf8_to_wstring(propertyName)), IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &res, NULL, NULL); } if (SUCCEEDED(hr)) { return true; } else { return false; } }
size_t NPObjectAPI::getMemberCount() const { if (m_browser.expired()) return 0; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind(&NPObjectAPI::getMemberCount, this)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) return tmp->getMemberCount(); else return 0; } NPIdentifier *idArray(NULL); uint32_t count; browser->Enumerate(obj, &idArray, &count); browser->MemFree(idArray); return (size_t)count; }
size_t IDispatchAPI::getMemberCount() const { if (m_browser.expired() || m_obj.expired()) return 0; ActiveXBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { return browser->CallOnMainThread(boost::bind(&IDispatchAPI::getMemberCount, this)); } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (!tmp) { // TODO: check if this should be -1 return 0; } return tmp->getMemberCount(); } size_t count = 0; try { CComQIPtr<IDispatchEx> dispatchEx(getIDispatch()); if (!dispatchEx) { return -1; } DISPID dispid = DISPID_STARTENUM; while (dispatchEx->GetNextDispID(fdexEnumAll, dispid, &dispid) != S_FALSE) { if (dispid >= 0) { ++count; } } } catch (...) {} return count; }
void NPObjectAPI::SetProperty(const std::string& propertyName, const FB::variant& value) { if (m_browser.expired()) return; NpapiBrowserHostPtr browser(getHost()); if (!browser->isMainThread()) { browser->CallOnMainThread(boost::bind((FB::SetPropertyType)&JSAPI::SetProperty, this, propertyName, value)); return; } if (is_JSAPI) { FB::JSAPIPtr tmp = inner.lock(); if (tmp) tmp->SetProperty(propertyName, value); return; } NPVariant val; browser->getNPVariant(&val, value); bool res = browser->SetProperty(obj, browser->GetStringIdentifier(propertyName.c_str()), &val); browser->ReleaseVariantValue(&val); if (!res) { throw script_error(propertyName.c_str()); } }
FB::variant GCPAPI::RemoveStream(const FB::JSAPIPtr& stream) { GoCast::RtcCenter* pCtr = GoCast::RtcCenter::Instance(); if(false == pCtr->Inited()) { std::string msg = m_htmlId.convert_cast<std::string>(); msg += ": Failed to init RtcCenter singleton"; FBLOG_ERROR_CUSTOM("GCPAPI::RemoveStream", msg); return false; } return pCtr->RemoveStream(m_htmlId.convert_cast<std::string>(), stream->GetProperty("label").convert_cast<std::string>()); }
BOOST_FOREACH(FB::JSAPIPtr ptr, m_retainedObjects) { // Notify each JSAPI object that we're shutting down ptr->shutdown(); }