1fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie/* 2fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Copyright (C) 2013 Samsung System LSI 3fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Licensed under the Apache License, Version 2.0 (the "License"); 4fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* you may not use this file except in compliance with the License. 5fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* You may obtain a copy of the License at 6fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 7fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* http://www.apache.org/licenses/LICENSE-2.0 8fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 9fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Unless required by applicable law or agreed to in writing, software 10fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* distributed under the License is distributed on an "AS IS" BASIS, 11fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* See the License for the specific language governing permissions and 13fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* limitations under the License. 14fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*/ 15fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepackage com.android.bluetooth.map; 16fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 17fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.IOException; 18fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.StringWriter; 19fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.io.UnsupportedEncodingException; 20fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.ArrayList; 21fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.Collections; 22fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport java.util.List; 235079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Guptaimport com.android.internal.util.FastXmlSerializer; 24fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 25fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport org.xmlpull.v1.XmlSerializer; 26fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 27fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Log; 28fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 29fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepublic class BluetoothMapMessageListing { 3070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private boolean hasUnread = false; 31fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String TAG = "BluetoothMapMessageListing"; 32326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final boolean D = BluetoothMapService.DEBUG; 33326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 345a60e47497f21f64e6d79420dc4c56c1907df22akschulz private List<BluetoothMapMessageListingElement> mList; 35fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 36fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public BluetoothMapMessageListing(){ 375a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); 38fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 39fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void add(BluetoothMapMessageListingElement element) { 405a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList.add(element); 4170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /* update info regarding whether the list contains unread messages */ 42326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (element.getReadBool()) 4370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 4470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz hasUnread = true; 4570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 46fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 47fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 48fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 49fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * Used to fetch the number of BluetoothMapMessageListingElement elements in the list. 50fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @return the number of elements in the list. 51fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 52fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public int getCount() { 535a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mList != null) 5470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 555a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mList.size(); 5670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 5770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return 0; 5870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 5970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 6070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /** 6170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * does the list contain any unread messages 6270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * @return true if unread messages have been added to the list, else false 6370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz */ 6470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean hasUnread() 6570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 6670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return hasUnread; 67fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 6870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 69326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 70326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 71326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * returns the entire list as a list 72326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return list 73326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 74326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public List<BluetoothMapMessageListingElement> getList(){ 755a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mList; 76326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 77326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 78fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 79fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 80fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * formatted XML-string in a trimmed byte array 81fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 825a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param version the version as a string. 835a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Set the listing version to e.g. "1.0" or "1.1". 845a60e47497f21f64e6d79420dc4c56c1907df22akschulz * To make this future proof, no check is added to validate the value, hence be careful. 85fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @return a reference to the encoded byte array. 86fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @throws UnsupportedEncodingException 87fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * if UTF-8 encoding is unsupported on the platform. 88fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 895a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: Remove includeThreadId when MAP-IM is adopted 905a60e47497f21f64e6d79420dc4c56c1907df22akschulz public byte[] encode(boolean includeThreadId, String version) throws UnsupportedEncodingException { 91fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie StringWriter sw = new StringWriter(); 925079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta XmlSerializer xmlMsgElement = new FastXmlSerializer(); 93fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 94fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlMsgElement.setOutput(sw); 955079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.startDocument("UTF-8", true); 965079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 975079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.startTag(null, "MAP-msg-listing"); 985a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlMsgElement.attribute(null, "version", version); 99fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // Do the XML encoding of list 1005a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (BluetoothMapMessageListingElement element : mList) { 101326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde element.encode(xmlMsgElement, includeThreadId); // Append the list element 102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1035079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.endTag(null, "MAP-msg-listing"); 104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlMsgElement.endDocument(); 105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 106326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalStateException e) { 108326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 110326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return sw.toString().getBytes("UTF-8"); 113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void sort() { 1165a60e47497f21f64e6d79420dc4c56c1907df22akschulz Collections.sort(mList); 117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void segment(int count, int offset) { 1205a60e47497f21f64e6d79420dc4c56c1907df22akschulz count = Math.min(count, mList.size() - offset); 121326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (count > 0) { 1225a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = mList.subList(offset, offset + count); 1235a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mList == null) { 1245a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); // Return an empty list 125326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(offset > mList.size()) { 1285a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); 129c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta Log.d(TAG, "offset greater than list size. Returning empty list"); 130c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta } else { 1315a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = mList.subList(offset, mList.size()); 132c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta } 133fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie} 136