1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.util; 18 19 import com.android.contacts.detail.ContactDetailDisplayUtils; 20 import com.android.contacts.test.NeededForTesting; 21 22 import android.content.Context; 23 import android.database.Cursor; 24 import android.provider.ContactsContract.StreamItems; 25 import android.text.Html; 26 27 import java.util.ArrayList; 28 import java.util.Collections; 29 import java.util.List; 30 31 /** 32 * Data object for a social stream item. Social stream items may contain multiple 33 * mPhotos. Social stream item entries are comparable; entries with more recent 34 * timestamps will be displayed on top. 35 */ 36 public class StreamItemEntry implements Comparable<StreamItemEntry> { 37 38 // Basic stream item fields. 39 private final long mId; 40 private final String mText; 41 private final String mComments; 42 private final long mTimestamp; 43 private final String mAccountType; 44 private final String mAccountName; 45 private final String mDataSet; 46 47 private boolean mDecoded; 48 private CharSequence mDecodedText; 49 private CharSequence mDecodedComments; 50 51 // Package references for label and icon resources. 52 private final String mResPackage; 53 private final String mIconRes; 54 private final String mLabelRes; 55 56 // Photos associated with this stream item. 57 private List<StreamItemPhotoEntry> mPhotos; 58 59 @NeededForTesting createForTest(long id, String text, String comments, long timestamp, String accountType, String accountName, String dataSet, String resPackage, String iconRes, String labelRes)60 public static StreamItemEntry createForTest(long id, String text, String comments, 61 long timestamp, String accountType, String accountName, String dataSet, 62 String resPackage, String iconRes, String labelRes) { 63 return new StreamItemEntry(id, text, comments, timestamp, accountType, accountName, dataSet, 64 resPackage, iconRes, labelRes); 65 } 66 StreamItemEntry(long id, String text, String comments, long timestamp, String accountType, String accountName, String dataSet, String resPackage, String iconRes, String labelRes)67 private StreamItemEntry(long id, String text, String comments, long timestamp, 68 String accountType, String accountName, String dataSet, String resPackage, 69 String iconRes, String labelRes) { 70 mId = id; 71 mText = text; 72 mComments = comments; 73 mTimestamp = timestamp; 74 mAccountType = accountType; 75 mAccountName = accountName; 76 mDataSet = dataSet; 77 mResPackage = resPackage; 78 mIconRes = iconRes; 79 mLabelRes = labelRes; 80 mPhotos = new ArrayList<StreamItemPhotoEntry>(); 81 } 82 StreamItemEntry(Cursor cursor)83 public StreamItemEntry(Cursor cursor) { 84 // This is expected to be populated via a cursor containing all StreamItems columns in 85 // its projection. 86 mId = getLong(cursor, StreamItems._ID); 87 mText = getString(cursor, StreamItems.TEXT); 88 mComments = getString(cursor, StreamItems.COMMENTS); 89 mTimestamp = getLong(cursor, StreamItems.TIMESTAMP); 90 mAccountType = getString(cursor, StreamItems.ACCOUNT_TYPE); 91 mAccountName = getString(cursor, StreamItems.ACCOUNT_NAME); 92 mDataSet = getString(cursor, StreamItems.DATA_SET); 93 mResPackage = getString(cursor, StreamItems.RES_PACKAGE); 94 mIconRes = getString(cursor, StreamItems.RES_ICON); 95 mLabelRes = getString(cursor, StreamItems.RES_LABEL); 96 mPhotos = new ArrayList<StreamItemPhotoEntry>(); 97 } 98 addPhoto(StreamItemPhotoEntry photoEntry)99 public void addPhoto(StreamItemPhotoEntry photoEntry) { 100 mPhotos.add(photoEntry); 101 } 102 103 @Override compareTo(StreamItemEntry other)104 public int compareTo(StreamItemEntry other) { 105 return mTimestamp == other.mTimestamp ? 0 : mTimestamp > other.mTimestamp ? -1 : 1; 106 } 107 getId()108 public long getId() { 109 return mId; 110 } 111 getText()112 public String getText() { 113 return mText; 114 } 115 getComments()116 public String getComments() { 117 return mComments; 118 } 119 getTimestamp()120 public long getTimestamp() { 121 return mTimestamp; 122 } 123 getAccountType()124 public String getAccountType() { 125 return mAccountType; 126 } 127 getAccountName()128 public String getAccountName() { 129 return mAccountName; 130 } 131 getDataSet()132 public String getDataSet() { 133 return mDataSet; 134 } 135 getResPackage()136 public String getResPackage() { 137 return mResPackage; 138 } 139 getIconRes()140 public String getIconRes() { 141 return mIconRes; 142 } 143 getLabelRes()144 public String getLabelRes() { 145 return mLabelRes; 146 } 147 getPhotos()148 public List<StreamItemPhotoEntry> getPhotos() { 149 Collections.sort(mPhotos); 150 return mPhotos; 151 } 152 153 /** 154 * Make {@link #getDecodedText} and {@link #getDecodedComments} available. Must be called 155 * before calling those. 156 * 157 * We can't do this automatically in the getters, because it'll require a {@link Context}. 158 */ decodeHtml(Context context)159 public void decodeHtml(Context context) { 160 final Html.ImageGetter imageGetter = ContactDetailDisplayUtils.getImageGetter(context); 161 if (mText != null) { 162 mDecodedText = HtmlUtils.fromHtml(context, mText, imageGetter, null); 163 } 164 if (mComments != null) { 165 mDecodedComments = HtmlUtils.fromHtml(context, mComments, imageGetter, null); 166 } 167 mDecoded = true; 168 } 169 getDecodedText()170 public CharSequence getDecodedText() { 171 checkDecoded(); 172 return mDecodedText; 173 } 174 getDecodedComments()175 public CharSequence getDecodedComments() { 176 checkDecoded(); 177 return mDecodedComments; 178 } 179 checkDecoded()180 private void checkDecoded() { 181 if (!mDecoded) { 182 throw new IllegalStateException("decodeHtml must have been called"); 183 } 184 } 185 getString(Cursor cursor, String columnName)186 private static String getString(Cursor cursor, String columnName) { 187 return cursor.getString(cursor.getColumnIndex(columnName)); 188 } 189 getLong(Cursor cursor, String columnName)190 private static long getLong(Cursor cursor, String columnName) { 191 final int columnIndex = cursor.getColumnIndex(columnName); 192 return cursor.getLong(columnIndex); 193 } 194 } 195