@@ -7,125 +7,85 @@ import android.support.v4.media.MediaBrowserCompat
7
7
import android.support.v4.media.MediaBrowserCompat.SubscriptionCallback
8
8
import android.util.Log
9
9
import android.widget.Toast
10
+ import androidx.lifecycle.ViewModel
11
+ import androidx.lifecycle.viewModelScope
12
+ import kotlinx.coroutines.launch
10
13
import java.io.OutputStream
11
14
import 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
15
17
16
18
17
- class MediaBrowseTreeSnapshot (private val context : Context , private val browser : MediaBrowserCompat ) {
19
+ class MediaBrowseTreeSnapshot (private val context : Context , private val browser : MediaBrowserCompat ):ViewModel() {
18
20
private val TAG = " MediaBrowseTreeSnapshot"
19
21
22
+
20
23
/* *
21
24
* Loads the browsers top level children and runs a DFS on them printing out
22
25
* each media item's contentes as it is visited.
23
26
*/
24
27
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()
41
28
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())
43
35
}
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)
55
36
} else {
56
37
notifyUser(" No media items found, could not save tree." )
57
38
}
58
39
}
59
40
}
60
41
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
+
61
56
/* *
62
57
* Kicks off the browse tree depth first search by visiting all of the top level media
63
58
* item nodes.
64
59
*/
65
- private fun runDFSOnBrowseTree (mediaItems : MutableList <MediaBrowserCompat .MediaItem >, executorService : ExecutorService , outputStream : OutputStream ) {
60
+ private suspend fun runDFSOnBrowseTree (mediaItems : MutableList <MediaBrowserCompat .MediaItem >, outputStream : OutputStream ) {
66
61
val printWriter = PrintWriter (outputStream)
67
62
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 )
84
65
}
66
+ printWriter.flush()
67
+ printWriter.close()
68
+ outputStream.close()
69
+ notifyUser(" MediaItems saved to specified location." )
85
70
}
86
71
87
72
/* *
88
73
* Visits a media item node by printing out its contents and then visiting all of its children.
89
74
*/
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 ) {
92
76
if (mediaItem != null ) {
93
77
printMediaItemDescription(printWriter, mediaItem, depth)
94
78
val mid = if (mediaItem.mediaId != null ) mediaItem.mediaId!! else " "
95
79
96
80
// If a media item is not a leaf continue DFS on it
97
81
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
- }
117
82
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)
124
84
125
85
// Run visit on all of the nodes children
126
86
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() )
129
89
}
130
90
}
131
91
}
@@ -147,7 +107,6 @@ class MediaBrowseTreeSnapshot(private val context: Context, private val browser:
147
107
val infoStr = String .format(
148
108
" %sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s" ,
149
109
tabStr, titleStr, subTitleStr, mIDStr, uriStr, desStr)
150
- Log .i(TAG , " Writing media Item" );
151
110
printWriter.println (infoStr)
152
111
}
153
112
0 commit comments