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 android.content.Context; 20 import android.database.Cursor; 21 import android.provider.ContactsContract.StreamItems; 22 import android.text.Html; 23 24 import com.android.contacts.detail.ContactDetailDisplayUtils; 25 import com.android.contacts.common.test.NeededForTesting; 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 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 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 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 99 public void addPhoto(StreamItemPhotoEntry photoEntry) { 100 mPhotos.add(photoEntry); 101 } 102 103 @Override 104 public int compareTo(StreamItemEntry other) { 105 return mTimestamp == other.mTimestamp ? 0 : mTimestamp > other.mTimestamp ? -1 : 1; 106 } 107 108 public long getId() { 109 return mId; 110 } 111 112 public String getText() { 113 return mText; 114 } 115 116 public String getComments() { 117 return mComments; 118 } 119 120 public long getTimestamp() { 121 return mTimestamp; 122 } 123 124 public String getAccountType() { 125 return mAccountType; 126 } 127 128 public String getAccountName() { 129 return mAccountName; 130 } 131 132 public String getDataSet() { 133 return mDataSet; 134 } 135 136 public String getResPackage() { 137 return mResPackage; 138 } 139 140 public String getIconRes() { 141 return mIconRes; 142 } 143 144 public String getLabelRes() { 145 return mLabelRes; 146 } 147 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 */ 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 170 public CharSequence getDecodedText() { 171 checkDecoded(); 172 return mDecodedText; 173 } 174 175 public CharSequence getDecodedComments() { 176 checkDecoded(); 177 return mDecodedComments; 178 } 179 180 private void checkDecoded() { 181 if (!mDecoded) { 182 throw new IllegalStateException("decodeHtml must have been called"); 183 } 184 } 185 186 private static String getString(Cursor cursor, String columnName) { 187 return cursor.getString(cursor.getColumnIndex(columnName)); 188 } 189 190 private static long getLong(Cursor cursor, String columnName) { 191 final int columnIndex = cursor.getColumnIndex(columnName); 192 return cursor.getLong(columnIndex); 193 } 194 } 195