/* * Copyright (C) 2015 Samsung System LSI * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.map; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Locale; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import android.util.Log; import android.util.Xml; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; /** * Class to contain a single folder element representation. * */ public class BluetoothMapFolderElement implements Comparable{ private String mName; private BluetoothMapFolderElement mParent = null; private long mFolderId = -1; private boolean mHasSmsMmsContent = false; private boolean mHasImContent = false; private boolean mHasEmailContent = false; private boolean mIgnore = false; private HashMap mSubFolders; private static final boolean D = BluetoothMapService.DEBUG; private static final boolean V = BluetoothMapService.VERBOSE; private final static String TAG = "BluetoothMapFolderElement"; public BluetoothMapFolderElement( String name, BluetoothMapFolderElement parrent){ this.mName = name; this.mParent = parrent; mSubFolders = new HashMap(); } public void setIngore(boolean ignore) { mIgnore = ignore; } public boolean shouldIgnore() { return mIgnore; } public String getName() { return mName; } public boolean hasSmsMmsContent(){ return mHasSmsMmsContent; } public long getFolderId(){ return mFolderId; } public boolean hasEmailContent(){ return mHasEmailContent; } public void setFolderId(long folderId) { this.mFolderId = folderId; } public void setHasSmsMmsContent(boolean hasSmsMmsContent) { this.mHasSmsMmsContent = hasSmsMmsContent; } public void setHasEmailContent(boolean hasEmailContent) { this.mHasEmailContent = hasEmailContent; } public void setHasImContent(boolean hasImContent) { this.mHasImContent = hasImContent; } public boolean hasImContent(){ return mHasImContent; } /** * Fetch the parent folder. * @return the parent folder or null if we are at the root folder. */ public BluetoothMapFolderElement getParent() { return mParent; } /** * Build the full path to this folder * @return a string representing the full path. */ public String getFullPath() { StringBuilder sb = new StringBuilder(mName); BluetoothMapFolderElement current = mParent; while(current != null) { if(current.getParent() != null) { sb.insert(0, current.mName + "/"); } current = current.getParent(); } //sb.insert(0, "/"); Should this be included? The MAP spec. do not include it in examples. return sb.toString(); } public BluetoothMapFolderElement getFolderByName(String name) { BluetoothMapFolderElement folderElement = this.getRoot(); folderElement = folderElement.getSubFolder("telecom"); folderElement = folderElement.getSubFolder("msg"); folderElement = folderElement.getSubFolder(name); if (folderElement != null && folderElement.getFolderId() == -1 ) folderElement = null; return folderElement; } public BluetoothMapFolderElement getFolderById(long id) { return getFolderById(id, this); } public static BluetoothMapFolderElement getFolderById(long id, BluetoothMapFolderElement folderStructure) { if(folderStructure == null) { return null; } return findFolderById(id, folderStructure.getRoot()); } private static BluetoothMapFolderElement findFolderById(long id, BluetoothMapFolderElement folder) { if(folder.getFolderId() == id) { return folder; } /* Else */ for(BluetoothMapFolderElement subFolder : folder.mSubFolders.values().toArray( new BluetoothMapFolderElement[folder.mSubFolders.size()])) { BluetoothMapFolderElement ret = findFolderById(id, subFolder); if(ret != null) { return ret; } } return null; } /** * Fetch the root folder. * @return the root folder. */ public BluetoothMapFolderElement getRoot() { BluetoothMapFolderElement rootFolder = this; while(rootFolder.getParent() != null) rootFolder = rootFolder.getParent(); return rootFolder; } /** * Add a virtual folder. * @param name the name of the folder to add. * @return the added folder element. */ public BluetoothMapFolderElement addFolder(String name){ name = name.toLowerCase(Locale.US); BluetoothMapFolderElement newFolder = mSubFolders.get(name); if(newFolder == null) { if(D) Log.i(TAG,"addFolder():" + name); newFolder = new BluetoothMapFolderElement(name, this); mSubFolders.put(name, newFolder); } else { if(D) Log.i(TAG,"addFolder():" + name + " already added"); } return newFolder; } /** * Add a sms/mms folder. * @param name the name of the folder to add. * @return the added folder element. */ public BluetoothMapFolderElement addSmsMmsFolder(String name){ if(D) Log.i(TAG,"addSmsMmsFolder()"); BluetoothMapFolderElement newFolder = addFolder(name); newFolder.setHasSmsMmsContent(true); return newFolder; } /** * Add a im folder. * @param name the name of the folder to add. * @return the added folder element. */ public BluetoothMapFolderElement addImFolder(String name, long idFolder){ if(D) Log.i(TAG,"addImFolder() id = " + idFolder); BluetoothMapFolderElement newFolder = addFolder(name); newFolder.setHasImContent(true); newFolder.setFolderId(idFolder); return newFolder; } /** * Add an Email folder. * @param name the name of the folder to add. * @return the added folder element. */ public BluetoothMapFolderElement addEmailFolder(String name, long emailFolderId){ if(V) Log.v(TAG,"addEmailFolder() id = " + emailFolderId); BluetoothMapFolderElement newFolder = addFolder(name); newFolder.setFolderId(emailFolderId); newFolder.setHasEmailContent(true); return newFolder; } /** * Fetch the number of sub folders. * @return returns the number of sub folders. */ public int getSubFolderCount(){ return mSubFolders.size(); } /** * Returns the subFolder element matching the supplied folder name. * @param folderName the name of the subFolder to find. * @return the subFolder element if found {@code null} otherwise. */ public BluetoothMapFolderElement getSubFolder(String folderName){ return mSubFolders.get(folderName.toLowerCase()); } public byte[] encode(int offset, int count) throws UnsupportedEncodingException { StringWriter sw = new StringWriter(); XmlSerializer xmlMsgElement = new FastXmlSerializer(); int i, stopIndex; // We need index based access to the subFolders BluetoothMapFolderElement[] folders = mSubFolders.values().toArray(new BluetoothMapFolderElement[mSubFolders.size()]); if(offset > mSubFolders.size()) throw new IllegalArgumentException("FolderListingEncode: offset > subFolders.size()"); stopIndex = offset + count; if(stopIndex > mSubFolders.size()) stopIndex = mSubFolders.size(); try { xmlMsgElement.setOutput(sw); xmlMsgElement.startDocument("UTF-8", true); xmlMsgElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); xmlMsgElement.startTag(null, "folder-listing"); xmlMsgElement.attribute(null, "version", BluetoothMapUtils.MAP_V10_STR); for(i = offset; i