/// <summary> /// Gets the children. /// </summary> /// <param name="entry">The entry.</param> /// <param name="useCache">if set to <c>true</c> [use cache].</param> /// <param name="receiver">The receiver.</param> /// <returns></returns> public FileEntry[] GetChildren( FileEntry entry, bool useCache, IListingReceiver receiver ) { // first thing we do is check the cache, and if we already have a recent // enough children list, we just return that. if ( useCache && !entry.NeedFetch ) { return entry.Children.ToArray ( ); } // if there's no receiver, then this is a synchronous call, and we // return the result of ls if ( receiver == null ) { DoLS ( entry ); return entry.Children.ToArray ( ); } // this is a asynchronous call. // we launch a thread that will do ls and give the listing // to the receiver Thread t = new Thread ( new ParameterizedThreadStart ( delegate ( object stateData ) { var state = stateData as ThreadState; DoLS ( entry ); receiver.SetChildren ( state.Entry, state.Entry.Children.ToArray ( ) ); FileEntry[] children = state.Entry.Children.ToArray ( ); if ( children.Length > 0 && children[0].IsApplicationPackage ) { var map = new Dictionary<String, FileEntry> ( ); children.ForEach ( child => { map.Add ( child.FullPath, child ); } ); // call pm. String command = PM_FULL_LISTING; try { this.Device.ExecuteShellCommand ( command, new PackageManagerListingReceiver ( map, receiver ) ); } catch ( IOException e ) { // adb failed somehow, we do nothing. Log.e ( "FileListingService", e ); } } // if another thread is pending, launch it lock ( Threads ) { // first remove ourselves from the list Threads.Remove ( state.Thread ); // then launch the next one if applicable. if ( Threads.Count > 0 ) { Thread ct = Threads[0]; ct.Start ( new ThreadState { Thread = ct, Entry = entry } ); } } } ) ); t.Name = "ls " + entry.FullPath; // we don't want to run multiple ls on the device at the same time, so we // store the thread in a list and launch it only if there's no other thread running. // the thread will launch the next one once it's done. lock ( Threads ) { // add to the list Threads.Add ( t ); // if it's the only one, launch it. if ( Threads.Count == 1 ) { t.Start ( new ThreadState { Thread = t } ); } } // and we return null. return null; }
/// <summary> /// Initializes a new instance of the <see cref="PackageManagerReceiver"/> class. /// </summary> /// <param name="entryMap">The entry map.</param> /// <param name="receiver">The receiver.</param> public PackageManagerListingReceiver( Dictionary<String, FileEntry> entryMap, IListingReceiver receiver ) { this.Map = entryMap; this.Receiver = receiver; }
/// <summary> /// Initializes a new instance of the <see cref="PackageManagerReceiver"/> class. /// </summary> /// <param name="entryMap">The entry map.</param> /// <param name="receiver">The receiver.</param> public PackageManagerListingReceiver(Dictionary <String, FileEntry> entryMap, IListingReceiver receiver) { this.Map = entryMap; this.Receiver = receiver; }
/// <summary> /// Returns the children of a <seealso cref="FileEntry"/>. /// <p/> /// This method supports a cache mechanism and synchronous and asynchronous modes. /// <p/> /// If <var>receiver</var> is <code>null</code>, the device side <code>ls</code> /// command is done synchronously, and the method will return upon completion of the command.<br> /// If <var>receiver</var> is non <code>null</code>, the command is launched is a separate /// thread and upon completion, the receiver will be notified of the result. /// <p/> /// The result for each <code>ls</code> command is cached in the parent /// <code>FileEntry</code>. <var>useCache</var> allows usage of this cache, but only if the /// cache is valid. The cache is valid only for <seealso cref="FileListingService#REFRESH_RATE"/> ms. /// After that a new <code>ls</code> command is always executed. /// <p/> /// If the cache is valid and <code>useCache == true</code>, the method will always simply /// return the value of the cache, whether a <seealso cref="IListingReceiver"/> has been provided or not. /// </summary> /// <param name="entry"> The parent entry. </param> /// <param name="useCache"> A flag to use the cache or to force a new ls command. </param> /// <param name="receiver"> A receiver for asynchronous calls. </param> /// <returns> The list of children or <code>null</code> for asynchronous calls. /// </returns> /// <seealso cref= FileEntry#getCachedChildren() </seealso> //JAVA TO C# CONVERTER WARNING: 'final' parameters are not allowed in .NET: //ORIGINAL LINE: public FileEntry[] getChildren(final FileEntry entry, boolean useCache, final IListingReceiver receiver) public FileEntry[] getChildren(FileEntry entry, bool useCache, IListingReceiver receiver) { // first thing we do is check the cache, and if we already have a recent // enough children list, we just return that. if (useCache && entry.needFetch() == false) { return entry.cachedChildren; } // if there's no receiver, then this is a synchronous call, and we // return the result of ls if (receiver == null) { doLs(entry); return entry.cachedChildren; } // this is a asynchronous call. // we launch a thread that will do ls and give the listing // to the receiver ThreadStart runner = () => { #if TODO doLs(entry); receiver.setChildren(entry, entry.getCachedChildren()); final FileEntry[] children = entry.getCachedChildren(); if (children.length > 0 && children[0].isApplicationPackage()) { final HashMap<String, FileEntry> map = new HashMap<String, FileEntry>(); for (FileEntry child : children) { String path = child.getFullPath(); map.put(path, child); } // call pm. String command = PM_FULL_LISTING; try { /*mDevice.executeShellCommand(command, new MultiLineReceiver() { @Override public void processNewLines(String[] lines) { for (String line : lines) { if (line.length() > 0) { // get the filepath and package from the line Matcher m = sPmPattern.matcher(line); if (m.matches()) { // get the children with that path FileEntry entry = map.get(m.group(1)); if (entry != null) { entry.info = m.group(2); receiver.refreshEntry(entry); } } } } } @Override public boolean isCancelled() { return false; } });*/ } catch (Exception e) { // adb failed somehow, we do nothing. } } // if another thread is pending, launch it synchronized(mThreadList) { // first remove ourselves from the list mThreadList.remove(this); // then launch the next one if applicable. if (mThreadList.size() > 0) { Thread t = mThreadList.get(0); t.start(); } } }
/// <include file='.\FileListingService.xml' path='/FileListingService/GetChildren/*'/> public FileEntry[] GetChildren(FileEntry entry, bool useCache, IListingReceiver receiver) { // first thing we do is check the cache, and if we already have a recent // enough children list, we just return that. if (useCache && !entry.NeedFetch) { return(entry.Children.ToArray( )); } // if there's no receiver, then this is a synchronous call, and we // return the result of ls if (receiver == null) { DoLS(entry); return(entry.Children.ToArray( )); } // this is a asynchronous call. // we launch a thread that will do ls and give the listing // to the receiver Thread t = new Thread(new ParameterizedThreadStart(delegate(object stateData) { var state = stateData as ThreadState; DoLS(entry); receiver.SetChildren(state.Entry, state.Entry.Children.ToArray( )); FileEntry[] children = state.Entry.Children.ToArray( ); if (children.Length > 0 && children[0].IsApplicationPackage) { var map = new Dictionary <String, FileEntry> ( ); children.ForEach(child => { map.Add(child.FullPath, child); }); // call pm. String command = PM_FULL_LISTING; try { this.Device.ExecuteShellCommand(command, new PackageManagerListingReceiver(map, receiver)); } catch (IOException e) { // adb failed somehow, we do nothing. Log.e("FileListingService", e); } } // if another thread is pending, launch it lock ( Threads ) { // first remove ourselves from the list Threads.Remove(state.Thread); // then launch the next one if applicable. if (Threads.Count > 0) { Thread ct = Threads[0]; ct.Start(new ThreadState { Thread = ct, Entry = entry }); } } })); t.Name = "ls " + entry.FullPath; // we don't want to run multiple ls on the device at the same time, so we // store the thread in a list and launch it only if there's no other thread running. // the thread will launch the next one once it's done. lock ( Threads ) { // add to the list Threads.Add(t); // if it's the only one, launch it. if (Threads.Count == 1) { t.Start(new ThreadState { Thread = t }); } } // and we return null. return(null); }