Skip to content

Commit ac86dc4

Browse files
author
Leo Neat
committed
Working with race condition
1 parent c979015 commit ac86dc4

File tree

1 file changed

+98
-77
lines changed

1 file changed

+98
-77
lines changed

mediacontroller/src/main/java/com/example/android/mediacontroller/MediaAppControllerActivity.java

Lines changed: 98 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ public class MediaAppControllerActivity extends AppCompatActivity {
146146
private MediaBrowserCompat mBrowserExtraSuggested;
147147
private AudioFocusHelper mAudioFocusHelper;
148148
private RatingUiHelper mRatingUiHelper;
149-
private CustomControlsAdapter mCustomControlsAdapter = new CustomControlsAdapter();
150-
private BrowseMediaItemsAdapter mBrowseMediaItemsAdapter = new BrowseMediaItemsAdapter();
151-
private BrowseMediaItemsAdapter mBrowseMediaItemsExtraSuggestedAdapter = new BrowseMediaItemsAdapter();
152-
private SearchMediaItemsAdapter mSearchMediaItemsAdapter = new SearchMediaItemsAdapter();
149+
private final CustomControlsAdapter mCustomControlsAdapter = new CustomControlsAdapter();
150+
private final BrowseMediaItemsAdapter mBrowseMediaItemsAdapter = new BrowseMediaItemsAdapter();
151+
private final BrowseMediaItemsAdapter mBrowseMediaItemsExtraSuggestedAdapter = new BrowseMediaItemsAdapter();
152+
private final SearchMediaItemsAdapter mSearchMediaItemsAdapter = new SearchMediaItemsAdapter();
153153

154154
private ViewPager mViewPager;
155155
private Spinner mInputTypeView;
@@ -275,6 +275,7 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
275275
mBrowseMediaItemsAdapter.init(findViewById(R.id.media_browse_tree_top),
276276
findViewById(R.id.media_browse_tree_up), findViewById(R.id.media_browse_tree_save));
277277

278+
278279
final RecyclerView browseTreeListExtraSuggested = findViewById(R.id.media_items_list_extra_suggested);
279280
browseTreeListExtraSuggested.setLayoutManager(new LinearLayoutManager(this));
280281
browseTreeListExtraSuggested.setHasFixedSize(true);
@@ -297,12 +298,10 @@ public Object instantiateItem(@NonNull ViewGroup container, int position) {
297298
}
298299

299300

300-
301301
@Override
302302
public void onRequestPermissionsResult(int requestCode,
303303
@NonNull String[] permissions,
304-
@NonNull int[] grantResults)
305-
{
304+
@NonNull int[] grantResults) {
306305
super.onRequestPermissionsResult(requestCode,
307306
permissions,
308307
grantResults);
@@ -314,8 +313,7 @@ public void onRequestPermissionsResult(int requestCode,
314313
"Storage Permission Granted, can save browse tree.",
315314
Toast.LENGTH_SHORT)
316315
.show();
317-
}
318-
else {
316+
} else {
319317
Toast.makeText(getApplicationContext(),
320318
"Storage Permission Denied, can not save browse tree to file.",
321319
Toast.LENGTH_SHORT)
@@ -440,6 +438,7 @@ private void setupMedia() {
440438
public void onConnected() {
441439
setupMediaController();
442440
mBrowseMediaItemsAdapter.setRoot(mBrowser.getRoot());
441+
Log.i(TAG, "Root of browse tree connected");
443442
}
444443

445444
@Override
@@ -1155,13 +1154,14 @@ private class BrowseMediaItemsAdapter extends
11551154
RecyclerView.Adapter<BrowseMediaItemsAdapter.ViewHolder> {
11561155

11571156
private List<MediaBrowserCompat.MediaItem> mItems;
1158-
private Stack<String> mNodes = new Stack<>();
1157+
private final Stack<String> mNodes = new Stack<>();
11591158

11601159
MediaBrowserCompat.SubscriptionCallback callback =
11611160
new MediaBrowserCompat.SubscriptionCallback() {
11621161
@Override
11631162
public void onChildrenLoaded(@NonNull String parentId,
11641163
@NonNull List<MediaItem> children) {
1164+
Log.i(TAG, "Children loaded.");
11651165
updateItemsEmptyIfNull(children);
11661166
}
11671167
};
@@ -1174,9 +1174,13 @@ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
11741174
.inflate(R.layout.media_browse_item, parent, false));
11751175
}
11761176

1177+
1178+
11771179
@Override
1178-
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
1180+
public void onBindViewHolder(@NonNull ViewHolder holder, int position){
1181+
Log.i(TAG, "On Bind view holder");
11791182
if (mNodes.size() == 0) {
1183+
Log.i(TAG, "Setting to no browser");
11801184
holder.name.setText(getString(R.string.media_no_browser));
11811185
holder.name.setVisibility(View.VISIBLE);
11821186
holder.description.setVisibility(View.GONE);
@@ -1186,6 +1190,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
11861190
return;
11871191
}
11881192
if (mItems == null) {
1193+
Log.i(TAG, "Setting to loading");
11891194
holder.name.setText(getString(R.string.media_browse_tree_loading));
11901195
holder.name.setVisibility(View.VISIBLE);
11911196
holder.description.setVisibility(View.GONE);
@@ -1195,6 +1200,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
11951200
return;
11961201
}
11971202
if (mItems.size() == 0) {
1203+
Log.i(TAG, "Setting to empty");
11981204
holder.name.setText(getString(R.string.media_browse_tree_empty));
11991205
holder.name.setVisibility(View.VISIBLE);
12001206
holder.description.setVisibility(View.GONE);
@@ -1203,7 +1209,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
12031209
});
12041210
return;
12051211
}
1206-
1212+
Log.i(TAG, "Populating media items");
12071213
final MediaBrowserCompat.MediaItem item = mItems.get(position);
12081214
holder.name.setText(item.getDescription().getTitle());
12091215
holder.name.setVisibility(View.VISIBLE);
@@ -1234,6 +1240,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
12341240
});
12351241
}
12361242

