Home | History | Annotate | Download | only in map
      1 /*
      2 * Copyright (C) 2015 Samsung System LSI
      3 * Licensed under the Apache License, Version 2.0 (the "License");
      4 * you may not use this file except in compliance with the License.
      5 * You may obtain a copy of the License at
      6 *
      7 *      http://www.apache.org/licenses/LICENSE-2.0
      8 *
      9 * Unless required by applicable law or agreed to in writing, software
     10 * distributed under the License is distributed on an "AS IS" BASIS,
     11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 * See the License for the specific language governing permissions and
     13 * limitations under the License.
     14 */
     15 package com.android.bluetooth.map;
     16 
     17 import java.io.IOException;
     18 import java.io.InputStream;
     19 import java.io.StringWriter;
     20 import java.io.UnsupportedEncodingException;
     21 import java.text.ParseException;
     22 import java.util.ArrayList;
     23 import java.util.Collections;
     24 import java.util.List;
     25 
     26 import org.xmlpull.v1.XmlPullParser;
     27 import org.xmlpull.v1.XmlPullParserException;
     28 import org.xmlpull.v1.XmlSerializer;
     29 
     30 import android.util.Log;
     31 import android.util.Xml;
     32 
     33 import com.android.internal.util.FastXmlSerializer;
     34 import com.android.internal.util.XmlUtils;
     35 
     36 public class BluetoothMapConvoListing {
     37     private boolean hasUnread = false;
     38     private static final String TAG = "BluetoothMapConvoListing";
     39     private static final boolean D = BluetoothMapService.DEBUG;
     40     private static final String XML_TAG = "MAP-convo-listing";
     41 
     42     private List<BluetoothMapConvoListingElement> mList;
     43 
     44     public BluetoothMapConvoListing(){
     45      mList = new ArrayList<BluetoothMapConvoListingElement>();
     46     }
     47     public void add(BluetoothMapConvoListingElement element) {
     48         mList.add(element);
     49         /* update info regarding whether the list contains unread conversations */
     50         if (element.getReadBool())
     51         {
     52             hasUnread = true;
     53         }
     54     }
     55 
     56     /**
     57      * Used to fetch the number of BluetoothMapConvoListingElement elements in the list.
     58      * @return the number of elements in the list.
     59      */
     60     public int getCount() {
     61         if(mList != null)
     62         {
     63             return mList.size();
     64         }
     65         return 0;
     66     }
     67 
     68     /**
     69      * does the list contain any unread messages
     70      * @return true if unread messages have been added to the list, else false
     71      */
     72     public boolean hasUnread()
     73     {
     74         return hasUnread;
     75     }
     76 
     77 
     78     /**
     79      *  returns the entire list as a list
     80      * @return list
     81      */
     82     public List<BluetoothMapConvoListingElement> getList(){
     83         return mList;
     84     }
     85 
     86     /**
     87      * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8
     88      * formatted XML-string in a trimmed byte array
     89      *
     90      * @return a reference to the encoded byte array.
     91      * @throws UnsupportedEncodingException
     92      *             if UTF-8 encoding is unsupported on the platform.
     93      */
     94     public byte[] encode() throws UnsupportedEncodingException {
     95         StringWriter sw = new StringWriter();
     96         XmlSerializer xmlConvoElement = new FastXmlSerializer();
     97         try {
     98             xmlConvoElement.setOutput(sw);
     99             xmlConvoElement.startDocument("UTF-8", true);
    100             xmlConvoElement.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
    101                     true);
    102             xmlConvoElement.startTag(null, XML_TAG);
    103             xmlConvoElement.attribute(null, "version", "1.0");
    104             // Do the XML encoding of list
    105             for (BluetoothMapConvoListingElement element : mList) {
    106                 element.encode(xmlConvoElement); // Append the list element
    107             }
    108             xmlConvoElement.endTag(null, XML_TAG);
    109             xmlConvoElement.endDocument();
    110         } catch (IllegalArgumentException e) {
    111             Log.w(TAG, e);
    112         } catch (IllegalStateException e) {
    113             Log.w(TAG, e);
    114         } catch (IOException e) {
    115             Log.w(TAG, e);
    116         }
    117         return sw.toString().getBytes("UTF-8");
    118     }
    119 
    120     public void sort() {
    121         Collections.sort(mList);
    122     }
    123 
    124     public void segment(int count, int offset) {
    125         count = Math.min(count, mList.size() - offset);
    126         if (count > 0) {
    127             mList = mList.subList(offset, offset + count);
    128             if(mList == null) {
    129                 mList = new ArrayList<BluetoothMapConvoListingElement>(); // Return an empty list
    130             }
    131         } else {
    132             if(offset > mList.size()) {
    133                mList = new ArrayList<BluetoothMapConvoListingElement>();
    134                Log.d(TAG, "offset greater than list size. Returning empty list");
    135             } else {
    136                mList = mList.subList(offset, mList.size());
    137             }
    138         }
    139     }
    140 
    141     public void appendFromXml(InputStream xmlDocument)
    142             throws XmlPullParserException, IOException, ParseException {
    143         try {
    144             XmlPullParser parser = Xml.newPullParser();
    145             int type;
    146             parser.setInput(xmlDocument, "UTF-8");
    147 
    148             // First find the folder-listing
    149             while((type=parser.next()) != XmlPullParser.END_TAG
    150                     && type != XmlPullParser.END_DOCUMENT ) {
    151                 // Skip until we get a start tag
    152                 if (parser.getEventType() != XmlPullParser.START_TAG) {
    153                     continue;
    154                 }
    155                 // Skip until we get a folder-listing tag
    156                 String name = parser.getName();
    157                 if(!name.equalsIgnoreCase(XML_TAG)) {
    158                     if(D) Log.i(TAG,"Unknown XML tag: " + name);
    159                     XmlUtils.skipCurrentTag(parser);
    160                 }
    161                 readConversations(parser);
    162             }
    163         } finally {
    164             xmlDocument.close();
    165         }
    166     }
    167 
    168     /**
    169      * Parses folder elements, and add to mSubFolders.
    170      * @param parser the Xml Parser currently pointing to an folder-listing tag.
    171      * @throws XmlPullParserException
    172      * @throws IOException
    173      * @throws
    174      */
    175     private void readConversations(XmlPullParser parser)
    176             throws XmlPullParserException, IOException, ParseException {
    177         int type;
    178         if(D) Log.i(TAG,"readConversations(): ");
    179         while((type=parser.next()) != XmlPullParser.END_TAG
    180                 && type != XmlPullParser.END_DOCUMENT ) {
    181             // Skip until we get a start tag
    182             if (parser.getEventType() != XmlPullParser.START_TAG) {
    183                 continue;
    184             }
    185             // Skip until we get a folder-listing tag
    186             String name = parser.getName();
    187             if(name.trim().equalsIgnoreCase(BluetoothMapConvoListingElement.XML_TAG_CONVERSATION)
    188                     == false) {
    189                 if(D) Log.i(TAG,"Unknown XML tag: " + name);
    190                 XmlUtils.skipCurrentTag(parser);
    191                 continue;
    192             }
    193             // Add a single conversation
    194             add(BluetoothMapConvoListingElement.createFromXml(parser));
    195         }
    196     }
    197 
    198 
    199     @Override
    200     public boolean equals(Object obj) {
    201         if (this == obj) {
    202             return true;
    203         }
    204         if (obj == null) {
    205             return false;
    206         }
    207         if (getClass() != obj.getClass()) {
    208             return false;
    209         }
    210         BluetoothMapConvoListing other = (BluetoothMapConvoListing) obj;
    211         if (hasUnread != other.hasUnread) {
    212             return false;
    213         }
    214         if (mList == null) {
    215             if (other.mList != null) {
    216                 return false;
    217             }
    218         } else if (!mList.equals(other.mList)) {
    219             return false;
    220         }
    221         return true;
    222     }
    223 
    224 }
    225