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 Xieimport android.util.Xml; 29fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 30fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepublic class BluetoothMapMessageListing { 3170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private boolean hasUnread = false; 32fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String TAG = "BluetoothMapMessageListing"; 33326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final boolean D = BluetoothMapService.DEBUG; 34326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 355a60e47497f21f64e6d79420dc4c56c1907df22akschulz private List<BluetoothMapMessageListingElement> mList; 36fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 37fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public BluetoothMapMessageListing(){ 385a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); 39fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 40fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void add(BluetoothMapMessageListingElement element) { 415a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList.add(element); 4270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /* update info regarding whether the list contains unread messages */ 43326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (element.getReadBool()) 4470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 4570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz hasUnread = true; 4670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 47fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 48fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 49fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 50fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * Used to fetch the number of BluetoothMapMessageListingElement elements in the list. 51fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @return the number of elements in the list. 52fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 53fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public int getCount() { 545a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mList != null) 5570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 565a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mList.size(); 5770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 5870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return 0; 5970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 6070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 6170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /** 6270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * does the list contain any unread messages 6370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * @return true if unread messages have been added to the list, else false 6470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz */ 6570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean hasUnread() 6670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz { 6770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return hasUnread; 68fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 6970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 70326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 71326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 72326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * returns the entire list as a list 73326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return list 74326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 75326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public List<BluetoothMapMessageListingElement> getList(){ 765a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mList; 77326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 78326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 79fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 80fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8 81fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * formatted XML-string in a trimmed byte array 82fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 835a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param version the version as a string. 845a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Set the listing version to e.g. "1.0" or "1.1". 855a60e47497f21f64e6d79420dc4c56c1907df22akschulz * To make this future proof, no check is added to validate the value, hence be careful. 86fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @return a reference to the encoded byte array. 87fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * @throws UnsupportedEncodingException 88fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * if UTF-8 encoding is unsupported on the platform. 89fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 905a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: Remove includeThreadId when MAP-IM is adopted 915a60e47497f21f64e6d79420dc4c56c1907df22akschulz public byte[] encode(boolean includeThreadId, String version) throws UnsupportedEncodingException { 92fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie StringWriter sw = new StringWriter(); 935079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta XmlSerializer xmlMsgElement = new FastXmlSerializer(); 94fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 95fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlMsgElement.setOutput(sw); 965079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.startDocument("UTF-8", true); 975079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); 985079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.startTag(null, "MAP-msg-listing"); 995a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlMsgElement.attribute(null, "version", version); 100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // Do the XML encoding of list 1015a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (BluetoothMapMessageListingElement element : mList) { 102326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde element.encode(xmlMsgElement, includeThreadId); // Append the list element 103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1045079ae05a3fa7cf09d2d8e564b71382dfc70a1aeHemant Gupta xmlMsgElement.endTag(null, "MAP-msg-listing"); 105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlMsgElement.endDocument(); 106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 107326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 108fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalStateException e) { 109326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 111326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return sw.toString().getBytes("UTF-8"); 114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void sort() { 1175a60e47497f21f64e6d79420dc4c56c1907df22akschulz Collections.sort(mList); 118fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 119fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 120fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void segment(int count, int offset) { 1215a60e47497f21f64e6d79420dc4c56c1907df22akschulz count = Math.min(count, mList.size() - offset); 122326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (count > 0) { 1235a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = mList.subList(offset, offset + count); 1245a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mList == null) { 1255a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); // Return an empty list 126326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 1285a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(offset > mList.size()) { 1295a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = new ArrayList<BluetoothMapMessageListingElement>(); 130c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta Log.d(TAG, "offset greater than list size. Returning empty list"); 131c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta } else { 1325a60e47497f21f64e6d79420dc4c56c1907df22akschulz mList = mList.subList(offset, mList.size()); 133c1f597b3ec02ccc112f3c917fd079588034c3eacHemant Gupta } 134fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 136fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie} 137