/// <summary> /// Sets the current context. The specified context /// must be from <see cref="MediaBrowser.AvailableContexts"/>. /// If it is not, then nothing will happen. /// </summary> /// <param name="context"></param> public void SetContainerContext(IMediaContainer context) { if (this.SetContainerContext(this.m_Context, context)) { this.RefreshChildren(); } }
/// <summary> /// /// </summary> /// <param name="mo"></param> /// <param name="writeProperties"></param> /// <param name="shouldPrintResources"></param> /// <param name="writeResources"></param> /// <param name="writeDescNodes"></param> /// <param name="formatter"></param> /// <param name="data"></param> /// <param name="xmlWriter"></param> public static void WriteInnerXml( IUPnPMedia mo, DelegateWriteProperties writeProperties, DelegateShouldPrintResources shouldPrintResources, DelegateWriteResources writeResources, DelegateWriteDescNodes writeDescNodes, ToXmlFormatter formatter, ToXmlData data, XmlTextWriter xmlWriter ) { // When serializing the properties, resources, and desc nodes, // we must always write the inner xml, the value, and the element // declaration. Save the original values, print these portions // of the DIDL-Lite and then revert back. ToXmlData d2 = data; data.IncludeElementDeclaration = true; data.IncludeInnerXml = true; data.IncludeValue = true; if (writeProperties != null) { writeProperties(mo, data, xmlWriter); } if (writeResources != null) { writeResources(mo, shouldPrintResources, formatter, data, xmlWriter); } if (writeDescNodes != null) { writeDescNodes(mo, data, xmlWriter); } data.IncludeElementDeclaration = d2.IncludeElementDeclaration; data.IncludeInnerXml = d2.IncludeInnerXml; data.IncludeValue = d2.IncludeValue; IMediaContainer mc = mo as IMediaContainer; if (mc != null) { if (data.IsRecursive) { foreach (IUPnPMedia child in mc.CompleteList) { ToXmlFormatter f2 = formatter; f2.StartElement = null; f2.EndElement = null; f2.WriteInnerXml = null; f2.WriteValue = null; child.ToXml(f2, data, xmlWriter); } } } }
public void CreateConnection(IMediaContainer Container, object Tag) { if (Container.MergedResources.Length > 0) { CreateConnection(this.GetBestMatch(Container.MergedResources)); } else { ArrayList RList = new ArrayList(); foreach (IMediaItem item in Container.Items) { foreach (IMediaResource r in item.MergedResources) { if (SupportsProtocolInfo(r.ProtocolInfo)) { RList.Add(r); break; } } } if (RList.Count == 0) { OnCreateConnectionFailedEvent.Fire(this, CreateFailedReason.UNSUPPORTED_MEDIA_ITEM, Tag); return; } CreateConnection((IMediaResource[])RList.ToArray(typeof(IMediaResource)), Tag); } }
private bool SetContainerContext(ContextInfo ci, IMediaContainer context) { bool retVal = false; bool fwd = false, bk = false; // check against forward contexts fwd = IsValidContext(context, ci.ForwardContexts, false); // check against current/entire context if (fwd == false) { bk = IsValidContext(context, ci.EntireContext, false); } // if selecting a valid context... if (fwd) { // going forward, so push the desired context // to our stack context lock (this) { ci.m_Context.Push(context); // if new context is a root container, set the server context if ((context.IsRootContainer) && (!(context is CpRootCollectionContainer))) { CpRootContainer root = context as CpRootContainer; if (root != null) { ci.m_ServerContext = root.Server; } } } retVal = true; } else if (bk) { lock (this) { // going back, so pop the stack until // we get to the desired context // and then refresh while ((this.CurrentContext != context) && (this.m_Context.m_Context.Count > 1)) { this.m_Context.m_Context.Pop(); } if (this.m_Context.m_Context.Count == 1) { this.m_Context.m_ServerContext = null; } } retVal = true; } return(retVal); }
public static int CalculateExpectedBrowseRequests(IMediaContainer c) { int count = 0; for (uint start = 0; start < c.ChildCount+1; start++) { for (uint requested = 0; requested < c.ChildCount+1; requested++) { uint start_requested = start+requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount+LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse) { count++; } } } return count; }
public static int CalculateExpectedBrowseRequests(IMediaContainer c) { int count = 0; for (uint start = 0; start < c.ChildCount + 1; start++) { for (uint requested = 0; requested < c.ChildCount + 1; requested++) { uint start_requested = start + requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount + LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse) { count++; } } } return(count); }
protected void URIMetaDataChangedSink(AVTransportLastChange sender) { if (sender.CurrentURIMetaData != "" && sender.CurrentURIMetaData != "NOT_IMPLEMENTED") { ArrayList a = MediaBuilder.BuildMediaBranches(sender.CurrentURIMetaData); if (a.Count > 0) { // Since new metadata was evented, we need to update the container, and then // update the current item _Container = (IMediaContainer)a[0]; UpdateCurrentItem(); } } }
/// <summary> /// This method just checks a MediaContainer, and lets the user know /// if this renderer is capable of renderering it. Note, that compatible /// in the sense of how the AV spec defines compatible. This does NOT /// gaurantee that it will actually be able to be renderered on the device. /// </summary> /// <param name="Container"></param> /// <returns></returns> public bool IsCompatible(IMediaContainer Container) { foreach (IMediaItem item in Container.Items) { foreach (IMediaResource r in item.MergedResources) { if (SupportsProtocolInfo(r.ProtocolInfo)) { return(true); } } } return(false); }
public Node(IMediaContainer master, Common.MemorySegment identifierPointer, int identifierSize, int lengthSize, long offset, long size, bool complete, bool shouldDispose = true) : base(shouldDispose) { Master = master; DataOffset = offset; IdentifierPointer = identifierPointer; Identifier = IdentifierPointer.Array; IdentifierSize = identifierSize; LengthSize = lengthSize; DataSize = size; IsComplete = complete; //Should calulcate here? }
/// <summary> /// Creates a shallow copy of the node without the data /// </summary> /// <param name="n"></param> Node(Node n, bool shouldDispose = true) : base(shouldDispose) { if (n == null) { throw new ArgumentNullException(); } Master = n.Master; DataOffset = n.DataOffset; Identifier = n.Identifier; IdentifierSize = n.IdentifierSize; LengthSize = n.LengthSize; DataSize = n.DataSize; IsComplete = n.IsComplete; }
private bool IsValidContext(IMediaContainer checkThis, object[] againstThis, bool isContextInfo) { for (int i = 0; i < againstThis.Length; i++) { if (isContextInfo) { ContextInfo ci = (ContextInfo)againstThis[i]; if ((IMediaContainer)(ci.m_Context.Peek()) == checkThis) { return(true); } } else if (againstThis[i] == checkThis) { return(true); } } return(false); }
private void listViewMediaList_DoubleClick(object sender, System.EventArgs e) { IMediaContainer mc = null; lock (this.comboBoxContext) { // change the context on the browser mc = this.listViewMediaList.SelectedItems[0].Tag as IMediaContainer; if (mc != null) { this.m_Browser.SetContainerContext(mc); } } // update UI if (mc != null) { this.HandleContextChange(); } }
/// <summary> /// Constucts a Node instance from the given parameters /// </summary> /// <param name="master"></param> /// <param name="identifier"></param> /// <param name="offset"></param> /// <param name="size"></param> /// <param name="complete"></param> public Node(IMediaContainer master, byte[] identifier, int lengthSize, long offset, long size, bool complete, bool shouldDispose = true) : base(shouldDispose) { if (master == null) { throw new ArgumentNullException("master"); } if (identifier == null) { throw new ArgumentNullException("identifier"); } Master = master; DataOffset = offset; Identifier = identifier; IdentifierPointer = new Common.MemorySegment(identifier); IdentifierSize = identifier.Length; LengthSize = lengthSize; DataSize = size; IsComplete = complete; //Should calulcate here? }
public void CreateConnection(IMediaContainer Container, object Tag) { ArrayList RList = new ArrayList(); foreach(IMediaItem item in Container.Items) { foreach(IMediaResource r in item.MergedResources) { if(Parent.SupportsProtocolInfo(r.ProtocolInfo)) { RList.Add(r); break; } } } if(RList.Count==0) { //ToDo: Throw Exception here return; } CreateConnection((IMediaResource[])RList.ToArray(typeof(IMediaResource)),Tag); }
public void CreateConnection(IMediaContainer Container, object Tag) { ArrayList RList = new ArrayList(); foreach (IMediaItem item in Container.Items) { foreach (IMediaResource r in item.MergedResources) { if (Parent.SupportsProtocolInfo(r.ProtocolInfo)) { RList.Add(r); break; } } } if (RList.Count == 0) { //ToDo: Throw Exception here return; } CreateConnection((IMediaResource[])RList.ToArray(typeof(IMediaResource)), Tag); }
private bool IsValidContext(IMediaContainer checkThis, object[] againstThis, bool isContextInfo) { for (int i=0; i < againstThis.Length; i++) { if (isContextInfo) { ContextInfo ci = (ContextInfo) againstThis[i]; if ((IMediaContainer)(ci.m_Context.Peek()) == checkThis) { return true; } } else if (againstThis[i] == checkThis) { return true; } } return false; }
/// <summary> /// /// </summary> /// <param name="parent"></param> /// <param name="cds"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="details"></param> /// <param name="C"></param> /// <returns></returns> /// <exception cref="TerminateEarly"> /// </exception> public static ArrayList GetContainerChildrenAndValidate(IMediaContainer parent, CpContentDirectory cds, CdsSubTest test, CdsSubTestArgument arg, CdsResult_BrowseAll details, Queue C) { uint totalExpected = uint.MaxValue; uint currentChild = 0; ArrayList children = new ArrayList(); while (currentChild < totalExpected) { BrowseInput input = new BrowseInput(); input.ObjectID = parent.ID; input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.StartingIndex = currentChild; input.RequestedCount = 1; input.SortCriteria = ""; string containerID = parent.ID; if (currentChild == 0) { test.SetExpectedTestingTime ((++details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress( details.TotalBrowseRequests * 30); } CdsBrowseSearchResults results = Browse(input, test, arg, cds, details); test.SetExpectedTestingTime ((details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress( (details.TotalBrowseRequests) * 30); if (results.WorstError >= UPnPTestStates.Failed) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " +input.PrintBrowseParams()+ " returned with an error or had problems with the DIDL-Lite."); } else { if (results.NumberReturned != 1) { if (currentChild != 0) { results.SetError(UPnPTestStates.Failed); arg._TestGroup.AddEvent(LogImportance.Low, test.Name, "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned NumberReturned=" +results.NumberReturned+ " when it should logically be 1."); } } if (results.TotalMatches != totalExpected) { if (currentChild != 0) { results.SetError(UPnPTestStates.Failed); arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned TotalMatches=" +results.TotalMatches+ " when it should logically be " +totalExpected+ " as reported in an earlier Browse request. This portion of the test requires that a MediaServer device not be in a state where its content hierarchy will change."); } else { totalExpected = results.TotalMatches; if (totalExpected > 0) { details.ExpectedTotalBrowseRequests += ((int)results.TotalMatches * 2) - 1; test.SetExpectedTestingTime ((details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress( details.TotalBrowseRequests * 30); } } } if (results.MediaObjects != null) { if (results.MediaObjects.Count == 1) { IUPnPMedia child = results.MediaObjects[0] as IUPnPMedia; if (child == null) { throw new TestException("\"" + test.Name + "\"" + " has a TEST LOGIC ERROR. Browse returned without errors but the child object's metadata is not stored in an IUPnPMedia object. The offending type is " + results.MediaObjects[0].GetType().ToString(), results.MediaObjects[0]); } // ensure no duplicates in object ID foreach (IUPnPMedia previousChild in details.AllObjects) { if (previousChild.ID == child.ID) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned an object with ID=\"" +child.ID+ "\" which conflicts with a previously seen media object in ParentContainerID=\"" +previousChild.ParentID+ "\"."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } // ensure updateID is the same between BrowseDirectChildren and earlier BrowseMetadata. try { uint previousUpdateID = (uint) parent.Tag; if (results.UpdateID != previousUpdateID) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned an UpdateID=" +results.UpdateID+ " whilst an UpdateID=" +previousUpdateID+ " was obtained in a previous call for ContainerID=\"" +parent.ID+ "\" with BrowseMetadata."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } catch (TerminateEarly te) { throw te; } catch (Exception e) { throw new TestException(test.Name + " has a TEST LOGIC ERROR. Error comparing UpdateID values", parent, e); } // add the child to lists: C, parent's child list, and Allobjects try { parent.AddObject(child, false); } catch (Exception e) { AddObjectError aoe = new AddObjectError(); aoe.Parent = parent; aoe.Child = child; throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but the child object could not be added to its parent.", aoe, e); } details.AllObjects.Add(child); children.Add(child); if (child.IsContainer) { C.Enqueue(child); details.TotalContainers++; } else { details.TotalItems++; } // // Do a BrowseMetadata and check to see if the XML values are the same. // CdsBrowseSearchResults compareResults = CheckMetadata(child, cds, test, arg, details); if (compareResults.InvokeError != null) { arg._TestGroup.AddEvent(LogImportance.High, test.Name, test.Name + ": Browse(BrowseDirectChildren,StartingIndex="+currentChild+",RequestedCount=0) on ContainerID=["+containerID+"] succeeded with warnings because a BrowseMetadata request was rejected by the CDS."); } else if (compareResults.ResultErrors.Count > 0) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " failed because a BrowseMetadata request succeeded but the DIDL-Lite could not be represented in object form. Invalid DIDL-Lite is most likely the cause."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } else if (compareResults.WorstError >= UPnPTestStates.Failed) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " failed because one or more child object's failed a comparison of results between BrowseDirectChildren and BrowseMetadata or encountered some other critical error in that process."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } else { //string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " succeeded."; //arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, msg); } // // Track the metadata properties found so far // as we may use them in Browse SortCriteria // // standard top-level attributes Tags T = Tags.GetInstance(); AddTo(details.PropertyNames, "@"+T[_ATTRIB.id]); AddTo(details.PropertyNames, "@"+T[_ATTRIB.parentID]); AddTo(details.PropertyNames, "@"+T[_ATTRIB.restricted]); if (child.IsContainer) { if (child.IsSearchable) { AddTo(details.PropertyNames, "@"+T[_ATTRIB.searchable]); AddTo(details.PropertyNames, T[_DIDL.Container]+"@"+T[_ATTRIB.searchable]); } AddTo(details.PropertyNames, T[_DIDL.Container]+"@"+T[_ATTRIB.id]); AddTo(details.PropertyNames, T[_DIDL.Container]+"@"+T[_ATTRIB.parentID]); AddTo(details.PropertyNames, T[_DIDL.Container]+"@"+T[_ATTRIB.restricted]); } else if (child.IsItem) { if (child.IsReference) { AddTo(details.PropertyNames, "@"+T[_ATTRIB.refID]); AddTo(details.PropertyNames, T[_DIDL.Item]+"@"+T[_ATTRIB.refID]); } AddTo(details.PropertyNames, T[_DIDL.Item]+"@"+T[_ATTRIB.id]); AddTo(details.PropertyNames, T[_DIDL.Item]+"@"+T[_ATTRIB.parentID]); AddTo(details.PropertyNames, T[_DIDL.Item]+"@"+T[_ATTRIB.restricted]); } // standard metadata IMediaProperties properties = child.MergedProperties; IList propertyNames = properties.PropertyNames; foreach (string propertyName in propertyNames) { if (details.PropertyNames.Contains(propertyName) == false) { details.PropertyNames.Add(propertyName); // add attributes if they are not added IList propertyValues = properties[propertyName]; foreach (ICdsElement val in propertyValues) { ICollection attributes = val.ValidAttributes; foreach (string attribName in attributes) { StringBuilder sbpn = new StringBuilder(); sbpn.AppendFormat("{0}@{1}", propertyName, attribName); string fullAttribName = sbpn.ToString(); AddTo(details.PropertyNames, fullAttribName); } } } // resources IList resources = child.MergedResources; foreach (IMediaResource res in resources) { ICollection attributes = res.ValidAttributes; foreach (string attribName in attributes) { string name1 = "res@"+attribName; string name2 = "@"+attribName; AddTo(details.PropertyNames, name1); AddTo(details.PropertyNames, name2); } } if (resources.Count > 0) { AddTo(details.PropertyNames, T[_DIDL.Res]); } } } else { if (results.TotalMatches > 0) { results.SetError(UPnPTestStates.Failed); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " did not yield exactly one CDS-compliant media object in its result. Instantiated a total of " +results.MediaObjects.Count+ " media objects."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } } else { throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but no media objects were instantiated.", null); } } currentChild++; } return children; }
/// <summary> /// Create a new Session on the renderer to play this IMediaContainer /// </summary> /// <param name="Container">Container to render</param> public void CreateConnection(IMediaContainer Container) { CreateConnection(Container, null); }
/// <summary> /// Tests the container with BrowseDirectChildren and different ranges. /// </summary> /// <param name="c"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults TestContainerRanges(IMediaContainer c, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults r = new CdsBrowseSearchResults(); try { BrowseInput input = new BrowseInput(); input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.ObjectID = c.ID; input.SortCriteria = ""; input.StartingIndex = 0; input.RequestedCount = 0; if (c.CompleteList.Count != c.ChildCount) { throw new TestException("\""+test.Name+"\" has c.CompleteList.Count=" +c.CompleteList.Count+ " but c.ChildCount=" +c.ChildCount+ ".", c); } //assume the test will pass, but worsen the result when we find errors r.SetError(UPnPTestStates.Pass); // test starting index = 0 to c.ChildCount+1 // test requested count = 0 to c.ChildCoun+1 for (uint start = 0; start < c.ChildCount+1; start++) { for (uint requested = 0; requested < c.ChildCount+1; requested++) { uint start_requested = start+requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount+LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse == false) { //stats.TotalBrowseRequests++; //arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } else { arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); input.StartingIndex = start; input.RequestedCount = requested; CdsBrowseSearchResults br; br = Cds_BrowseAll.Browse(input, test, arg, cds, stats); if (br.WorstError >= UPnPTestStates.Failed) { if ( (input.StartingIndex < c.ChildCount) ) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " +input.PrintBrowseParams()+ " returned with an error or had problems with the DIDL-Lite."); } else { arg._TestGroup.AddEvent(LogImportance.High, test.Name, "\"" + test.Name + "\": Warning: " +input.PrintBrowseParams()+ " returned an error."); r.SetError(UPnPTestStates.Warn); } } // check return values if (br.NumberReturned != br.MediaObjects.Count) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and the number of media objects instantiated from the DIDL-Lite (instantiated=" +br.MediaObjects.Count+ ") does not match NumberReturned=" +br.NumberReturned+"."); } long expectedReturned; if (input.StartingIndex == 0) { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount; } else if (input.RequestedCount > c.ChildCount) { expectedReturned = c.ChildCount; } else if (input.RequestedCount <= c.ChildCount) { expectedReturned = input.RequestedCount; } else { throw new TestException("\""+test.Name+"\" should not reach here.", null); } } else { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount - input.StartingIndex; } else { expectedReturned = c.ChildCount - input.StartingIndex; if (expectedReturned > input.RequestedCount) { expectedReturned = input.RequestedCount; } } } if ((expectedReturned < 0) || (expectedReturned > c.ChildCount)) { throw new TestException("\""+test.Name+"\" did a " + input.PrintBrowseParams() + " and the expected number of media objects is invalid=" + expectedReturned + ".", br); } if (br.NumberReturned != expectedReturned) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and NumberReturned=" +br.NumberReturned+ " but test expects " +expectedReturned+ " child objects according to results from a prerequisite test."); } if (br.TotalMatches != c.ChildCount) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and TotalMatches=" +br.TotalMatches+ " but test found " +c.ChildCount+ " child objects in a prerequisite test."); } uint cUpdateID = 0; try { cUpdateID = (uint) c.Tag; } catch (Exception ce) { throw new TestException("\""+test.Name+"\" could not cast c.Tag into a uint value", null, ce); } if (br.UpdateID != cUpdateID) { throw new TerminateEarly("\""+test.Name+"\" did a "+ input.PrintBrowseParams() + " and UpdateID=" +br.UpdateID+ " but test expected=" +cUpdateID+ " as found in a prerequisite test."); } arg.TestGroup.AddEvent(LogImportance.Remark, test.Name, "\""+test.Name+"\" did a " +input.PrintBrowseParams()+ " and encountered no errors in the results."); arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } } } } catch (TerminateEarly te) { arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, test.Name + " is terminating early because of the following error: " + te.Message); r.SetError(UPnPTestStates.Failed); return r; } if (r.WorstError > UPnPTestStates.Warn) { throw new TestException("\"" + test.Name + "\" should not reach this code if the result is worse than " + UPnPTestStates.Warn.ToString() + ".", null); } return r; }
public override void CalculateExpectedTestingTime(ICollection otherSubTests, ISubTestArgument arg) { // get the results from the BrowseAll test CdsResult_BrowseAll PRE = null; foreach (ISubTest preTest in otherSubTests) { if (preTest.Name == this.PRE_BROWSEALL.Name) { if (preTest.TestState >= UPnPTestStates.Pass) { PRE = preTest.Details as CdsResult_BrowseAll; break; } } } if (PRE == null) { return; } if (PRE.MostMetadata == null) { return; } if (PRE.MostMetadata.Properties.Count != PRE.MostMetadata.Properties.PropertyNames.Count) { return; } IUPnPMedia MM = PRE.MostMetadata; if (MM == null) { return; } IMediaContainer MC = PRE.MostMetadata.Parent; if (MC == null) { return; } int numProps = MM.Properties.Count; int numChildren = MC.ChildCount; // we browse for "res" and each possible res@attribute numProps += (2 * MediaResource.GetPossibleAttributes().Count) + 2; int expectedBrowses = 0; int inc = numProps / 4; if (inc == 0) { inc = 1; } for (int nProps = 0; nProps < numProps; nProps++) { for (int iProp = 0; iProp < numProps; iProp += inc) { expectedBrowses++; } } expectedBrowses *= 2; int maxTime = 90 * expectedBrowses; this._ExpectedTestingTime = maxTime; }
/// <summary> /// /// </summary> /// <param name="parent"></param> /// <param name="cds"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="details"></param> /// <param name="C"></param> /// <returns></returns> /// <exception cref="TerminateEarly"> /// </exception> public static ArrayList GetContainerChildrenAndValidate(IMediaContainer parent, CpContentDirectory cds, CdsSubTest test, CdsSubTestArgument arg, CdsResult_BrowseAll details, Queue C) { uint totalExpected = uint.MaxValue; uint currentChild = 0; ArrayList children = new ArrayList(); while (currentChild < totalExpected) { BrowseInput input = new BrowseInput(); input.ObjectID = parent.ID; input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.StartingIndex = currentChild; input.RequestedCount = 1; input.SortCriteria = ""; string containerID = parent.ID; if (currentChild == 0) { test.SetExpectedTestingTime((++details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress(details.TotalBrowseRequests * 30); } CdsBrowseSearchResults results = Browse(input, test, arg, cds, details); test.SetExpectedTestingTime((details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress((details.TotalBrowseRequests) * 30); if (results.WorstError >= UPnPTestStates.Failed) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " + input.PrintBrowseParams() + " returned with an error or had problems with the DIDL-Lite."); } else { if (results.NumberReturned != 1) { if (currentChild != 0) { results.SetError(UPnPTestStates.Failed); arg._TestGroup.AddEvent(LogImportance.Low, test.Name, "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned NumberReturned=" + results.NumberReturned + " when it should logically be 1."); } } if (results.TotalMatches != totalExpected) { if (currentChild != 0) { results.SetError(UPnPTestStates.Failed); arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned TotalMatches=" + results.TotalMatches + " when it should logically be " + totalExpected + " as reported in an earlier Browse request. This portion of the test requires that a MediaServer device not be in a state where its content hierarchy will change."); } else { totalExpected = results.TotalMatches; if (totalExpected > 0) { details.ExpectedTotalBrowseRequests += ((int)results.TotalMatches * 2) - 1; test.SetExpectedTestingTime((details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress(details.TotalBrowseRequests * 30); } } } if (results.MediaObjects != null) { if (results.MediaObjects.Count == 1) { IUPnPMedia child = results.MediaObjects[0] as IUPnPMedia; if (child == null) { throw new TestException("\"" + test.Name + "\"" + " has a TEST LOGIC ERROR. Browse returned without errors but the child object's metadata is not stored in an IUPnPMedia object. The offending type is " + results.MediaObjects[0].GetType().ToString(), results.MediaObjects[0]); } // ensure no duplicates in object ID foreach (IUPnPMedia previousChild in details.AllObjects) { if (previousChild.ID == child.ID) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned an object with ID=\"" + child.ID + "\" which conflicts with a previously seen media object in ParentContainerID=\"" + previousChild.ParentID + "\"."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } // ensure updateID is the same between BrowseDirectChildren and earlier BrowseMetadata. try { uint previousUpdateID = (uint)parent.Tag; if (results.UpdateID != previousUpdateID) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned an UpdateID=" + results.UpdateID + " whilst an UpdateID=" + previousUpdateID + " was obtained in a previous call for ContainerID=\"" + parent.ID + "\" with BrowseMetadata."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } catch (TerminateEarly te) { throw te; } catch (Exception e) { throw new TestException(test.Name + " has a TEST LOGIC ERROR. Error comparing UpdateID values", parent, e); } // add the child to lists: C, parent's child list, and Allobjects try { parent.AddObject(child, false); } catch (Exception e) { AddObjectError aoe = new AddObjectError(); aoe.Parent = parent; aoe.Child = child; throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but the child object could not be added to its parent.", aoe, e); } details.AllObjects.Add(child); children.Add(child); if (child.IsContainer) { C.Enqueue(child); details.TotalContainers++; } else { details.TotalItems++; } // // Do a BrowseMetadata and check to see if the XML values are the same. // CdsBrowseSearchResults compareResults = CheckMetadata(child, cds, test, arg, details); if (compareResults.InvokeError != null) { arg._TestGroup.AddEvent(LogImportance.High, test.Name, test.Name + ": Browse(BrowseDirectChildren,StartingIndex=" + currentChild + ",RequestedCount=0) on ContainerID=[" + containerID + "] succeeded with warnings because a BrowseMetadata request was rejected by the CDS."); } else if (compareResults.ResultErrors.Count > 0) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " failed because a BrowseMetadata request succeeded but the DIDL-Lite could not be represented in object form. Invalid DIDL-Lite is most likely the cause."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } else if (compareResults.WorstError >= UPnPTestStates.Failed) { string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " failed because one or more child object's failed a comparison of results between BrowseDirectChildren and BrowseMetadata or encountered some other critical error in that process."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } else { //string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " succeeded."; //arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, msg); } // // Track the metadata properties found so far // as we may use them in Browse SortCriteria // // standard top-level attributes Tags T = Tags.GetInstance(); AddTo(details.PropertyNames, "@" + T[_ATTRIB.id]); AddTo(details.PropertyNames, "@" + T[_ATTRIB.parentID]); AddTo(details.PropertyNames, "@" + T[_ATTRIB.restricted]); if (child.IsContainer) { if (child.IsSearchable) { AddTo(details.PropertyNames, "@" + T[_ATTRIB.searchable]); AddTo(details.PropertyNames, T[_DIDL.Container] + "@" + T[_ATTRIB.searchable]); } AddTo(details.PropertyNames, T[_DIDL.Container] + "@" + T[_ATTRIB.id]); AddTo(details.PropertyNames, T[_DIDL.Container] + "@" + T[_ATTRIB.parentID]); AddTo(details.PropertyNames, T[_DIDL.Container] + "@" + T[_ATTRIB.restricted]); } else if (child.IsItem) { if (child.IsReference) { AddTo(details.PropertyNames, "@" + T[_ATTRIB.refID]); AddTo(details.PropertyNames, T[_DIDL.Item] + "@" + T[_ATTRIB.refID]); } AddTo(details.PropertyNames, T[_DIDL.Item] + "@" + T[_ATTRIB.id]); AddTo(details.PropertyNames, T[_DIDL.Item] + "@" + T[_ATTRIB.parentID]); AddTo(details.PropertyNames, T[_DIDL.Item] + "@" + T[_ATTRIB.restricted]); } // standard metadata IMediaProperties properties = child.MergedProperties; IList propertyNames = properties.PropertyNames; foreach (string propertyName in propertyNames) { if (details.PropertyNames.Contains(propertyName) == false) { details.PropertyNames.Add(propertyName); // add attributes if they are not added IList propertyValues = properties[propertyName]; foreach (ICdsElement val in propertyValues) { ICollection attributes = val.ValidAttributes; foreach (string attribName in attributes) { StringBuilder sbpn = new StringBuilder(); sbpn.AppendFormat("{0}@{1}", propertyName, attribName); string fullAttribName = sbpn.ToString(); AddTo(details.PropertyNames, fullAttribName); } } } // resources IList resources = child.MergedResources; foreach (IMediaResource res in resources) { ICollection attributes = res.ValidAttributes; foreach (string attribName in attributes) { string name1 = "res@" + attribName; string name2 = "@" + attribName; AddTo(details.PropertyNames, name1); AddTo(details.PropertyNames, name2); } } if (resources.Count > 0) { AddTo(details.PropertyNames, T[_DIDL.Res]); } } } else { if (results.TotalMatches > 0) { results.SetError(UPnPTestStates.Failed); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " did not yield exactly one CDS-compliant media object in its result. Instantiated a total of " + results.MediaObjects.Count + " media objects."; arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); throw new TerminateEarly(msg); } } } else { throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but no media objects were instantiated.", null); } } currentChild++; } return(children); }
public static CdsBrowseSearchResults GetContainerMetadataAndValidate(string containerID, CpContentDirectory cds, CdsSubTest test, CdsSubTestArgument arg, CdsResult_BrowseAll details, out IUPnPMedia metadata) { BrowseInput input = new BrowseInput(); input.ObjectID = containerID; input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEMETADATA; input.Filter = "*"; input.StartingIndex = 0; input.RequestedCount = 0; input.SortCriteria = ""; metadata = null; test.SetExpectedTestingTime((++details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress(details.TotalBrowseRequests * 30); CdsBrowseSearchResults results = Browse(input, test, arg, cds, details); test.SetExpectedTestingTime((details.ExpectedTotalBrowseRequests) * 30); arg.ActiveTests.UpdateTimeAndProgress((details.TotalBrowseRequests) * 30); if (results.InvokeError == null) { if (results.NumberReturned != 1) { //results.SetError(UPnPTestStates.Warn); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned NumberReturned=" + results.NumberReturned + " when it should logically be 1. This output parameter is not really useful for BrowseMetadata so this logic error does not prevent towards certification, but it should be fixed."; //arg._TestGroup.AddEvent(LogImportance.Low, test.Name, msg); results.ResultErrors.Add(new Exception(msg)); } if (results.TotalMatches != 1) { //results.SetError(UPnPTestStates.Warn); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned TotalMatches=" + results.TotalMatches + " when it should logically be 1. This output parameter is not really useful BrowseMetadata so this logic error does not prevent towards certification, but it should be fixed."; //arg._TestGroup.AddEvent(LogImportance.Low, test.Name, msg); results.ResultErrors.Add(new Exception(msg)); } if (results.MediaObjects != null) { if (results.MediaObjects.Count == 1) { metadata = results.MediaObjects[0] as IUPnPMedia; if (metadata == null) { throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but the container's metadata is not stored in an IUPnPMedia object. The offending type is " + results.MediaObjects[0].GetType().ToString(), results.MediaObjects[0]); } IMediaContainer imc = metadata as IMediaContainer; // // check metadata // if (imc == null) { //results.SetError(UPnPTestStates.Failed); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned a DIDL-Lite media object but it was not declared with a \"container\" element."; //arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); results.ResultErrors.Add(new Exception(msg)); } else { } if (metadata.ID != containerID) { //results.SetError(UPnPTestStates.Failed); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned a DIDL-Lite media object with ID=\"" + metadata.ID + "\" when it should be \"" + containerID + "\" as indicated by the input parameter."; //arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); results.ResultErrors.Add(new Exception(msg)); } if (containerID == "0") { if (metadata.ParentID != "-1") { //results.SetError(UPnPTestStates.Failed); string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " returned a DIDL-Lite media object with parentID=\"" + metadata.ID + "\" when it must be \"-1\" because the container is the root container."; //arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); results.ResultErrors.Add(new Exception(msg)); } // no need to check parentID values for other containers because // they get checked when getting the children for this container. } if (results.WorstError < UPnPTestStates.Failed) { //string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " succeeded."; //arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, msg); } } else { //results.SetError(UPnPTestStates.Failed); //string msg = "\"" + test.Name + "\": " + input.PrintBrowseParams() + " did not yield exactly one CDS-compliant media object in its result. Instantiated a total of " +results.MediaObjects.Count+ " media objects."; //arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg); } } else { //throw new TestException(test.Name + " has a TEST LOGIC ERROR. Browse returned without errors but no media objects were instantiated.", null); } } if ((results.InvokeError != null) || (results.ResultErrors.Count > 0)) { StringBuilder msg = new StringBuilder(); results.SetError(UPnPTestStates.Failed); msg.AppendFormat("\"{0}\": {1} did not yield exactly one CDS-compliant media object in its result. Instantiated a total of {2} media objects.", test.Name, input.PrintBrowseParams(), results.MediaObjects.Count); msg.AppendFormat("\r\nAdditional Information:"); if (results.InvokeError != null) { msg.AppendFormat("\r\n{0}", results.InvokeError.Message); } foreach (Exception e in results.ResultErrors) { msg.AppendFormat("\r\n{0}", e.Message); } arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, msg.ToString()); } return(results); }
/// <summary> /// Create a new Session on the renderer to play this IMediaContainer /// </summary> /// <param name="Container">Container to render</param> public void CreateConnection(IMediaContainer Container) { CreateConnection(Container,null); }
/// <summary> /// This method just checks a MediaContainer, and lets the user know /// if this renderer is capable of renderering it. Note, that compatible /// in the sense of how the AV spec defines compatible. This does NOT /// gaurantee that it will actually be able to be renderered on the device. /// </summary> /// <param name="Container"></param> /// <returns></returns> public bool IsCompatible(IMediaContainer Container) { foreach(IMediaItem item in Container.Items) { foreach(IMediaResource r in item.MergedResources) { if(SupportsProtocolInfo(r.ProtocolInfo)) return(true); } } return(false); }
protected void URIMetaDataChangedSink(AVTransportLastChange sender) { if(sender.CurrentURIMetaData!="" && sender.CurrentURIMetaData!="NOT_IMPLEMENTED") { ArrayList a = MediaBuilder.BuildMediaBranches(sender.CurrentURIMetaData); if(a.Count>0) { // Since new metadata was evented, we need to update the container, and then // update the current item _Container = (IMediaContainer)a[0]; UpdateCurrentItem(); } } }
private bool SetContainerContext(ContextInfo ci, IMediaContainer context) { bool retVal = false; bool fwd = false, bk = false; // check against forward contexts fwd = IsValidContext(context, ci.ForwardContexts, false); // check against current/entire context if (fwd == false) { bk = IsValidContext(context, ci.EntireContext, false); } // if selecting a valid context... if (fwd) { // going forward, so push the desired context // to our stack context lock (this) { ci.m_Context.Push(context); // if new context is a root container, set the server context if ((context.IsRootContainer) && (!(context is CpRootCollectionContainer))) { CpRootContainer root = context as CpRootContainer; if (root != null) { ci.m_ServerContext = root.Server; } } } retVal = true; } else if (bk) { lock(this) { // going back, so pop the stack until // we get to the desired context // and then refresh while ((this.CurrentContext != context) && (this.m_Context.m_Context.Count > 1)) { this.m_Context.m_Context.Pop(); } if (this.m_Context.m_Context.Count == 1) { this.m_Context.m_ServerContext = null; } } retVal = true; } return retVal; }
public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg) { CpContentDirectory CDS = this.GetCDS(arg._Device); _Details = new CdsResult_BrowseFilter(); this._TestState = UPnPTestStates.Running; arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\"" + this.Name + "\" started."); // get the results from the BrowseAll test CdsResult_BrowseAll PRE = null; try { foreach (ISubTest preTest in otherSubTests) { if (preTest.Name == this.PRE_BROWSEALL.Name) { PRE = preTest.Details as CdsResult_BrowseAll; break; } } if (PRE == null) { throw new TestException(this._Name + " requires that the \"" + this.PRE_BROWSEALL.Name + "\" test be run as a prerequisite. The results from that test cannot be obtained.", otherSubTests); } } catch (Exception e) { throw new TestException(this._Name + " requires that the \"" + this.PRE_BROWSEALL.Name + "\" test be run before. An error occurred when attempting to obtain the results of a prerequisite.", otherSubTests, e); } _Details.BrowseAllResults = PRE; if (PRE.MostMetadata == null) { throw new TestException(this.PRE_BROWSEALL.Name + " failed to find a media object with the most metadata. " + this._Name + " requires this value.", PRE); } if (PRE.MostMetadata.Properties.Count != PRE.MostMetadata.Properties.PropertyNames.Count) { throw new TestException(this.Name + " has conflicting reports for the number of metadata properties. " + PRE.MostMetadata.Properties.Count + "/" + PRE.MostMetadata.Properties.PropertyNames.Count, PRE.MostMetadata.Properties); } IUPnPMedia MM = PRE.MostMetadata; if (MM == null) { string skippedMsg = "\"" + this.Name + "\" skipped because the tested content hierarchy does not have a media object with at least one resource and has an ID!=\"0\""; arg.TestGroup.AddEvent(LogImportance.Critical, this.Name, skippedMsg); arg.TestGroup.AddResult(skippedMsg); return(UPnPTestStates.Ready); } IMediaContainer MC = PRE.MostMetadata.Parent; if (MC == null) { throw new TestException(this.Name + " has MostMetadata.Parent == null", PRE.MostMetadata); } int numProps = MM.Properties.Count; int numChildren = MC.ChildCount; // we browse for "res" and each possible res@attribute numProps += (2 * MediaResource.GetPossibleAttributes().Count) + 2; _Details.NumberOfProperties = numProps; _Details.ExpectedTotalBrowseRequests = 0; int inc = numProps / 4; if (inc == 0) { inc = 1; } for (int nProps = 0; nProps < numProps; nProps++) { for (int iProp = 0; iProp < numProps; iProp += inc) { _Details.ExpectedTotalBrowseRequests++; } } _Details.ExpectedTotalBrowseRequests *= 2; int maxTime = 90 * _Details.ExpectedTotalBrowseRequests; this._ExpectedTestingTime = maxTime; // browse metadata with various filter settings // browsedirectchildren with various filter settings UPnPTestStates state = this._TestState; CdsBrowseSearchResults test1 = TestFiltersBrowseMetadata(MM, CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEMETADATA, this, arg, CDS, _Details); if (test1.WorstError > state) { state = test1.WorstError; } CdsBrowseSearchResults test2 = TestFiltersBrowseMetadata(MM, CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN, this, arg, CDS, _Details); if (test2.WorstError > state) { state = test2.WorstError; } // finish up logging this._TestState = state; StringBuilder sb = new StringBuilder(); sb.AppendFormat("\"{0}\" completed", this.Name); if (this._TestState <= UPnPTestStates.Running) { throw new TestException("\"" + this.Name + "\" must have a pass/warn/fail result.", this._TestState); } switch (this._TestState) { case UPnPTestStates.Pass: sb.Append(" successfully."); break; case UPnPTestStates.Warn: sb.Append(" with warnings."); break; case UPnPTestStates.Failed: sb.Append(" with a failed result."); break; } arg._TestGroup.AddResult(sb.ToString()); if (this._TestState <= UPnPTestStates.Warn) { if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests) { throw new TestException("TotalBrowseRequests=" + _Details.TotalBrowseRequests.ToString() + " ExpectedTotal=" + _Details.ExpectedTotalBrowseRequests.ToString(), _Details); } } arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, sb.ToString()); return(this._TestState); }
public override UPnPTestStates Run(ICollection otherSubTests, CdsSubTestArgument arg) { // init basic stuff CpContentDirectory CDS = this.GetCDS(arg._Device); _Details = new CdsResult_BrowseAll(); // set up a queue of containers to browse, starting with root container Queue C = new Queue(); _Details.Root = new MediaContainer(); _Details.Root.ID = "0"; _Details.AllObjects.Add(_Details.Root); _Details.TotalContainers = 1; _Details.TotalItems = 0; C.Enqueue(_Details.Root); // if we have containers to browse, do so this._TestState = UPnPTestStates.Running; UPnPTestStates testResult = UPnPTestStates.Ready; arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, "\"" + this.Name + "\" started."); while (C.Count > 0) { IMediaContainer c = (IMediaContainer)C.Dequeue(); this._ExpectedTestingTime = _Details.ExpectedTotalBrowseRequests * 30; arg.ActiveTests.UpdateTimeAndProgress(_Details.TotalBrowseRequests * 30); // // get the container's metadata // IUPnPMedia metadata; CdsBrowseSearchResults results = GetContainerMetadataAndValidate(c.ID, CDS, this, arg, _Details, out metadata); testResult = results.WorstError; if (testResult > UPnPTestStates.Warn) { arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, this.Name + " terminating because container metadata could not be obtained or the metadata was not CDS-compliant."); testResult = UPnPTestStates.Failed; this._TestState = testResult; return(this._TestState); } if (metadata != null) { try { c.UpdateObject(metadata); c.Tag = results.UpdateID; } catch (Exception e) { UpdateObjectError uoe = new UpdateObjectError(); uoe.UpdateThis = c; uoe.Metadata = metadata; throw new TestException("Critical error updating metadata of a container using UpdateObject()", uoe, e); } } else { string reason = "\"" + this.Name + "\" terminating because container metadata could not be cast into object form."; arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason); arg._TestGroup.AddResult("\"" + this.Name + "\" test failed. " + reason); testResult = UPnPTestStates.Failed; this._TestState = testResult; return(this._TestState); } // // Now get the container's children // ArrayList children = new ArrayList(); try { children = GetContainerChildrenAndValidate(c, CDS, this, arg, _Details, C); if ((_Details.LargestContainer == null) || (children.Count > _Details.LargestContainer.ChildCount)) { _Details.LargestContainer = c; } } catch (TerminateEarly te) { string reason = "\"" + this.Name + "\" terminating early. Reason => " + te.Message; arg._TestGroup.AddEvent(LogImportance.Critical, this.Name, reason); arg._TestGroup.AddResult("\"" + this.Name + "\" test failed. " + reason); testResult = UPnPTestStates.Failed; this._TestState = testResult; return(this._TestState); } } if (testResult >= UPnPTestStates.Failed) { throw new TestException("Execution should not reach this code if testResult is WARN or worse.", testResult); } if (testResult == UPnPTestStates.Ready) { throw new TestException("We should not return Ready state.", testResult); } StringBuilder sb = new StringBuilder(); sb.Append("\"" + this._Name + "\" test finished"); if (testResult == UPnPTestStates.Warn) { sb.Append(" with warnings"); } sb.AppendFormat(" and found {0}/{1}/{2} TotalObjects/TotalContainers/TotalItems.", _Details.AllObjects.Count, _Details.TotalContainers, _Details.TotalItems); arg.TestGroup.AddResult(sb.ToString()); arg._TestGroup.AddEvent(LogImportance.Remark, this.Name, this.Name + " completed."); this._TestState = testResult; if (this._TestState <= UPnPTestStates.Warn) { if (_Details.TotalBrowseRequests != _Details.ExpectedTotalBrowseRequests) { throw new TestException("TotalBrowseRequests=" + _Details.TotalBrowseRequests.ToString() + " ExpectedTotal=" + _Details.ExpectedTotalBrowseRequests.ToString(), _Details); } } return(this._TestState); }
/// <summary> /// Performs a Browse invocation. /// </summary> /// <param name="input"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults Browse(BrowseInput input, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults results = new CdsBrowseSearchResults(); results.SetError(UPnPTestStates.Pass); results.ResultErrors = new ArrayList(); arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" about to do " + input.PrintBrowseParams() + "."); try { cds.Sync_Browse(input.ObjectID, input.BrowseFlag, input.Filter, input.StartingIndex, input.RequestedCount, input.SortCriteria, out results.Result, out results.NumberReturned, out results.TotalMatches, out results.UpdateID); } catch (UPnPInvokeException error) { results.InvokeError = error; } if (results.InvokeError == null) { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" completed " + input.PrintBrowseParams() + " with no errors returned by the device."); } else { arg._TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" completed " + input.PrintBrowseParams() + " with the device returning an error."); } stats.TotalBrowseRequests++; ArrayList branches = null; if (results.InvokeError == null) { try { if (results.Result != null) { if (results.Result != "") { bool schemaOK = CheckDidlLiteSchema(results.Result); if (schemaOK) { results.MediaObjects = branches = MediaBuilder.BuildMediaBranches(results.Result, typeof(MediaItem), typeof(MediaContainer), true); if (branches.Count != results.NumberReturned) { results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " + branches.Count + " media objects but the request returned NumberReturned=" + results.NumberReturned + ".")); } if (input.BrowseFlag == CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEMETADATA) { if (branches.Count != 1) { results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument indicating the presence of " + branches.Count + " media objects but the request should have only returned 1 media object.")); } } foreach (IUPnPMedia mobj in branches) { IMediaContainer imc = mobj as IMediaContainer; if (imc != null) { if (imc.CompleteList.Count > 0) { StringBuilder offendingList = new StringBuilder(); int offenses = 0; foreach (IUPnPMedia offending in imc.CompleteList) { if (offenses > 0) { offendingList.Append(","); } offendingList.AppendFormat("\"{0}\"", offending.ID); offenses++; } results.ResultErrors.Add(new CdsException(input.PrintBrowseParams() + " has the \"Result\" argument with a declared container (ID=\"" + imc.ID + "\") element that also includes its immediate children. Illegally declared media objects in the response are: " + offendingList.ToString())); } } } } } } } catch (Exception error2) { results.ResultErrors.Add(error2); if (results.MediaObjects == null) { results.MediaObjects = new ArrayList(); } } } // log any errors if ((results.InvokeError != null) || (results.ResultErrors.Count > 0)) { LogErrors(arg._TestGroup, test, input, "Browse", results.InvokeError, results.ResultErrors); results.SetError(UPnPTestStates.Failed); } return(results); }
/// <summary> /// Given an <see cref="IUPnPMedia"/> the returned values /// are a list (or null) of all values associated with the supplied /// metadata property. /// </summary> /// <param name="media">the <see cref="IUPnPMedia"/> to interrogage</param> /// <returns>a list of values associated with metadata</returns> public IList Extract(IUPnPMedia media) { ArrayList results = new ArrayList(); // Obtain the values of the appropriate property. // if (this.m_SearchDesc == false) { if (this.m_SearchContainer || this.m_SearchItem) { //grab attributes of item and container if (this.m_Attrib != "") { // Compare element attribute // if (string.Compare(this.m_Attrib, T[_ATTRIB.id], true) == 0) { results.Add(media.ID); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.parentID], true) == 0) { results.Add(media.ParentID); } else if ( (string.Compare(this.m_Attrib, T[_ATTRIB.refID], true) == 0) || (string.Compare(this.m_Attrib, T[_ATTRIB.childCount], true) == 0) ) { IMediaContainer container = media as IMediaContainer; if (container != null) { results.Add(container.ChildCount); } else { IMediaItem mi = media as IMediaItem; if (mi != null) { if (mi.IsReference) { results.Add(mi.RefID); } } } } else if (string.Compare(this.m_Attrib, T[_ATTRIB.restricted], true) == 0) { // Regardless of 0/1 or false/true, a standard of string comparison will do. // results.Add(media.IsRestricted); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.searchable], true) == 0) { IMediaContainer container = media as IMediaContainer; if (container != null) { results.Add(container.IsSearchable); } } } else { // Grab the innerText value of an item or container object // because that's really the value of an item or container. // results.Add(this.GrabInnerText(media)); } } else if (this.m_SearchRes) { foreach (IMediaResource res in media.MergedResources) { if (this.m_Attrib != "") { IList resAttribs = res.ValidAttributes; if (resAttribs.Contains(this.m_Attrib)) { if (string.Compare(this.m_Attrib, T[_ATTRIB.bitrate], true) == 0) { results.Add(res.Bitrate); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.bitsPerSample], true) == 0) { results.Add(res.BitsPerSample); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.colorDepth], true) == 0) { results.Add(res.ColorDepth); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.duration], true) == 0) { results.Add(res.Duration); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.importUri], true) == 0) { results.Add(res.ImportUri); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.nrAudioChannels], true) == 0) { results.Add(res.nrAudioChannels); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.protection], true) == 0) { results.Add(res.Protection); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.protocolInfo], true) == 0) { results.Add(res.ProtocolInfo.ToString()); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.resolution], true) == 0) { results.Add(res[_RESATTRIB.resolution]); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.sampleFrequency], true) == 0) { results.Add(res.SampleFrequency); } else if (string.Compare(this.m_Attrib, T[_ATTRIB.size], true) == 0) { results.Add(res.Size); } } } else { Type resType = res.GetType(); PropertyInfo pi = resType.GetProperty("RelativeContentUri"); if (pi == null) { results.Add(res.ContentUri); } else { string relativeUri = (string)pi.GetValue(res, null); if ((relativeUri != null) && (relativeUri != "")) { results.Add(relativeUri); } else { throw new ApplicationException("res.RelativeContentUri is null or empty."); } } } } //end for } else if (string.Compare(this.m_Tag, _DC.title.ToString(), true) == 0) { string title = media.Title; results.Add(title); } else { StringBuilder sb = new StringBuilder(); sb.AppendFormat("{0}:{1}", this.m_Ns, this.m_Tag); IList values = null; IList propValues = media.MergedProperties[sb.ToString()]; if (propValues != null) { foreach (ICdsElement propertyValue in propValues) { if (values == null) { values = new ArrayList(); } object val = null; if (this.m_Attrib != "") { val = propertyValue.ExtractAttribute(this.m_Attrib); } else { val = propertyValue.ComparableValue; } if (val != null) { values.Add(val); } } if (values != null) { results.AddRange(values); } } } } else { // Limit our searches to the "desc" elements. // throw new UPnPCustomException(709, "Extraction, sorting, or comparison of <desc> elements or child elements in <desc> nodes is not implemented yet."); } return(results); }
public void CreateConnection(IMediaContainer Container, object Tag) { if (Container.MergedResources.Length > 0) { CreateConnection(this.GetBestMatch(Container.MergedResources)); } else { ArrayList RList = new ArrayList(); foreach(IMediaItem item in Container.Items) { foreach(IMediaResource r in item.MergedResources) { if(SupportsProtocolInfo(r.ProtocolInfo)) { RList.Add(r); break; } } } if(RList.Count==0) { OnCreateConnectionFailedEvent.Fire(this,CreateFailedReason.UNSUPPORTED_MEDIA_ITEM,Tag); return; } CreateConnection((IMediaResource[])RList.ToArray(typeof(IMediaResource)),Tag); } }
/// <summary> /// Tests the container with BrowseDirectChildren and different ranges. /// </summary> /// <param name="c"></param> /// <param name="test"></param> /// <param name="arg"></param> /// <param name="cds"></param> /// <param name="stats"></param> /// <returns></returns> public static CdsBrowseSearchResults TestContainerRanges(IMediaContainer c, CdsSubTest test, CdsSubTestArgument arg, CpContentDirectory cds, CdsResult_BrowseStats stats) { CdsBrowseSearchResults r = new CdsBrowseSearchResults(); try { BrowseInput input = new BrowseInput(); input.BrowseFlag = CpContentDirectory.Enum_A_ARG_TYPE_BrowseFlag.BROWSEDIRECTCHILDREN; input.Filter = "*"; input.ObjectID = c.ID; input.SortCriteria = ""; input.StartingIndex = 0; input.RequestedCount = 0; if (c.CompleteList.Count != c.ChildCount) { throw new TestException("\"" + test.Name + "\" has c.CompleteList.Count=" + c.CompleteList.Count + " but c.ChildCount=" + c.ChildCount + ".", c); } //assume the test will pass, but worsen the result when we find errors r.SetError(UPnPTestStates.Pass); // test starting index = 0 to c.ChildCount+1 // test requested count = 0 to c.ChildCoun+1 for (uint start = 0; start < c.ChildCount + 1; start++) { for (uint requested = 0; requested < c.ChildCount + 1; requested++) { uint start_requested = start + requested; bool doBrowse = false; int tenthCount = c.ChildCount / 10; int quarterCount = c.ChildCount / 4; if (quarterCount == 0) { quarterCount = 1; } if (tenthCount == 0) { tenthCount = 1; } if (start < LIMIT) { if ( (requested == 0) || (start_requested > c.ChildCount - LIMIT) ) { doBrowse = true; } } else if (start >= c.ChildCount - LIMIT) { if (start_requested < c.ChildCount + LIMIT) { doBrowse = true; } } else if ((start % quarterCount == 0) && (requested % tenthCount == 0)) { doBrowse = true; } if (doBrowse == false) { //stats.TotalBrowseRequests++; //arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } else { arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); input.StartingIndex = start; input.RequestedCount = requested; CdsBrowseSearchResults br; br = Cds_BrowseAll.Browse(input, test, arg, cds, stats); if (br.WorstError >= UPnPTestStates.Failed) { if ( (input.StartingIndex < c.ChildCount) ) { throw new TerminateEarly("\"" + test.Name + "\" is terminating early because " + input.PrintBrowseParams() + " returned with an error or had problems with the DIDL-Lite."); } else { arg._TestGroup.AddEvent(LogImportance.High, test.Name, "\"" + test.Name + "\": Warning: " + input.PrintBrowseParams() + " returned an error."); r.SetError(UPnPTestStates.Warn); } } // check return values if (br.NumberReturned != br.MediaObjects.Count) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and the number of media objects instantiated from the DIDL-Lite (instantiated=" + br.MediaObjects.Count + ") does not match NumberReturned=" + br.NumberReturned + "."); } long expectedReturned; if (input.StartingIndex == 0) { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount; } else if (input.RequestedCount > c.ChildCount) { expectedReturned = c.ChildCount; } else if (input.RequestedCount <= c.ChildCount) { expectedReturned = input.RequestedCount; } else { throw new TestException("\"" + test.Name + "\" should not reach here.", null); } } else { if (input.RequestedCount == 0) { expectedReturned = c.ChildCount - input.StartingIndex; } else { expectedReturned = c.ChildCount - input.StartingIndex; if (expectedReturned > input.RequestedCount) { expectedReturned = input.RequestedCount; } } } if ((expectedReturned < 0) || (expectedReturned > c.ChildCount)) { throw new TestException("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and the expected number of media objects is invalid=" + expectedReturned + ".", br); } if (br.NumberReturned != expectedReturned) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and NumberReturned=" + br.NumberReturned + " but test expects " + expectedReturned + " child objects according to results from a prerequisite test."); } if (br.TotalMatches != c.ChildCount) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and TotalMatches=" + br.TotalMatches + " but test found " + c.ChildCount + " child objects in a prerequisite test."); } uint cUpdateID = 0; try { cUpdateID = (uint)c.Tag; } catch (Exception ce) { throw new TestException("\"" + test.Name + "\" could not cast c.Tag into a uint value", null, ce); } if (br.UpdateID != cUpdateID) { throw new TerminateEarly("\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and UpdateID=" + br.UpdateID + " but test expected=" + cUpdateID + " as found in a prerequisite test."); } arg.TestGroup.AddEvent(LogImportance.Remark, test.Name, "\"" + test.Name + "\" did a " + input.PrintBrowseParams() + " and encountered no errors in the results."); arg.ActiveTests.UpdateTimeAndProgress(stats.TotalBrowseRequests * 300); } } } } catch (TerminateEarly te) { arg._TestGroup.AddEvent(LogImportance.Critical, test.Name, test.Name + " is terminating early because of the following error: " + te.Message); r.SetError(UPnPTestStates.Failed); return(r); } if (r.WorstError > UPnPTestStates.Warn) { throw new TestException("\"" + test.Name + "\" should not reach this code if the result is worse than " + UPnPTestStates.Warn.ToString() + ".", null); } return(r); }