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