MockUiProvider.java revision 33fe908589dca6a7f58aa9f56d73f74a48ac42f6
1/** 2 * Copyright (c) 2011, Google Inc. 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 17package com.android.mail.providers.protos.mock; 18 19import com.android.mail.providers.AccountCacheProvider; 20import com.android.mail.providers.UIProvider.AccountCapabilities; 21import com.android.mail.providers.UIProvider.AccountColumns; 22import com.android.mail.providers.UIProvider.AttachmentColumns; 23import com.android.mail.providers.UIProvider.ConversationColumns; 24import com.android.mail.providers.UIProvider.FolderCapabilities; 25import com.android.mail.providers.UIProvider.FolderColumns; 26import com.android.mail.providers.UIProvider.MessageColumns; 27 28import android.content.ContentProvider; 29import android.content.ContentValues; 30import android.database.Cursor; 31import android.database.MatrixCursor; 32import android.net.Uri; 33import android.provider.BaseColumns; 34import android.text.Html; 35 36import com.google.common.annotations.VisibleForTesting; 37import com.google.common.collect.Lists; 38import com.google.common.collect.Maps; 39import com.google.common.collect.ImmutableList; 40import com.google.common.collect.ImmutableMap; 41 42import java.lang.Long; 43import java.lang.Object; 44import java.lang.Override; 45import java.lang.String; 46import java.util.Date; 47import java.util.List; 48import java.util.Map; 49import java.util.Set; 50 51public final class MockUiProvider extends ContentProvider { 52 53 public static final String AUTHORITY = "com.android.mail.mockprovider"; 54 55 56 static final String BASE_URI_STRING = "content://" + AUTHORITY; 57 58 public static final int NUM_MOCK_ACCOUNTS = 2; 59 60 // A map of query result for uris 61 // TODO(pwestbro) read this map from an external 62 private static final Map<String, List<Map<String, Object>>> MOCK_QUERY_RESULTS; 63 64 static { 65 ImmutableMap.Builder<String, List<Map<String, Object>>> builder = ImmutableMap.builder(); 66 67 // Add results for account list 68 final List<Map<String, Object>> accountList = Lists.newArrayList(); 69 Map<String, Object> accountDetailsMap1; 70 71 // Account 1 72 accountDetailsMap1 = createAccountDetailsMap(0); 73 74 accountList.add(accountDetailsMap1); 75 String accountUri1 = (String)accountDetailsMap1.get(AccountColumns.URI); 76 builder.put(accountUri1, ImmutableList.of(accountDetailsMap1)); 77 78 // Account 2 79 Map<String, Object> accountDetailsMap2 = createAccountDetailsMap(1); 80 accountList.add(accountDetailsMap2); 81 82 String accountUri2 = (String) accountDetailsMap2.get(AccountColumns.URI); 83 builder.put(accountUri2, ImmutableList.of(accountDetailsMap2)); 84 85 // Add the account list to the builder 86 builder.put(getAccountsUri().toString(), accountList); 87 88 Map<String, Object> folderDetailsMap0 = createFolderDetailsMap(0, "zero", true, 0, 2); 89 builder.put(folderDetailsMap0.get(FolderColumns.URI).toString(), 90 ImmutableList.of(folderDetailsMap0)); 91 builder.put( 92 folderDetailsMap0.get(FolderColumns.CHILD_FOLDERS_LIST_URI).toString(), 93 ImmutableList.of(createFolderDetailsMap(10, "zeroChild0", 0, 0), 94 createFolderDetailsMap(11, "zeroChild1", 0, 0))); 95 96 Map<String, Object> conv0 = createConversationDetailsMap("zeroConv0".hashCode(), 97 "zeroConv0", 1); 98 builder.put(conv0.get(ConversationColumns.URI).toString(), 99 ImmutableList.of(conv0)); 100 Map<String, Object> conv1 = createConversationDetailsMap("zeroConv1".hashCode(), 101 "zeroConv1", 1); 102 builder.put(conv1.get(ConversationColumns.URI).toString(), 103 ImmutableList.of(conv1)); 104 builder.put(folderDetailsMap0.get(FolderColumns.CONVERSATION_LIST_URI).toString(), 105 ImmutableList.of(conv0, conv1)); 106 107 Map<String, Object> message0 = createMessageDetailsMap("zeroConv0".hashCode(), "zeroConv0", 108 1); 109 builder.put(message0.get(MessageColumns.URI).toString(), ImmutableList.of(message0)); 110 builder.put(conv0.get(ConversationColumns.MESSAGE_LIST_URI).toString(), 111 ImmutableList.of(message0)); 112 builder.put(message0.get(MessageColumns.ATTACHMENT_LIST_URI).toString(), 113 ImmutableList.of(createAttachmentDetailsMap(0, "zero"))); 114 Map<String, Object> message1 = createMessageDetailsMap("zeroConv1".hashCode(), "zeroConv1", 115 1); 116 builder.put(message1.get(MessageColumns.URI).toString(), ImmutableList.of(message1)); 117 Map<String, Object> message1a = createMessageDetailsMap("zeroConv1a".hashCode(), "zeroConv1a", 118 2); 119 builder.put(message1a.get(MessageColumns.URI).toString(), ImmutableList.of(message1a)); 120 builder.put(conv1.get(ConversationColumns.MESSAGE_LIST_URI).toString(), 121 ImmutableList.of(message1, message1a)); 122 builder.put(message1.get(MessageColumns.ATTACHMENT_LIST_URI).toString(), 123 ImmutableList.of(createAttachmentDetailsMap(1, "one"))); 124 125 Map<String, Object> folderDetailsMap1 = createFolderDetailsMap(1, "one", 0, 0); 126 builder.put(folderDetailsMap1.get(FolderColumns.URI).toString(), 127 ImmutableList.of(folderDetailsMap1)); 128 builder.put(accountDetailsMap1.get(AccountColumns.FOLDER_LIST_URI).toString(), 129 ImmutableList.of(folderDetailsMap0, folderDetailsMap1)); 130 131 Map<String, Object> folderDetailsMap2 = createFolderDetailsMap(2, "two", 2, 2); 132 builder.put(folderDetailsMap2.get(FolderColumns.URI).toString(), 133 ImmutableList.of(folderDetailsMap2)); 134 Map<String, Object> folderDetailsMap3 = createFolderDetailsMap(3, "three", 0, 0); 135 builder.put(folderDetailsMap3.get(FolderColumns.URI).toString(), 136 ImmutableList.of(folderDetailsMap3)); 137 builder.put(accountDetailsMap2.get(AccountColumns.FOLDER_LIST_URI).toString(), 138 ImmutableList.of(folderDetailsMap2, folderDetailsMap3)); 139 140 Map<String, Object> conv2 = createConversationDetailsMap("zeroConv2".hashCode(), 141 "zeroConv2", 0); 142 builder.put(conv2.get(ConversationColumns.URI).toString(), 143 ImmutableList.of(conv2)); 144 Map<String, Object> conv3 = createConversationDetailsMap("zeroConv3".hashCode(), 145 "zeroConv3", 0); 146 builder.put(conv3.get(ConversationColumns.URI).toString(), 147 ImmutableList.of(conv3)); 148 builder.put(folderDetailsMap2.get(FolderColumns.CONVERSATION_LIST_URI).toString(), 149 ImmutableList.of(conv2, conv3)); 150 151 Map<String, Object> message2 = createMessageDetailsMap("zeroConv2".hashCode(), "zeroConv2", 152 0); 153 builder.put(message2.get(MessageColumns.URI).toString(), ImmutableList.of(message2)); 154 builder.put(conv2.get(ConversationColumns.MESSAGE_LIST_URI).toString(), 155 ImmutableList.of(message2)); 156 Map<String, Object> message3 = createMessageDetailsMap("zeroConv3".hashCode(), "zeroConv3", 157 0); 158 builder.put(message3.get(MessageColumns.URI).toString(), ImmutableList.of(message3)); 159 builder.put(conv3.get(ConversationColumns.MESSAGE_LIST_URI).toString(), 160 ImmutableList.of(message3)); 161 162 MOCK_QUERY_RESULTS = builder.build(); 163 } 164 165 private static Map<String, Object> createConversationDetailsMap(int conversationId, 166 String subject, int hasAttachments) { 167 final String conversationUri = "content://" + AUTHORITY + "/conversation/" + conversationId; 168 Map<String, Object> conversationMap = Maps.newHashMap(); 169 conversationMap.put(BaseColumns._ID, Long.valueOf(conversationId)); 170 conversationMap.put(ConversationColumns.URI, conversationUri); 171 conversationMap.put(ConversationColumns.MESSAGE_LIST_URI, conversationUri + "/getMessages"); 172 conversationMap.put(ConversationColumns.SUBJECT, "Conversation " + subject); 173 conversationMap.put(ConversationColumns.SNIPPET, "snippet"); 174 conversationMap.put(ConversationColumns.SENDER_INFO, "Conversation " + subject); 175 conversationMap.put(ConversationColumns.DATE_RECEIVED_MS, new Date().getTime()); 176 conversationMap.put(ConversationColumns.HAS_ATTACHMENTS, hasAttachments); 177 return conversationMap; 178 } 179 180 private static Map<String, Object> createMessageDetailsMap(int messageId, String subject, 181 int hasAttachments) { 182 final String messageUri = "content://" + AUTHORITY + "/message/" + messageId; 183 Map<String, Object> messageMap = Maps.newHashMap(); 184 messageMap.put(BaseColumns._ID, Long.valueOf(messageId)); 185 messageMap.put(MessageColumns.URI, messageUri); 186 messageMap.put(MessageColumns.SUBJECT, "Message " + subject); 187 messageMap.put(MessageColumns.SNIPPET, "SNIPPET"); 188 String html = "<html><body><b><i>This is some html!!!</i></b></body></html>"; 189 messageMap.put(MessageColumns.BODY_HTML, html); 190 messageMap.put(MessageColumns.BODY_TEXT, Html.fromHtml(html)); 191 messageMap.put(MessageColumns.HAS_ATTACHMENTS, hasAttachments); 192 messageMap.put(MessageColumns.ATTACHMENT_LIST_URI, messageUri + "/getAttachments"); 193 messageMap.put(MessageColumns.TO, "account1@mock.com, account2@mock.com"); 194 messageMap.put(MessageColumns.FROM, "fromaccount1@mock.com"); 195 return messageMap; 196 } 197 198 private static Map<String, Object> createAttachmentDetailsMap(int attachmentId, String name) { 199 Map<String, Object> attachmentMap = Maps.newHashMap(); 200 attachmentMap.put(BaseColumns._ID, Long.valueOf(attachmentId)); 201 attachmentMap.put(AttachmentColumns.NAME, "Attachment " + name); 202 return attachmentMap; 203 } 204 205 private static Map<String, Object> createFolderDetailsMap(int folderId, String name, 206 int unread, int total) { 207 return createFolderDetailsMap(folderId, name, false, unread, total); 208 } 209 210 private static Map<String, Object> createFolderDetailsMap(int folderId, String name, 211 boolean hasChildren, int unread, int total) { 212 final String folderUri = "content://" + AUTHORITY + "/folder/" + folderId; 213 Map<String, Object> folderMap = Maps.newHashMap(); 214 folderMap.put(BaseColumns._ID, Long.valueOf(folderId)); 215 folderMap.put(FolderColumns.URI, folderUri); 216 folderMap.put(FolderColumns.NAME, "Folder " + name); 217 folderMap.put(FolderColumns.HAS_CHILDREN, new Integer(hasChildren ? 1 : 0)); 218 folderMap.put(FolderColumns.CONVERSATION_LIST_URI, folderUri + "/getConversations"); 219 folderMap.put(FolderColumns.CHILD_FOLDERS_LIST_URI, folderUri + "/getChildFolders"); 220 folderMap.put(FolderColumns.CAPABILITIES, 221 Long.valueOf( 222 FolderCapabilities.SYNCABLE | 223 FolderCapabilities.PARENT | 224 FolderCapabilities.CAN_HOLD_MAIL | 225 FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)); 226 folderMap.put(FolderColumns.UNREAD_COUNT, unread); 227 folderMap.put(FolderColumns.TOTAL_COUNT, total); 228 return folderMap; 229 } 230 231 // Temporarily made this public to allow the Gmail accounts to use the mock ui provider uris 232 public static Map<String, Object> createAccountDetailsMap(int accountId) { 233 final String accountUri = getMockAccountUri(accountId); 234 Map<String, Object> accountMap = Maps.newHashMap(); 235 accountMap.put(BaseColumns._ID, Long.valueOf(accountId)); 236 accountMap.put(AccountColumns.NAME, "account" + accountId + "@mockuiprovider.com"); 237 accountMap.put(AccountColumns.PROVIDER_VERSION, Long.valueOf(1)); 238 accountMap.put(AccountColumns.URI, accountUri); 239 accountMap.put(AccountColumns.CAPABILITIES, 240 Long.valueOf( 241 AccountCapabilities.SYNCABLE_FOLDERS | 242 AccountCapabilities.REPORT_SPAM | 243 AccountCapabilities.ARCHIVE | 244 AccountCapabilities.MUTE | 245 AccountCapabilities.SERVER_SEARCH | 246 AccountCapabilities.FOLDER_SERVER_SEARCH | 247 AccountCapabilities.SANITIZED_HTML | 248 AccountCapabilities.DRAFT_SYNCHRONIZATION | 249 AccountCapabilities.MULTIPLE_FROM_ADDRESSES | 250 AccountCapabilities.SMART_REPLY | 251 AccountCapabilities.LOCAL_SEARCH | 252 AccountCapabilities.THREADED_CONVERSATIONS)); 253 accountMap.put(AccountColumns.FOLDER_LIST_URI, accountUri + "/folders"); 254 accountMap.put(AccountColumns.SEARCH_URI, accountUri + "/search"); 255 accountMap.put(AccountColumns.ACCOUNT_FROM_ADDRESSES_URI, accountUri + "/fromAddresses"); 256 accountMap.put(AccountColumns.SAVE_DRAFT_URI, accountUri + "/saveDraft"); 257 accountMap.put(AccountColumns.SEND_MESSAGE_URI, accountUri + "/sendMessage"); 258 259 addAccountInfoToAccountCache(accountMap); 260 return accountMap; 261 } 262 263 public static String getMockAccountUri(int accountId) { 264 return "content://" + AUTHORITY + "/account/" + accountId; 265 } 266 267 @Override 268 public boolean onCreate() { 269 return true; 270 } 271 272 @Override 273 public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, 274 String sortOrder) { 275 276 // TODO (pwestbro): respect the projection that is specified by the caller 277 278 final List<Map<String, Object>> queryResults = 279 MOCK_QUERY_RESULTS.get(url.toString()); 280 281 if (queryResults != null && queryResults.size() > 0) { 282 // Get the projection. If there are rows in the result set, pick the first item to 283 // generate the projection 284 // TODO (pwestbro): handle the case where we want to return an empty result.\ 285 if (projection == null) { 286 Set<String> keys = queryResults.get(0).keySet(); 287 projection = keys.toArray(new String[keys.size()]); 288 } 289 MatrixCursor matrixCursor = new MatrixCursor(projection, queryResults.size()); 290 291 for (Map<String, Object> queryResult : queryResults) { 292 MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow(); 293 294 for (String key : projection) { 295 rowBuilder.add(queryResult.get(key)); 296 } 297 } 298 return matrixCursor; 299 } 300 301 return null; 302 } 303 304 @Override 305 public Uri insert(Uri url, ContentValues values) { 306 return url; 307 } 308 309 @Override 310 public int update(Uri url, ContentValues values, String selection, 311 String[] selectionArgs) { 312 return 0; 313 } 314 315 @Override 316 public int delete(Uri url, String selection, String[] selectionArgs) { 317 return 0; 318 } 319 320 @Override 321 public String getType(Uri uri) { 322 return null; 323 } 324 325 @VisibleForTesting 326 static Uri getAccountsUri() { 327 // TODO: this should probably return a different specific to the mock account list 328 return Uri.parse(BASE_URI_STRING + "/"); 329 } 330 331 private static void addAccountInfoToAccountCache(Map<String, Object> accountInfo) { 332 final AccountCacheProvider.CachedAccount account = 333 new AccountCacheProvider.CachedAccount((Long)accountInfo.get(BaseColumns._ID), 334 (String)accountInfo.get(AccountColumns.NAME), 335 (String)accountInfo.get(AccountColumns.URI), 336 (Long)accountInfo.get(AccountColumns.CAPABILITIES), 337 (String)accountInfo.get(AccountColumns.FOLDER_LIST_URI), 338 (String)accountInfo.get(AccountColumns.SEARCH_URI), 339 (String)accountInfo.get(AccountColumns.ACCOUNT_FROM_ADDRESSES_URI), 340 (String)accountInfo.get(AccountColumns.SAVE_DRAFT_URI), 341 (String)accountInfo.get(AccountColumns.SEND_MESSAGE_URI)); 342 343 344 AccountCacheProvider.addAccount(account); 345 } 346} 347 348