Home | History | Annotate | Download | only in mock
      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 
     17 package com.android.mail.providers.protos.mock;
     18 
     19 import android.content.ContentProvider;
     20 import android.content.ContentValues;
     21 import android.database.Cursor;
     22 import android.database.MatrixCursor;
     23 import android.net.Uri;
     24 import android.provider.BaseColumns;
     25 import android.text.Html;
     26 
     27 import com.android.mail.providers.ConversationInfo;
     28 import com.android.mail.providers.Folder;
     29 import com.android.mail.providers.FolderList;
     30 import com.android.mail.providers.ParticipantInfo;
     31 import com.android.mail.providers.ReplyFromAccount;
     32 import com.android.mail.providers.Settings;
     33 import com.android.mail.providers.UIProvider.AccountCapabilities;
     34 import com.android.mail.providers.UIProvider.AccountColumns;
     35 import com.android.mail.providers.UIProvider.AccountColumns.SettingsColumns;
     36 import com.android.mail.providers.UIProvider.AttachmentColumns;
     37 import com.android.mail.providers.UIProvider.ConversationColumns;
     38 import com.android.mail.providers.UIProvider.ConversationCursorCommand;
     39 import com.android.mail.providers.UIProvider.FolderCapabilities;
     40 import com.android.mail.providers.UIProvider.FolderColumns;
     41 import com.android.mail.providers.UIProvider.MessageColumns;
     42 import com.google.common.annotations.VisibleForTesting;
     43 import com.google.common.collect.ImmutableList;
     44 import com.google.common.collect.Lists;
     45 import com.google.common.collect.Maps;
     46 
     47 import org.json.JSONArray;
     48 
     49 import java.util.ArrayList;
     50 import java.util.Date;
     51 import java.util.List;
     52 import java.util.Map;
     53 import java.util.Set;
     54 
     55 public final class MockUiProvider extends ContentProvider {
     56 
     57     public static final String AUTHORITY = "com.android.mail.mockprovider";
     58 
     59     private static final int NUM_ACCOUNTS = 5;
     60 
     61 
     62     private static final Uri MOCK_ACCOUNTS_URI = Uri.parse("content://" + AUTHORITY + "/accounts");
     63 
     64     // A map of query result for uris
     65     // TODO(pwestbro) read this map from an external file
     66     private static Map<String, List<Map<String, Object>>> MOCK_QUERY_RESULTS = Maps.newHashMap();
     67 
     68     private static void initializeAccount(int accountId,
     69             Map<String, List<Map<String, Object>>> resultMap) {
     70         final Map<String, Object> inboxfolderDetailsMap =
     71                 createFolderDetailsMap(0, accountId, "zero", true, 0, 2);
     72         resultMap.put(inboxfolderDetailsMap.get(FolderColumns.URI).toString(),
     73                 ImmutableList.of(inboxfolderDetailsMap));
     74 
     75         final Map<String, Object> accountDetailsMap = createAccountDetailsMap(accountId,
     76                 (String)inboxfolderDetailsMap.get(FolderColumns.URI));
     77         resultMap.put(((Uri) accountDetailsMap.get(AccountColumns.URI)).toString(),
     78                 ImmutableList.of(accountDetailsMap));
     79 
     80         final Map<String, Object> secondFolderDetailsMap =
     81                 createFolderDetailsMap(2, accountId, "two", 2, 2);
     82         resultMap.put(secondFolderDetailsMap.get(FolderColumns.URI).toString(),
     83                 ImmutableList.of(secondFolderDetailsMap));
     84 
     85         resultMap.put(
     86                 inboxfolderDetailsMap.get(FolderColumns.CHILD_FOLDERS_LIST_URI).toString(),
     87                 ImmutableList.of(createFolderDetailsMap(10, accountId, "zeroChild0", 0, 0),
     88                         createFolderDetailsMap(11, accountId, "zeroChild1", 0, 0)));
     89 
     90         final ArrayList<Map<String, Object>> conversations = new ArrayList<Map<String, Object>>();
     91         for (int i = 0; i < 100; i++) {
     92             final String name = "zeroConv"+i;
     93             conversations.add(createConversationDetailsMap(accountId, name.hashCode(),
     94                     name, 1, 5, i % 2));
     95         }
     96         resultMap.put(inboxfolderDetailsMap.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
     97                 conversations);
     98 
     99         final Map<String, Object> message0 =
    100                 createMessageDetailsMap(accountId, "zeroConv0".hashCode(), "zeroConv0", 1, false);
    101         resultMap.put(message0.get(MessageColumns.URI).toString(), ImmutableList.of(message0));
    102         resultMap.put(conversations.get(0).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
    103                 ImmutableList.of(message0));
    104         resultMap.put(message0.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
    105                 ImmutableList.of(createAttachmentDetailsMap(0, "zero")));
    106         final Map<String, Object> message1 =
    107                 createMessageDetailsMap(accountId, "zeroConv1".hashCode(), "zeroConv1", 1, false);
    108         resultMap.put(message1.get(MessageColumns.URI).toString(), ImmutableList.of(message1));
    109         final Map<String, Object> message1a =
    110                 createMessageDetailsMap(accountId, "zeroConv1a".hashCode(), "zeroConv1a", 2, false);
    111         resultMap.put(message1a.get(MessageColumns.URI).toString(), ImmutableList.of(message1a));
    112         resultMap.put(conversations.get(1).get(ConversationColumns.MESSAGE_LIST_URI).toString(),
    113                 ImmutableList.of(message1, message1a));
    114         resultMap.put(message1.get(MessageColumns.ATTACHMENT_LIST_URI).toString(),
    115                 ImmutableList.of(createAttachmentDetailsMap(1, "one")));
    116 
    117         final Map<String, Object> folderDetailsMap1 =
    118                 createFolderDetailsMap(1, accountId,  "one", 0, 0);
    119         resultMap.put(folderDetailsMap1.get(FolderColumns.URI).toString(),
    120                 ImmutableList.of(folderDetailsMap1));
    121 
    122         // We currently have two configurations for accounts
    123         if (accountId % 2 == 0) {
    124             resultMap.put(accountDetailsMap.get(AccountColumns.FOLDER_LIST_URI).toString(),
    125                     ImmutableList.of(inboxfolderDetailsMap, folderDetailsMap1));
    126         } else {
    127             resultMap.put(secondFolderDetailsMap.get(FolderColumns.URI).toString(),
    128                     ImmutableList.of(secondFolderDetailsMap));
    129             final Map<String, Object> folderDetailsMap3 =
    130                     createFolderDetailsMap(3, accountId, "three", 0, 0);
    131             resultMap.put(folderDetailsMap3.get(FolderColumns.URI).toString(),
    132                     ImmutableList.of(folderDetailsMap3));
    133 
    134             resultMap.put(accountDetailsMap.get(AccountColumns.FOLDER_LIST_URI).toString(),
    135                     ImmutableList.of(secondFolderDetailsMap, folderDetailsMap3));
    136         }
    137 
    138         final Map<String, Object> conv3 =
    139                 createConversationDetailsMap(accountId, "zeroConv3".hashCode(), "zeroConv3",
    140                         0, 1, 0);
    141         resultMap.put(conv3.get(ConversationColumns.URI).toString(),
    142                 ImmutableList.of(conv3));
    143         final Map<String, Object> conv4 =
    144                 createConversationDetailsMap(accountId, "zeroConv4".hashCode(), "zeroConv4",
    145                         0, 1, 0);
    146         resultMap.put(conv4.get(ConversationColumns.URI).toString(),
    147                 ImmutableList.of(conv4));
    148         resultMap.put(secondFolderDetailsMap.get(FolderColumns.CONVERSATION_LIST_URI).toString(),
    149                 ImmutableList.of(conv3, conv4));
    150 
    151         final Map<String, Object> message2 =
    152                 createMessageDetailsMap(accountId, "zeroConv3".hashCode(), "zeroConv3", 0, true);
    153         resultMap.put(message2.get(MessageColumns.URI).toString(), ImmutableList.of(message2));
    154         resultMap.put(conv3.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
    155                 ImmutableList.of(message2));
    156         final Map<String, Object> message3 =
    157                 createMessageDetailsMap(accountId, "zeroConv4".hashCode(), "zeroConv4", 0, true);
    158         resultMap.put(message3.get(MessageColumns.URI).toString(), ImmutableList.of(message3));
    159         resultMap.put(conv4.get(ConversationColumns.MESSAGE_LIST_URI).toString(),
    160                 ImmutableList.of(message3));
    161 
    162         // Add the account to the list of accounts
    163         List<Map<String, Object>> accountList = resultMap.get(getAccountsUri().toString());
    164         if (accountList == null) {
    165             accountList = Lists.newArrayList();
    166             resultMap.put(getAccountsUri().toString(), accountList);
    167         }
    168         accountList.add(accountDetailsMap);
    169     }
    170 
    171     public static void initializeMockProvider() {
    172         MOCK_QUERY_RESULTS = Maps.newHashMap();
    173 
    174         for (int accountId = 0; accountId < NUM_ACCOUNTS; accountId++) {
    175             initializeAccount(accountId, MOCK_QUERY_RESULTS);
    176         }
    177     }
    178 
    179     private static Map<String, Object> createConversationDetailsMap(int accountId,
    180             int conversationId, String subject, int hasAttachments, int messageCount,
    181             int draftCount) {
    182         final String conversationUri = getMockConversationUri(accountId, conversationId);
    183         Map<String, Object> conversationMap = Maps.newHashMap();
    184         conversationMap.put(BaseColumns._ID, Long.valueOf(conversationId));
    185         conversationMap.put(ConversationColumns.URI, conversationUri);
    186         conversationMap.put(ConversationColumns.MESSAGE_LIST_URI, conversationUri + "/getMessages");
    187         conversationMap.put(ConversationColumns.SUBJECT, "Conversation " + subject);
    188         conversationMap.put(ConversationColumns.SNIPPET, "snippet");
    189         conversationMap.put(ConversationColumns.SENDER_INFO,
    190                 "account1 (at) mock.com, account2 (at) mock.com");
    191         conversationMap.put(ConversationColumns.DATE_RECEIVED_MS, new Date().getTime());
    192         conversationMap.put(ConversationColumns.HAS_ATTACHMENTS, hasAttachments);
    193         conversationMap.put(ConversationColumns.NUM_MESSAGES, 1);
    194         conversationMap.put(ConversationColumns.NUM_DRAFTS, 1);
    195         conversationMap.put(ConversationColumns.SENDING_STATE, 1);
    196         conversationMap.put(ConversationColumns.READ, 0);
    197         conversationMap.put(ConversationColumns.SEEN, 0);
    198         conversationMap.put(ConversationColumns.STARRED, 0);
    199         conversationMap.put(ConversationColumns.CONVERSATION_INFO,
    200                 generateConversationInfo(messageCount, draftCount));
    201         final List<Folder> folders = new ArrayList<Folder>(3);
    202         for (int i = 0; i < 3; i++) {
    203             final Folder folder = Folder.newUnsafeInstance();
    204             folder.name = "folder" + i;
    205             switch (i) {
    206                 case 0:
    207                     folder.bgColor = "#fff000";
    208                     break;
    209                 case 1:
    210                     folder.bgColor = "#0000FF";
    211                     break;
    212                 case 2:
    213                     folder.bgColor = "#FFFF00";
    214                     break;
    215                 default:
    216                     folder.bgColor = null;
    217                     break;
    218             }
    219 
    220             folders.add(folder);
    221         }
    222         final FolderList folderList = FolderList.copyOf(folders);
    223         conversationMap.put(
    224                 MockRespondMatrixCursor.MOCK_RESPOND_PREFIX +
    225                         ConversationCursorCommand.COMMAND_GET_RAW_FOLDERS, folderList);
    226         return conversationMap;
    227     }
    228 
    229     private static byte[] generateConversationInfo(int messageCount, int draftCount) {
    230         ConversationInfo info = new ConversationInfo(messageCount, draftCount, "first",
    231                 "firstUnread", "last");
    232         for (int i = 0; i < messageCount; i++) {
    233             if (i % 2 == 0) {
    234                 info.addParticipant(new ParticipantInfo(i + "Test", "testsender (at) test.com", -1,
    235                         false));
    236             } else if (i % 3 == 0) {
    237                 info.addParticipant(new ParticipantInfo(i + "sender (at) test.com", "sender (at) test.com",
    238                         -1, false));
    239             } else {
    240                 info.addParticipant(new ParticipantInfo(" .. ", null, -1, false));
    241             }
    242         }
    243         return info.toBlob();
    244     }
    245 
    246     private static Map<String, Object> createMessageDetailsMap(int accountId, int messageId,
    247             String subject, int hasAttachments, boolean addReplyTo) {
    248         final String accountUri = getMockAccountUri(accountId);
    249         final String messageUri = getMockMessageUri(accountId, messageId);
    250         Map<String, Object> messageMap = Maps.newHashMap();
    251         messageMap.put(BaseColumns._ID, Long.valueOf(messageId));
    252         messageMap.put(MessageColumns.URI, messageUri);
    253         messageMap.put(MessageColumns.SUBJECT, "Message " + subject);
    254         messageMap.put(MessageColumns.SNIPPET, "SNIPPET");
    255         String html = "<html><body><b><i>This is some html!!!</i></b></body></html>";
    256         messageMap.put(MessageColumns.BODY_HTML, html);
    257         messageMap.put(MessageColumns.BODY_TEXT, Html.fromHtml(html));
    258         messageMap.put(MessageColumns.HAS_ATTACHMENTS, hasAttachments);
    259         messageMap.put(MessageColumns.DATE_RECEIVED_MS, new Date().getTime());
    260         messageMap.put(MessageColumns.ATTACHMENT_LIST_URI, messageUri + "/getAttachments");
    261         messageMap.put(MessageColumns.TO, "account1 (at) mock.com, account2 (at) mock.com");
    262         messageMap.put(MessageColumns.FROM, "fromaccount1 (at) mock.com");
    263         messageMap.put(MessageColumns.MESSAGE_ACCOUNT_URI, accountUri);
    264         return messageMap;
    265     }
    266 
    267     private static Map<String, Object> createAttachmentDetailsMap(int attachmentId, String name) {
    268         Map<String, Object> attachmentMap = Maps.newHashMap();
    269         attachmentMap.put(BaseColumns._ID, Long.valueOf(attachmentId));
    270         attachmentMap.put(AttachmentColumns.NAME, "Attachment " + name);
    271         attachmentMap.put(AttachmentColumns.URI,
    272                 "attachmentUri/" + attachmentMap.get(AttachmentColumns.NAME));
    273         return attachmentMap;
    274     }
    275 
    276     private static Map<String, Object> createFolderDetailsMap(int folderId, int accountId,
    277             String name, int unread, int total) {
    278         return createFolderDetailsMap(folderId, accountId, name, false, unread, total);
    279     }
    280 
    281     private static Map<String, Object> createFolderDetailsMap(int folderId, int accountId,
    282             String name, boolean hasChildren, int unread, int total) {
    283         final String folderUri = getMockAccountFolderUri(accountId, folderId);
    284 
    285         Map<String, Object> folderMap = Maps.newHashMap();
    286         folderMap.put(BaseColumns._ID, folderId);
    287         folderMap.put(FolderColumns.URI, folderUri);
    288         folderMap.put(FolderColumns.NAME, "Folder " + name);
    289         folderMap.put(FolderColumns.HAS_CHILDREN, hasChildren ? 1 : 0);
    290         folderMap.put(FolderColumns.CONVERSATION_LIST_URI, folderUri + "/getConversations");
    291         folderMap.put(FolderColumns.CHILD_FOLDERS_LIST_URI, folderUri + "/getChildFolders");
    292         folderMap.put(FolderColumns.CAPABILITIES, FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES);
    293         folderMap.put(FolderColumns.UNREAD_COUNT, unread);
    294         folderMap.put(FolderColumns.TOTAL_COUNT, total);
    295         folderMap.put(FolderColumns.SYNC_STATUS, 0);
    296         folderMap.put(FolderColumns.LAST_SYNC_RESULT, 0);
    297         return folderMap;
    298     }
    299 
    300     // Temporarily made this public to allow the Gmail accounts to use the mock ui provider uris
    301     public static Map<String, Object> createAccountDetailsMap(int accountId,String defaultInbox) {
    302         final String accountUri = getMockAccountUri(accountId);
    303         Map<String, Object> accountMap = Maps.newHashMap();
    304         accountMap.put(BaseColumns._ID, Long.valueOf(accountId));
    305         accountMap.put(AccountColumns.NAME, "account" + accountId + "@mockuiprovider.com");
    306         accountMap.put(AccountColumns.TYPE, "com.android.mail.providers.protos.mock");
    307         accountMap.put(AccountColumns.ACCOUNT_MANAGER_NAME,
    308                 "account" + accountId + "@mockuiprovider.com");
    309         accountMap.put(AccountColumns.ACCOUNT_ID,
    310                 "account" + accountId + "@mockuiprovider.com");
    311         accountMap.put(AccountColumns.PROVIDER_VERSION, Long.valueOf(1));
    312         accountMap.put(AccountColumns.URI, Uri.parse(accountUri));
    313         accountMap.put(AccountColumns.CAPABILITIES,
    314                 Integer.valueOf(
    315                         AccountCapabilities.SYNCABLE_FOLDERS |
    316                         AccountCapabilities.REPORT_SPAM |
    317                         AccountCapabilities.ARCHIVE |
    318                         AccountCapabilities.MUTE |
    319                         AccountCapabilities.SERVER_SEARCH |
    320                         AccountCapabilities.FOLDER_SERVER_SEARCH |
    321                         AccountCapabilities.SERVER_SANITIZED_HTML |
    322                         AccountCapabilities.DRAFT_SYNCHRONIZATION |
    323                         AccountCapabilities.MULTIPLE_FROM_ADDRESSES |
    324                         AccountCapabilities.SMART_REPLY |
    325                         AccountCapabilities.LOCAL_SEARCH |
    326                         AccountCapabilities.THREADED_CONVERSATIONS |
    327                         AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV));
    328         JSONArray replyFroms = new JSONArray();
    329         ArrayList<ReplyFromAccount> list = new ArrayList<ReplyFromAccount>();
    330         list.add(new ReplyFromAccount(null, Uri.parse(accountUri), "customAddress1 (at) custom.com",
    331                 "customAddress2 (at) custom.com", "Custom1", false, true));
    332         list.add(new ReplyFromAccount(null, Uri.parse(accountUri), "customAddress2 (at) custom.com",
    333                 "customAddress2 (at) custom.com", "Custom2", false, true));
    334         for (ReplyFromAccount a : list) {
    335             replyFroms.put(a.serialize());
    336         }
    337         accountMap.put(AccountColumns.ACCOUNT_FROM_ADDRESSES, replyFroms.toString());
    338         accountMap.put(AccountColumns.FOLDER_LIST_URI, Uri.parse(accountUri + "/folders"));
    339         accountMap.put(AccountColumns.FULL_FOLDER_LIST_URI, Uri.parse(accountUri + "/folders"));
    340         accountMap.put(AccountColumns.ALL_FOLDER_LIST_URI, Uri.parse(accountUri + "/folders"));
    341         accountMap.put(AccountColumns.SEARCH_URI, Uri.parse(accountUri + "/search"));
    342         accountMap.put(AccountColumns.EXPUNGE_MESSAGE_URI,
    343                 Uri.parse(accountUri + "/expungeMessage"));
    344         accountMap.put(AccountColumns.UNDO_URI, Uri.parse(accountUri + "/undo"));
    345         accountMap.put(AccountColumns.SETTINGS_INTENT_URI, Uri.EMPTY);
    346         accountMap.put(AccountColumns.HELP_INTENT_URI, Uri.EMPTY);
    347         accountMap.put(AccountColumns.SEND_FEEDBACK_INTENT_URI, Uri.EMPTY);
    348         accountMap.put(AccountColumns.REAUTHENTICATION_INTENT_URI, Uri.EMPTY);
    349         accountMap.put(AccountColumns.SYNC_STATUS, 0);
    350         accountMap.put(AccountColumns.COMPOSE_URI, Uri.parse(accountUri + "/compose"));
    351         accountMap.put(AccountColumns.RECENT_FOLDER_LIST_URI,
    352                 Uri.parse(accountUri + "/recentFolderListUri"));
    353         accountMap.put(AccountColumns.MIME_TYPE, "account/mock");
    354         accountMap.put(AccountColumns.COLOR, 0);
    355         accountMap.put(AccountColumns.RECENT_FOLDER_LIST_URI, Uri.EMPTY);
    356         accountMap.put(AccountColumns.DEFAULT_RECENT_FOLDER_LIST_URI, Uri.EMPTY);
    357         accountMap.put(AccountColumns.MANUAL_SYNC_URI, Uri.EMPTY);
    358         accountMap.put(AccountColumns.VIEW_INTENT_PROXY_URI, Uri.EMPTY);
    359         accountMap.put(AccountColumns.ACCOUNT_COOKIE_QUERY_URI, Uri.EMPTY);
    360         accountMap.put(AccountColumns.UPDATE_SETTINGS_URI, Uri.EMPTY);
    361         accountMap.put(AccountColumns.ENABLE_MESSAGE_TRANSFORMS, 1);
    362 
    363 
    364         // Add settings columns
    365         accountMap.put(SettingsColumns.SIGNATURE, "");
    366         accountMap.put(SettingsColumns.AUTO_ADVANCE, 1);
    367         accountMap.put(SettingsColumns.SNAP_HEADERS, 1);
    368         accountMap.put(SettingsColumns.REPLY_BEHAVIOR, 1);
    369         accountMap.put(SettingsColumns.CONV_LIST_ICON, 1);
    370         accountMap.put(SettingsColumns.CONFIRM_DELETE, 1);
    371         accountMap.put(SettingsColumns.CONFIRM_ARCHIVE, 1);
    372         accountMap.put(SettingsColumns.CONFIRM_SEND, 1);
    373         accountMap.put(SettingsColumns.DEFAULT_INBOX, defaultInbox);
    374         accountMap.put(SettingsColumns.DEFAULT_INBOX_NAME, "Inbox");
    375         accountMap.put(SettingsColumns.FORCE_REPLY_FROM_DEFAULT, 1);
    376         accountMap.put(SettingsColumns.MAX_ATTACHMENT_SIZE, 25 * 1024 * 1024);
    377         accountMap.put(SettingsColumns.SWIPE, 1);
    378         accountMap.put(SettingsColumns.IMPORTANCE_MARKERS_ENABLED, 1);
    379         accountMap.put(SettingsColumns.SHOW_CHEVRONS_ENABLED, 0);
    380         accountMap.put(SettingsColumns.SETUP_INTENT_URI, Uri.EMPTY);
    381         accountMap.put(SettingsColumns.CONVERSATION_VIEW_MODE, 1);
    382         accountMap.put(SettingsColumns.VEILED_ADDRESS_PATTERN, null);
    383         accountMap.put(SettingsColumns.MOVE_TO_INBOX, Uri.EMPTY);
    384         accountMap.put(SettingsColumns.SHOW_IMAGES, Settings.ShowImages.ASK_FIRST);
    385         return accountMap;
    386     }
    387 
    388     public static String getMockAccountUri(int accountId) {
    389         return "content://" + AUTHORITY + "/account/" + accountId;
    390     }
    391 
    392     private static String getMockAccountFolderUri(int accountId, int folderId) {
    393         return getMockAccountUri(accountId) + "/folder/" + folderId;
    394     }
    395 
    396     private static String getMockConversationUri(int accountId, int conversationId) {
    397         return getMockAccountUri(accountId) + "/conversation/" + conversationId;
    398     }
    399 
    400     private static String getMockMessageUri(int accountId, int messageId) {
    401         return getMockAccountUri(accountId) + "/message/" + messageId;
    402     }
    403 
    404     @Override
    405     public boolean onCreate() {
    406         MockUiProvider.initializeMockProvider();
    407         return true;
    408     }
    409 
    410     @Override
    411     public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
    412             String sortOrder) {
    413 
    414         final List<Map<String, Object>> queryResults = MOCK_QUERY_RESULTS.get(url.toString());
    415 
    416         if (queryResults != null && queryResults.size() > 0) {
    417             // Get the projection.  If there are rows in the result set, pick the first item to
    418             // generate the projection
    419             // TODO (pwestbro): handle the case where we want to return an empty result.\
    420             if (projection == null) {
    421                 Set<String> keys = queryResults.get(0).keySet();
    422                 projection = keys.toArray(new String[keys.size()]);
    423             }
    424             final MatrixCursor matrixCursor =
    425                     new MockRespondMatrixCursor(projection, queryResults.size(), queryResults);
    426 
    427             for (Map<String, Object> queryResult : queryResults) {
    428                 MatrixCursor.RowBuilder rowBuilder = matrixCursor.newRow();
    429 
    430                 for (String key : projection) {
    431                     rowBuilder.add(queryResult.get(key));
    432                 }
    433             }
    434             return matrixCursor;
    435         }
    436 
    437         return null;
    438     }
    439 
    440     @Override
    441     public Uri insert(Uri url, ContentValues values) {
    442         return url;
    443     }
    444 
    445     @Override
    446     public int update(Uri url, ContentValues values, String selection,
    447             String[] selectionArgs) {
    448         return 0;
    449     }
    450 
    451     @Override
    452     public int delete(Uri url, String selection, String[] selectionArgs) {
    453         return 0;
    454     }
    455 
    456     @Override
    457     public String getType(Uri uri) {
    458         return null;
    459     }
    460 
    461     @VisibleForTesting
    462     static Uri getAccountsUri() {
    463         return MOCK_ACCOUNTS_URI;
    464     }
    465 }
    466 
    467