1243+
12371244
@Override
12381245
public int getItemCount() {
12391246
if (mNodes.size() == 0 || mItems == null || mItems.size() == 0) {
@@ -1244,13 +1251,15 @@ public int getItemCount() {
12441251

12451252
void updateItemsEmptyIfNull(List<MediaBrowserCompat.MediaItem> items) {
12461253
if (items == null) {
1254+
Log.i(TAG, "Trying to update an null list");
12471255
updateItems(Collections.emptyList());
12481256
} else {
12491257
updateItems(items);
12501258
}
12511259
}
12521260

12531261
void updateItems(List<MediaBrowserCompat.MediaItem> items) {
1262+
Log.i(TAG, "Updating items");
12541263
mItems = items;
12551264
notifyDataSetChanged();
12561265
}
@@ -1283,88 +1292,91 @@ void init(View topButtonView, View upButtonView, View saveButtonView) {
12831292
});
12841293
}
12851294
if (saveButtonView != null) {
1286-
notifyDataSetChanged();
12871295

12881296
// Go to root of browse tree
1297+
// TODO: Fix race condition with subscription callback
12891298
unsubscribe();
12901299
while (mNodes.size() > 1) {
12911300
mNodes.pop();
12921301
}
12931302
subscribe();
1294-
12951303
saveButtonView.setOnClickListener(
12961304
v -> {
12971305

12981306
if (mNodes.isEmpty()) {
12991307
Toast toast =
13001308
Toast.makeText(
1301-
getApplicationContext(), "List Empty, nothing saved! ", Toast.LENGTH_LONG);
1309+
getApplicationContext(),
1310+
"List Empty, nothing saved! ", Toast.LENGTH_LONG);
13021311
toast.setMargin(50, 50);
13031312
toast.show();
13041313
return;
13051314
}
1315+
1316+
// Create output file
13061317
File root = android.os.Environment.getExternalStorageDirectory();
13071318
String dirs_path = root.getAbsolutePath() + "/Temp/";
13081319
File dirs = new File(dirs_path);
1309-
File file = new File(dirs.getAbsolutePath(), "_BrowseTreeContent.txt");
1310-
if(file.exists()){
1320+
dirs.mkdirs();
1321+
File file = new File(dirs.getAbsolutePath(),
1322+
"_BrowseTreeContent.txt");
1323+
if (file.exists()) {
13111324
file.delete();
13121325
}
13131326
try {
13141327
final FileOutputStream f = new FileOutputStream(file);
1315-
1316-
PrintWriter pw = new PrintWriter(f);
1317-
// We print the file path at the beginning of the file so that we can use it
1318-
// to pull the file from platform to local computer.
1319-
1320-
pw.println(file.toString());
1321-
if(mItems == null){
1322-
Toast toast =
1323-
Toast.makeText(
1324-
getApplicationContext(),
1325-
"No media items found, could not save tree.",
1326-
Toast.LENGTH_LONG);
1327-
toast.setMargin(50, 50);
1328-
toast.show();
1329-
return;
1330-
}
1331-
pw.println("Root:");
1332-
Semaphore writeCompleted = new Semaphore(1);
1333-
ExecutorService executorService = Executors.newFixedThreadPool(4);
1334-
executorService.execute(new Runnable() {
1335-
@Override
1336-
public void run() {
1337-
for (MediaBrowserCompat.MediaItem item : mItems) {
1338-
try {
1339-
writeCompleted.acquire();
1340-
} catch (InterruptedException e) {
1341-
e.printStackTrace();
1342-
}
1343-
writeMediaItemToFile(item, pw, 1, executorService);
1344-
writeCompleted.release();
1345-
1328+
PrintWriter pw = new PrintWriter(f);
1329+
if(mItems == null){
1330+
Log.i(TAG, "Nodes: " + mNodes.toString());
1331+
subscribe();
1332+
Toast toast =
1333+
Toast.makeText(
1334+
getApplicationContext(),
1335+
"No media items found, could not save tree.",
1336+
Toast.LENGTH_LONG);
1337+
toast.setMargin(50, 50);
1338+
toast.show();
1339+
return;
13461340
}
1347-
1348-
Log.i(TAG, "CLOSING FILE");
1349-
pw.flush();
1350-
pw.close();
1351-
try {
1352-
f.close();
1353-
} catch (IOException e) {
1354-
e.printStackTrace();
1355-
}
1356-
runOnUiThread(new Runnable() {
1341+
pw.println("Root:");
1342+
Semaphore writeCompleted = new Semaphore(1);
1343+
ExecutorService executorService =
1344+
Executors.newFixedThreadPool(4);
1345+
executorService.execute(new Runnable() {
1346+
@Override
13571347
public void run() {
1358-
Toast toast =
1359-
Toast.makeText(
1360-
getApplicationContext(),
1361-
"MediaItems saved to " + file.getAbsolutePath(),
1362-
Toast.LENGTH_LONG);
1363-
toast.setMargin(50, 50);
1364-
toast.show();
1348+
for (MediaBrowserCompat.MediaItem item : mItems) {
1349+
try {
1350+
writeCompleted.acquire();
1351+
} catch (InterruptedException e) {
1352+
e.printStackTrace();
1353+
}
1354+
writeMediaItemToFile(item, pw, 1,
1355+
executorService);
1356+
writeCompleted.release();
1357+
1358+
}
1359+
pw.flush();
1360+
pw.close();
1361+
try {
1362+
f.close();
1363+
} catch (IOException e) {
1364+
e.printStackTrace();
1365+
}
1366+
runOnUiThread(new Runnable() {
1367+
public void run() {
1368+
Toast toast =
1369+
Toast.makeText(
1370+
getApplicationContext(),
1371+
"MediaItems saved to " +
1372+
file.getAbsolutePath(),
1373+
Toast.LENGTH_LONG);
1374+
toast.setMargin(50, 50);
1375+
toast.show();
1376+
}
1377+
});
13651378
}
13661379
});
1367-
}});
13681380
} catch (FileNotFoundException e) {
13691381
e.printStackTrace();
13701382
}
@@ -1374,13 +1386,15 @@ public void run() {
13741386
}
13751387

13761388
@RequiresApi(api = Build.VERSION_CODES.N)
1377-
private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter, int depth, ExecutorService executorService){
1378-
if(mediaItem != null) {
1389+
private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter, int depth,
1390+
ExecutorService executorService) {
1391+
if (mediaItem != null) {
13791392
MediaDescriptionCompat descriptionCompat = mediaItem.getDescription();
13801393
if (descriptionCompat != null) {
13811394

13821395
// Tab the media item to the respective depth
1383-
String tabStr = new String(new char[depth]).replace("\0", "\t");
1396+
String tabStr = new String(new char[depth]).replace("\0",
1397+
"\t");
13841398

13851399
String titleStr = descriptionCompat.getTitle() != null
13861400
? descriptionCompat.getTitle().toString()
@@ -1389,18 +1403,21 @@ private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter,
13891403
? descriptionCompat.getSubtitle().toString()
13901404
: "NAN";
13911405
String mIDStr = descriptionCompat.getMediaId() != null
1392-
? descriptionCompat.getMediaId().toString()
1406+
? descriptionCompat.getMediaId()
13931407
: "NAN";
13941408
String uriStr = descriptionCompat.getMediaUri() != null
13951409
? descriptionCompat.getMediaUri().toString()
13961410
: "NAN";
13971411
String desStr = descriptionCompat.getDescription() != null
13981412
? descriptionCompat.getDescription().toString()
13991413
: "NAN";
1400-
String infoStr = String.format("%sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s", tabStr, titleStr, subTitleStr, mIDStr, uriStr, desStr);
1414+
String infoStr = String.format(
1415+
"%sTitle:%s,Subtitle:%s,MediaId:%s,URI:%s,Description:%s",
1416+
tabStr, titleStr, subTitleStr, mIDStr, uriStr, desStr);
14011417
Log.i(TAG, "Logging media item: " + infoStr + " at depth: " + depth);
14021418
printWriter.println(infoStr);
14031419
}
1420+
// If a media item is not a leaf continue DFS on it
14041421
if (mediaItem.isBrowsable()) {
14051422
Log.i(TAG, "Media Item is browseable");
14061423
Semaphore loaded = new Semaphore(1);
@@ -1413,10 +1430,12 @@ private void writeMediaItemToFile(MediaItem mediaItem, PrintWriter printWriter,
14131430
executorService.execute(new Runnable() {
14141431
@Override
14151432
public void run() {
1416-
mBrowser.subscribe(mediaItem.getMediaId(), new MediaBrowserCompat.SubscriptionCallback() {
1433+
mBrowser.subscribe(mediaItem.getMediaId(),
1434+
new MediaBrowserCompat.SubscriptionCallback() {
14171435
@Override
1418-
public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaItem> children) {
1419-
Log.i(TAG, "Children loaded");
1436+
public void onChildrenLoaded(@NonNull String parentId,
1437+
@NonNull List<MediaItem> children) {
1438+
// Notify the main thread that all of the children have loaded
14201439
mChildren.addAll(children);
14211440
loaded.release();
14221441
super.onChildrenLoaded(parentId, children);
@@ -1425,18 +1444,20 @@ public void onChildrenLoaded(@NonNull String parentId, @NonNull List
14251444
}
14261445
});
14271446

1447+
// Wait for all of the media children to be loaded before continuing DFS
14281448
try {
14291449
loaded.acquire();
14301450
} catch (InterruptedException e) {
14311451
e.printStackTrace();
14321452
}
1433-
Log.i(TAG, "Childeren finished loading");
1453+
1454+
// Run DFS on all of the nodes children
14341455
for (MediaItem mediaItemChild : mChildren) {
1435-
writeMediaItemToFile(mediaItemChild, printWriter, depth + 1, executorService);
1456+
writeMediaItemToFile(mediaItemChild, printWriter, depth + 1,
1457+
executorService);
14361458
}
14371459
}
14381460
}
1439-
14401461
}
14411462

14421463
protected void subscribe() {

0 commit comments

Comments
 (0)