@@ -7,125 +7,85 @@ import android.support.v4.media.MediaBrowserCompat
77import android.support.v4.media.MediaBrowserCompat.SubscriptionCallback
88import android.util.Log
99import android.widget.Toast
10+ import androidx.lifecycle.ViewModel
11+ import androidx.lifecycle.viewModelScope
12+ import kotlinx.coroutines.launch
1013import java.io.OutputStream
1114import java.io.PrintWriter
12- import java.util.concurrent.ExecutorService
13- import java.util.concurrent.Executors
14- import java.util.concurrent.Semaphore
15+ import kotlin.coroutines.resume
16+ import kotlin.coroutines.suspendCoroutine
1517
1618
17- class MediaBrowseTreeSnapshot (private val context : Context , private val browser : MediaBrowserCompat ) {
19+ class MediaBrowseTreeSnapshot (private val context : Context , private val browser : MediaBrowserCompat ):ViewModel() {
1820 private val TAG = " MediaBrowseTreeSnapshot"
1921
22+
2023 /* *
2124 * Loads the browsers top level children and runs a DFS on them printing out
2225 * each media item's contentes as it is visited.
2326 */
2427 fun takeBrowserSnapshot (outputStream : OutputStream ) {
25- val loaded = Semaphore (1 )
26- val executorService = Executors .newFixedThreadPool(4 )
27- val mItems: MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
28- executorService.execute {
29- try {
30- loaded.acquire()
31- } catch (e: InterruptedException ) {
32- e.printStackTrace()
33- }
34- browser.subscribe(browser.root, object : SubscriptionCallback () {
35- override fun onChildrenLoaded (parentId : String ,
36- children : List <MediaBrowserCompat .MediaItem >) {
37- // Notify the main thread that all of the children have loaded
38- Log .i(TAG , " Children loaded for init" )
39- mItems.addAll(children)
40- loaded.release()
4128
42- super .onChildrenLoaded(parentId, children)
29+ viewModelScope.launch {
30+ val mediaItems: MutableList <MediaBrowserCompat .MediaItem > = getChildNodes(browser.root)
31+ if (mediaItems.isNotEmpty()) {
32+ runDFSOnBrowseTree(mediaItems, outputStream)
33+ for (item in mediaItems) {
34+ Log .i(TAG , item.toString())
4335 }
44- })
45-
46- // Wait for all of the media children to be loaded before starting snapshot
47- try {
48- loaded.acquire()
49- } catch (e: InterruptedException ) {
50- e.printStackTrace()
51- }
52-
53- if (mItems.size > 0 ) {
54- runDFSOnBrowseTree(mItems, executorService, outputStream)
5536 } else {
5637 notifyUser(" No media items found, could not save tree." )
5738 }
5839 }
5940 }
6041
42+ private suspend fun getChildNodes (rootItemMid : String ): MutableList <MediaBrowserCompat .MediaItem > =
43+ suspendCoroutine {
44+ val mediaItems: MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
45+ browser.subscribe(rootItemMid, object : SubscriptionCallback () {
46+ override fun onChildrenLoaded (parentId : String ,
47+ children : List <MediaBrowserCompat .MediaItem >) {
48+ // Notify the main thread that all of the children have loaded
49+ mediaItems.addAll(children)
50+ super .onChildrenLoaded(parentId, children)
51+ it.resume(mediaItems)
52+ }
53+ })
54+ }
55+
6156 /* *
6257 * Kicks off the browse tree depth first search by visiting all of the top level media
6358 * item nodes.
6459 */
65- private fun runDFSOnBrowseTree (mediaItems : MutableList <MediaBrowserCompat .MediaItem >, executorService : ExecutorService , outputStream : OutputStream ) {
60+ private suspend fun runDFSOnBrowseTree (mediaItems : MutableList <MediaBrowserCompat .MediaItem >, outputStream : OutputStream ) {
6661 val printWriter = PrintWriter (outputStream)
6762 printWriter.println (" Root:" )
68- val writeCompleted = Semaphore (1 )
69- executorService.execute {
70- for (item in mediaItems) {
71- try {
72- writeCompleted.acquire()
73- } catch (e: InterruptedException ) {
74- e.printStackTrace()
75- }
76- visitMediaItemNode(item, printWriter, 1 ,
77- executorService)
78- writeCompleted.release()
79- }
80- printWriter.flush()
81- printWriter.close()
82- outputStream.close()
83- notifyUser(" MediaItems saved to specified location." )
63+ for (item in mediaItems) {
64+ visitMediaItemNode(item, printWriter, 1 )
8465 }
66+ printWriter.flush()
67+ printWriter.close()
68+ outputStream.close()
69+ notifyUser(" MediaItems saved to specified location." )
8570 }
8671
8772 /* *
8873 * Visits a media item node by printing out its contents and then visiting all of its children.
8974 */
90- private fun visitMediaItemNode (mediaItem : MediaBrowserCompat .MediaItem ? , printWriter : PrintWriter , depth : Int ,
91- executorService : ExecutorService ) {
75+ private suspend fun visitMediaItemNode (mediaItem : MediaBrowserCompat .MediaItem ? , printWriter : PrintWriter , depth : Int ) {
9276 if (mediaItem != null ) {
9377 printMediaItemDescription(printWriter, mediaItem, depth)
9478 val mid = if (mediaItem.mediaId != null ) mediaItem.mediaId!! else " "
9579
9680 // If a media item is not a leaf continue DFS on it
9781 if (mediaItem.isBrowsable && mid != " " ) {
98- val loaded = Semaphore (1 )
99- try {
100- loaded.acquire()
101- } catch (e: InterruptedException ) {
102- e.printStackTrace()
103- }
104- val mediaChildren: MutableList <MediaBrowserCompat .MediaItem > = ArrayList ()
105- executorService.execute {
106- browser.subscribe(mid,
107- object : SubscriptionCallback () {
108- override fun onChildrenLoaded (parentId : String ,
109- children : List <MediaBrowserCompat .MediaItem >) {
110- // Notify the main thread that all of the children have loaded
111- mediaChildren.addAll(children)
112- loaded.release()
113- super .onChildrenLoaded(parentId, children)
114- }
115- })
116- }
11782
118- // Wait for all of the media children to be loaded before continuing DFS
119- try {
120- loaded.acquire()
121- } catch (e: InterruptedException ) {
122- e.printStackTrace()
123- }
83+ val mediaChildren: MutableList <MediaBrowserCompat .MediaItem > = getChildNodes(mid)
12484
12585 // Run visit on all of the nodes children
12686 for (mediaItemChild in mediaChildren) {
127- visitMediaItemNode(mediaItemChild, printWriter, depth + 1 ,
128- executorService )
87+ visitMediaItemNode(mediaItemChild, printWriter, depth + 1 )
88+ Log .i( TAG , " Visiting: " + mediaItemChild.toString() )
12989 }
13090 }
13191 }
@@ -147,7 +107,6 @@ class MediaBrowseTreeSnapshot(private val context: Context, private val browser:
147107 val infoStr = String .format(
148108 " %sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s" ,
149109 tabStr, titleStr, subTitleStr, mIDStr, uriStr, desStr)
150- Log .i(TAG , " Writing media Item" );
151110 printWriter.println (infoStr)
152111 }
153112
0 commit comments