12df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal/* 22df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * Copyright (C) 2016 The Android Open Source Project 32df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * 42df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License"); 52df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * you may not use this file except in compliance with the License. 62df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * You may obtain a copy of the License at 72df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * 82df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * http://www.apache.org/licenses/LICENSE-2.0 92df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * 102df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * Unless required by applicable law or agreed to in writing, software 112df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS, 122df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * See the License for the specific language governing permissions and 142df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal * limitations under the License. 152df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal */ 162df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 172df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalpackage com.android.bluetooth.avrcpcontroller; 182df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 19c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport android.media.MediaDescription; 202df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport android.media.browse.MediaBrowser; 212df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport android.media.browse.MediaBrowser.MediaItem; 222df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport android.os.Bundle; 232df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport android.service.media.MediaBrowserService.Result; 242df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport android.util.Log; 252df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 262df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport java.util.ArrayList; 272df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport java.util.HashMap; 282df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalimport java.util.List; 292df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 302df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Browsing hierarchy. 312df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Root: 322df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Player1: 332df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Now_Playing: 342df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// MediaItem1 352df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// MediaItem2 362df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Folder1 372df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Folder2 382df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// .... 392df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// Player2 402df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal// .... 412df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalpublic class BrowseTree { 422df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal private static final String TAG = "BrowseTree"; 43a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo private static final boolean DBG = false; 44a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo private static final boolean VDBG = false; 452df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 462df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final int DIRECTION_DOWN = 0; 472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final int DIRECTION_UP = 1; 488e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal public static final int DIRECTION_SAME = 2; 492df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final int DIRECTION_UNKNOWN = -1; 502df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 512df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final String ROOT = "__ROOT__"; 522df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final String NOW_PLAYING_PREFIX = "NOW_PLAYING"; 532df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public static final String PLAYER_PREFIX = "PLAYER"; 542df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 552df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Static instance of Folder ID <-> Folder Instance (for navigation purposes) 562df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal private final HashMap<String, BrowseNode> mBrowseMap = new HashMap<String, BrowseNode>(); 572df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal private BrowseNode mCurrentBrowseNode; 58a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal private BrowseNode mCurrentBrowsedPlayer; 59a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal private BrowseNode mCurrentAddressedPlayer; 602df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 612df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseTree() { 628e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal } 638e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 648e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal public void init() { 652df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal MediaDescription.Builder mdb = new MediaDescription.Builder(); 662df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setMediaId(ROOT); 672df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setTitle(ROOT); 682df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Bundle mdBundle = new Bundle(); 692df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdBundle.putString(AvrcpControllerService.MEDIA_ITEM_UID_KEY, ROOT); 702df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setExtras(mdBundle); 712df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mBrowseMap.put(ROOT, new BrowseNode(new MediaItem(mdb.build(), MediaItem.FLAG_BROWSABLE))); 722df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mCurrentBrowseNode = mBrowseMap.get(ROOT); 732df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 742df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 758e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal public void clear() { 768e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal // Clearing the map should garbage collect everything. 778e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal mBrowseMap.clear(); 788e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal } 798e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 802df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Each node of the tree is represented by Folder ID, Folder Name and the children. 812df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal class BrowseNode { 822df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // MediaItem to store the media related details. 832df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal MediaItem mItem; 842df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 852df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Type of this browse node. 862df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Since Media APIs do not define the player separately we define that 872df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // distinction here. 882df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal boolean mIsPlayer = false; 892df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 908e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal // If this folder is currently cached, can be useful to return the contents 918e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal // without doing another fetch. 928e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal boolean mCached = false; 938e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 942df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Result object if this node is not loaded yet. This result object will be used 952df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // once loading is finished. 962df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Result<List<MediaItem>> mResult = null; 972df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 982df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // List of children. 992df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal final List<BrowseNode> mChildren = new ArrayList<BrowseNode>(); 1002df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1012df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode(MediaItem item) { 1022df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mItem = item; 1032df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1042df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1052df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode(AvrcpPlayer player) { 1062df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mIsPlayer = true; 1072df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1082df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Transform the player into a item. 1092df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal MediaDescription.Builder mdb = new MediaDescription.Builder(); 1102df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Bundle mdExtra = new Bundle(); 1112df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal String playerKey = PLAYER_PREFIX + player.getId(); 1122df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdExtra.putString(AvrcpControllerService.MEDIA_ITEM_UID_KEY, playerKey); 1132df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setExtras(mdExtra); 1142df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setMediaId(playerKey); 1152df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mdb.setTitle(player.getName()); 1162df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mItem = new MediaBrowser.MediaItem(mdb.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE); 1172df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1182df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1192df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized List<BrowseNode> getChildren() { 1202df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mChildren; 1212df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1222df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1232df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized boolean isChild(BrowseNode node) { 1242df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal for (BrowseNode bn : mChildren) { 1252df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (bn.equals(node)) { 1262df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return true; 1272df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1282df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1292df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return false; 1302df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1312df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1328e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal synchronized boolean isCached() { 1338e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal return mCached; 1348e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal } 1358e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 1368e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal synchronized void setCached(boolean cached) { 1378e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal mCached = cached; 1388e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal } 1398e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 1402df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Fetch the Unique UID for this item, this is unique across all elements in the tree. 1412df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized String getID() { 1422df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mItem.getDescription().getMediaId(); 1432df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1442df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1452df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Get the BT Player ID associated with this node. 1462df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized int getPlayerID() { 1472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return Integer.parseInt(getID().replace(PLAYER_PREFIX, "")); 1482df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1492df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1502df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Fetch the Folder UID that can be used to fetch folder listing via bluetooth. 1512df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // This may not be unique hence this combined with direction will define the 1522df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // browsing here. 1532df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized String getFolderUID() { 154c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return mItem.getDescription() 155c4fbd756e2645147470c486ae96f2253f5e13a52Jack He .getExtras() 156c4fbd756e2645147470c486ae96f2253f5e13a52Jack He .getString(AvrcpControllerService.MEDIA_ITEM_UID_KEY); 1572df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1582df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1592df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized MediaItem getMediaItem() { 1602df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mItem; 1612df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1622df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1632df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized boolean isPlayer() { 1642df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mIsPlayer; 1652df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1662df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1672df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized boolean isNowPlaying() { 1682df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return getID().startsWith(NOW_PLAYING_PREFIX); 1692df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1702df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1712df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal @Override 1722df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public boolean equals(Object other) { 1732df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (!(other instanceof BrowseNode)) { 1742df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return false; 1752df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1762df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode otherNode = (BrowseNode) other; 1772df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return getID().equals(otherNode.getID()); 1782df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1792df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1802df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal @Override 1812df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public String toString() { 182a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo if (VDBG) { 183a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo return "ID: " + getID() + " desc: " + mItem; 184a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo } else { 185a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo return "ID: " + getID(); 186a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo } 1872df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1882df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1892df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1902df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized <E> void refreshChildren(String parentID, List<E> children) { 1912df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode parent = findFolderByIDLocked(parentID); 1922df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (parent == null) { 1932df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.w(TAG, "parent not found for parentID " + parentID); 1942df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return; 1952df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1962df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal refreshChildren(parent, children); 1972df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 1982df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 1992df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized <E> void refreshChildren(BrowseNode parent, List<E> children) { 2002df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (children == null) { 2012df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.e(TAG, "children cannot be null "); 2022df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return; 2032df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2042df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2052df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal List<BrowseNode> bnList = new ArrayList<BrowseNode>(); 2062df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal for (E child : children) { 2072df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (child instanceof MediaItem) { 2082df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal bnList.add(new BrowseNode((MediaItem) child)); 2092df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } else if (child instanceof AvrcpPlayer) { 2102df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal bnList.add(new BrowseNode((AvrcpPlayer) child)); 2112df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2122df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2132df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2142df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal String parentID = parent.getID(); 2152df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Make sure that the child list is clean. 216a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo if (VDBG) { 2172df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.d(TAG, "parent " + parentID + " child list " + parent.getChildren()); 2182df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2192df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2202df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal addChildrenLocked(parent, bnList); 2212df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal List<MediaItem> childrenList = new ArrayList<MediaItem>(); 2222df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal for (BrowseNode bn : parent.getChildren()) { 2232df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal childrenList.add(bn.getMediaItem()); 2242df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2258e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 2268e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal parent.setCached(true); 2272df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2282df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2292df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized BrowseNode findBrowseNodeByID(String parentID) { 2302df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode bn = mBrowseMap.get(parentID); 2312df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (bn == null) { 2322df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.e(TAG, "folder " + parentID + " not found!"); 2332df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return null; 2342df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 235a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo if (VDBG) { 2362df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.d(TAG, "Browse map: " + mBrowseMap); 2372df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2382df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return bn; 2392df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2402df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2412df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode findFolderByIDLocked(String parentID) { 2422df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mBrowseMap.get(parentID); 2432df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2442df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2452df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal void addChildrenLocked(BrowseNode parent, List<BrowseNode> items) { 2462df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Remove existing children and then add the new children. 2472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal for (BrowseNode c : parent.getChildren()) { 2482df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mBrowseMap.remove(c.getID()); 2492df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2502df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal parent.getChildren().clear(); 2512df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2522df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal for (BrowseNode bn : items) { 2532df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal parent.getChildren().add(bn); 2542df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mBrowseMap.put(bn.getID(), bn); 2552df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2562df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2572df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2582df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized int getDirection(String toUID) { 2592df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode fromFolder = mCurrentBrowseNode; 2602df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode toFolder = findFolderByIDLocked(toUID); 2612df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (fromFolder == null || toFolder == null) { 2622df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.e(TAG, "from folder " + mCurrentBrowseNode + " or to folder " + toUID + " null!"); 2632df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2642df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2652df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal // Check the relationship. 2662df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (fromFolder.isChild(toFolder)) { 2672df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return DIRECTION_DOWN; 2682df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } else if (toFolder.isChild(fromFolder)) { 2692df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return DIRECTION_UP; 2708e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal } else if (fromFolder.equals(toFolder)) { 2718e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal return DIRECTION_SAME; 2722df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } else { 273a016a2a7ece99211165717d01401a5c1a4c4ac3bJoseph Pirozzo Log.w(TAG, "from folder " + mCurrentBrowseNode + "to folder " + toUID); 2742df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return DIRECTION_UNKNOWN; 2752df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2762df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2772df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2782df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized boolean setCurrentBrowsedFolder(String uid) { 2792df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal BrowseNode bn = findFolderByIDLocked(uid); 2802df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal if (bn == null) { 2812df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal Log.e(TAG, "Setting an unknown browsed folder, ignoring bn " + uid); 2822df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return false; 2832df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2848e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 2858e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal // Set the previous folder as not cached so that we fetch the contents again. 286609f94bb870727471a8c571ede2aa8cbbaf70f76Sanket Agarwal if (!bn.equals(mCurrentBrowseNode)) { 287609f94bb870727471a8c571ede2aa8cbbaf70f76Sanket Agarwal Log.d(TAG, "Set cache false " + bn + " curr " + mCurrentBrowseNode); 288609f94bb870727471a8c571ede2aa8cbbaf70f76Sanket Agarwal mCurrentBrowseNode.setCached(false); 289609f94bb870727471a8c571ede2aa8cbbaf70f76Sanket Agarwal } 2908e509db28e65be858598365b3ad25d08532a32f9Sanket Agarwal 2912df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal mCurrentBrowseNode = bn; 2922df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return true; 2932df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2942df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 2952df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal synchronized BrowseNode getCurrentBrowsedFolder() { 2962df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mCurrentBrowseNode; 2972df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 2982df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal 299a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal synchronized boolean setCurrentBrowsedPlayer(String uid) { 300a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal BrowseNode bn = findFolderByIDLocked(uid); 301a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal if (bn == null) { 302a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal Log.e(TAG, "Setting an unknown browsed player, ignoring bn " + uid); 303a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return false; 304a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 305a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal mCurrentBrowsedPlayer = bn; 306a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return true; 307a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 308a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal 309a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal synchronized BrowseNode getCurrentBrowsedPlayer() { 310a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return mCurrentBrowsedPlayer; 311a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 312a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal 313a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal synchronized boolean setCurrentAddressedPlayer(String uid) { 314a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal BrowseNode bn = findFolderByIDLocked(uid); 315a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal if (bn == null) { 316a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal Log.e(TAG, "Setting an unknown addressed player, ignoring bn " + uid); 317a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return false; 318a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 319a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal mCurrentAddressedPlayer = bn; 320a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return true; 321a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 322a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal 323a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal synchronized BrowseNode getCurrentAddressedPlayer() { 324a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal return mCurrentAddressedPlayer; 325a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal } 326a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal 3272df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal @Override 3282df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal public String toString() { 3292df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal return mBrowseMap.toString(); 3302df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal } 3312df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal} 332