TelephonyBackupAgentTest.java revision 3aa281731a6f25cd36b88bca809b13d3f581d05f
18b39acf181c547e87161873112d6c52a581fc778Roman Sorokin/*
28b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Copyright (C) 2016 The Android Open Source Project
38b39acf181c547e87161873112d6c52a581fc778Roman Sorokin *
48b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Licensed under the Apache License, Version 2.0 (the "License");
58b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * you may not use this file except in compliance with the License.
68b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * You may obtain a copy of the License at
78b39acf181c547e87161873112d6c52a581fc778Roman Sorokin *
88b39acf181c547e87161873112d6c52a581fc778Roman Sorokin *      http://www.apache.org/licenses/LICENSE-2.0
98b39acf181c547e87161873112d6c52a581fc778Roman Sorokin *
108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Unless required by applicable law or agreed to in writing, software
118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * distributed under the License is distributed on an "AS IS" BASIS,
128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * See the License for the specific language governing permissions and
148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * limitations under the License
158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */
168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
178b39acf181c547e87161873112d6c52a581fc778Roman Sorokinpackage com.android.providers.telephony;
188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
198b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.annotation.TargetApi;
2021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokinimport android.app.backup.FullBackupDataOutput;
219037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport android.content.ContentProvider;
229037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport android.content.ContentResolver;
231d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokinimport android.content.ContentUris;
248b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.content.ContentValues;
259037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport android.content.ContextWrapper;
268b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.database.Cursor;
278b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.net.Uri;
288b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.os.Build;
298b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.provider.BaseColumns;
308b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.provider.Telephony;
318b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.test.AndroidTestCase;
328b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.test.mock.MockContentProvider;
339037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport android.test.mock.MockContentResolver;
348b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.test.mock.MockCursor;
358b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.util.ArrayMap;
361d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokinimport android.util.ArraySet;
378b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.util.JsonReader;
388b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.util.JsonWriter;
399037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport android.util.Log;
408b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport android.util.SparseArray;
418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
429037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport org.json.JSONArray;
439037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport org.json.JSONException;
449037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport org.json.JSONObject;
459037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
468b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.io.StringReader;
478b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.io.StringWriter;
488b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.ArrayList;
498b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.Arrays;
508b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.HashMap;
513aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokinimport java.util.HashSet;
528b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.List;
538b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.Map;
541d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokinimport java.util.Set;
559037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport java.util.UUID;
568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin/**
598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Tests for testing backup/restore of SMS and text MMS messages.
608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * For backup it creates fake provider and checks resulting json array.
618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * For restore provides json array and checks inserts of the messages into provider.
628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */
638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin@TargetApi(Build.VERSION_CODES.M)
648b39acf181c547e87161873112d6c52a581fc778Roman Sorokinpublic class TelephonyBackupAgentTest extends AndroidTestCase {
651d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Map subscriptionId -> phone number */
668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private SparseArray<String> mSubId2Phone;
671d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Map phone number -> subscriptionId */
688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private ArrayMap<String, Integer> mPhone2SubId;
691d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Table being used for sms cursor */
708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private final List<ContentValues> mSmsTable = new ArrayList<>();
711d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Table begin used for mms cursor */
728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private final List<ContentValues> mMmsTable = new ArrayList<>();
731d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Table contains parts, addresses of mms */
748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private final List<ContentValues> mMmsAllContentValues = new ArrayList<>();
751d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Cursors being used to access sms, mms tables */
768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private FakeCursor mSmsCursor, mMmsCursor;
771d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Test data with sms and mms */
788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private ContentValues[] mSmsRows, mMmsRows;
791d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Json representation for the test data */
808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private String[] mSmsJson, mMmsJson;
811d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* sms, mms json concatenated as json array */
828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private String mAllSmsJson, mAllMmsJson;
838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private StringWriter mStringWriter;
851d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
869037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    /* Content resolver passed to the backupAgent */
879037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    private MockContentResolver mMockContentResolver = new MockContentResolver();
889037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
891d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    /* Map uri -> cursors. Being used for contentprovider. */
908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private Map<Uri, FakeCursor> mCursors;
9176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin    /* Content provider with threadIds.*/
9276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin    private ThreadProvider mThreadProvider = new ThreadProvider();
938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static final String EMPTY_JSON_ARRAY = "[]";
9521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
9621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    TelephonyBackupAgent mTelephonyBackupAgent;
9721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    @Override
998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    protected void setUp() throws Exception {
1008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        super.setUp();
1011d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
1021d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        /* Filling up subscription maps */
1038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mStringWriter = new StringWriter();
1048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSubId2Phone = new SparseArray<String>();
1058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSubId2Phone.append(1, "+111111111111111");
1068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSubId2Phone.append(3, "+333333333333333");
1078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mPhone2SubId = new ArrayMap<>();
1098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        for (int i=0; i<mSubId2Phone.size(); ++i) {
1108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            mPhone2SubId.put(mSubId2Phone.valueAt(i), mSubId2Phone.keyAt(i));
1118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
1128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
11321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mCursors = new HashMap<Uri, FakeCursor>();
1141d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        /* Bind tables to the cursors */
1158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsCursor = new FakeCursor(mSmsTable, TelephonyBackupAgent.SMS_PROJECTION);
11621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mCursors.put(Telephony.Sms.CONTENT_URI, mSmsCursor);
1178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsCursor = new FakeCursor(mMmsTable, TelephonyBackupAgent.MMS_PROJECTION);
11821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mCursors.put(Telephony.Mms.CONTENT_URI, mMmsCursor);
1191d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
1208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1211d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        /* Generating test data */
1228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsRows = new ContentValues[3];
1238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsJson = new String[3];
1248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsRows[0] = createSmsRow(1, 1, "+1232132214124", "sms 1", "sms subject", 9087978987l,
1258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                999999999, 3, 44, 1);
1268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsJson[0] = "{\"self_phone\":\"+111111111111111\",\"address\":" +
1278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"+1232132214124\",\"body\":\"sms 1\",\"subject\":\"sms subject\",\"date\":" +
1281d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                "\"9087978987\",\"date_sent\":\"999999999\",\"status\":\"3\",\"type\":\"44\"," +
1293aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                "\"recipients\":[\"+123 (213) 2214124\"],\"archived\":true}";
1303aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        mThreadProvider.setArchived(
1313aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                mThreadProvider.getOrCreateThreadId(new String[]{"+123 (213) 2214124"}));
1328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsRows[1] = createSmsRow(2, 2, "+1232132214124", "sms 2", null, 9087978987l, 999999999,
1348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                0, 4, 1);
1358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsJson[1] = "{\"address\":\"+1232132214124\",\"body\":\"sms 2\",\"date\":" +
1361d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                "\"9087978987\",\"date_sent\":\"999999999\",\"status\":\"0\",\"type\":\"4\"," +
13776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"recipients\":[\"+123 (213) 2214124\"]}";
1388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsRows[2] = createSmsRow(4, 3, "+1232221412433 +1232221412444", "sms 3", null,
1408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                111111111111l, 999999999, 2, 3, 2);
1418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsJson[2] =  "{\"self_phone\":\"+333333333333333\",\"address\":" +
1428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"+1232221412433 +1232221412444\",\"body\":\"sms 3\",\"date\":\"111111111111\"," +
1438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"date_sent\":" +
1441d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                "\"999999999\",\"status\":\"2\",\"type\":\"3\"," +
14576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"recipients\":[\"+1232221412433\",\"+1232221412444\"]}";
14676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin        mThreadProvider.getOrCreateThreadId(new String[]{"+1232221412433", "+1232221412444"});
1478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1481d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        mAllSmsJson = makeJsonArray(mSmsJson);
1498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsRows = new ContentValues[3];
1538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsJson = new String[3];
1548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsRows[0] = createMmsRow(1 /*id*/, 1 /*subid*/, "Subject 1" /*subject*/,
1558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                100 /*subcharset*/, 111111 /*date*/, 111112 /*datesent*/, 3 /*type*/,
1568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                17 /*version*/, 1 /*textonly*/,
1578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                11 /*msgBox*/, "location 1" /*contentLocation*/, "MMs body 1" /*body*/,
1588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                111 /*body charset*/,
15976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                new String[]{"+111 (111) 11111111", "+11121212", "example@example.com",
16076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                        "+999999999"} /*addresses*/,
16176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                3 /*threadId*/);
1628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsJson[0] = "{\"self_phone\":\"+111111111111111\",\"sub\":\"Subject 1\"," +
1648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"date\":\"111111\",\"date_sent\":\"111112\",\"m_type\":\"3\",\"v\":\"17\"," +
16576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"msg_box\":\"11\",\"ct_l\":\"location 1\"," +
16676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"recipients\":[\"+11121212\",\"example@example.com\",\"+999999999\"]," +
16776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"mms_addresses\":" +
16876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "[{\"type\":10,\"address\":\"+111 (111) 11111111\",\"charset\":100}," +
16976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "{\"type\":11,\"address\":\"+11121212\",\"charset\":101},{\"type\":12,\"address\":"+
17076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"example@example.com\",\"charset\":102},{\"type\":13,\"address\":\"+999999999\"" +
17176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                ",\"charset\":103}],\"mms_body\":\"MMs body 1\",\"mms_charset\":111,\"" +
1728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "sub_cs\":\"100\"}";
17376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin        mThreadProvider.getOrCreateThreadId(new String[]{"+11121212", "example@example.com",
17476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "+999999999"});
1758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
1768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsRows[1] = createMmsRow(2 /*id*/, 2 /*subid*/, null /*subject*/, 100 /*subcharset*/,
1778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                111122 /*date*/, 1111112 /*datesent*/, 4 /*type*/, 18 /*version*/, 1 /*textonly*/,
1788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                222 /*msgBox*/, "location 2" /*contentLocation*/, "MMs body 2" /*body*/,
1798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                121 /*body charset*/,
18076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                new String[]{"+7 (333) ", "example@example.com", "+999999999"} /*addresses*/,
18176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                4 /*threadId*/);
1828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsJson[1] = "{\"date\":\"111122\",\"date_sent\":\"1111112\",\"m_type\":\"4\"," +
18376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"v\":\"18\",\"msg_box\":\"222\",\"ct_l\":\"location 2\"," +
18476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"recipients\":[\"example@example.com\",\"+999999999\"]," +
18576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"mms_addresses\":" +
18676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "[{\"type\":10,\"address\":\"+7 (333) \",\"charset\":100}," +
18776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "{\"type\":11,\"address\":\"example@example.com\",\"charset\":101}," +
18876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "{\"type\":12,\"address\":\"+999999999\",\"charset\":102}]," +
1898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"mms_body\":\"MMs body 2\",\"mms_charset\":121}";
19076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin        mThreadProvider.getOrCreateThreadId(new String[]{"example@example.com", "+999999999"});
1918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
19276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin        mMmsRows[2] = createMmsRow(9 /*id*/, 3 /*subid*/, "Subject 10" /*subject*/,
1938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                10 /*subcharset*/, 111133 /*date*/, 1111132 /*datesent*/, 5 /*type*/,
1948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                19 /*version*/, 1 /*textonly*/,
1958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                333 /*msgBox*/, null /*contentLocation*/, "MMs body 3" /*body*/,
19676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                131 /*body charset*/,
19776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                new String[]{"333 333333333333", "+1232132214124"} /*addresses*/,
19876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                1 /*threadId*/);
1998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsJson[2] = "{\"self_phone\":\"+333333333333333\",\"sub\":\"Subject 10\"," +
2018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"date\":\"111133\",\"date_sent\":\"1111132\",\"m_type\":\"5\",\"v\":\"19\"," +
20276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"msg_box\":\"333\"," +
2033aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                "\"recipients\":[\"+123 (213) 2214124\"],\"archived\":true," +
20476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"mms_addresses\":" +
20576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "[{\"type\":10,\"address\":\"333 333333333333\",\"charset\":100}," +
20676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "{\"type\":11,\"address\":\"+1232132214124\",\"charset\":101}]," +
20776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                "\"mms_body\":\"MMs body 3\",\"mms_charset\":131," +
2088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                "\"sub_cs\":\"10\"}";
2091d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        mAllMmsJson = makeJsonArray(mMmsJson);
2108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2119037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        ContentProvider contentProvider = new MockContentProvider() {
2128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            @Override
2138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            public Cursor query(Uri uri, String[] projection, String selection,
2148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                String[] selectionArgs, String sortOrder) {
2158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                if (mCursors.containsKey(uri)) {
2168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    FakeCursor fakeCursor = mCursors.get(uri);
2178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    if (projection != null) {
2188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        fakeCursor.setProjection(projection);
2198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    }
22021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin                    fakeCursor.nextRow = 0;
2218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    return fakeCursor;
2228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                }
2239037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin                fail("No cursor for " + uri.toString());
2249037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin                return null;
2258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
2268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        };
2278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2289037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("sms", contentProvider);
2299037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("mms", contentProvider);
2309037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("mms-sms", mThreadProvider);
2319037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
2329037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent = new TelephonyBackupAgent();
2339037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.attach(new ContextWrapper(getContext()) {
2349037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            @Override
2359037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            public ContentResolver getContentResolver() {
2369037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin                return mMockContentResolver;
2379037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            }
2389037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        });
2399037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
2409037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
24121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.clearSharedPreferences();
2429037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.setContentResolver(mMockContentResolver);
2439037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.setSubId(mSubId2Phone, mPhone2SubId);
24421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    }
24521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
24621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    @Override
24721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    protected void tearDown() throws Exception {
24821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.clearSharedPreferences();
24921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        super.tearDown();
2508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
2518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2521d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    private static String makeJsonArray(String[] json) {
2538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        StringBuilder stringBuilder = new StringBuilder("[");
2548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        for (int i=0; i<json.length; ++i) {
2558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (i > 0) {
2568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                stringBuilder.append(",");
2578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
2588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            stringBuilder.append(json[i]);
2598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
2608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        stringBuilder.append("]");
2618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        return stringBuilder.toString();
2628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
2638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static ContentValues createSmsRow(int id, int subId, String address, String body,
2658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                              String subj, long date, long dateSent,
2668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                              int status, int type, long threadId) {
2678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        ContentValues smsRow = new ContentValues();
2688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms._ID, id);
2698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.SUBSCRIPTION_ID, subId);
2708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        if (address != null) {
2718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            smsRow.put(Telephony.Sms.ADDRESS, address);
2728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
2738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        if (body != null) {
2748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            smsRow.put(Telephony.Sms.BODY, body);
2758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
2768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        if (subj != null) {
2778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            smsRow.put(Telephony.Sms.SUBJECT, subj);
2788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
2798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.DATE, String.valueOf(date));
2808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.DATE_SENT, String.valueOf(dateSent));
2818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.STATUS, String.valueOf(status));
2828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.TYPE, String.valueOf(type));
2838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smsRow.put(Telephony.Sms.THREAD_ID, threadId);
2848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        return smsRow;
2868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
2878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
2888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private ContentValues createMmsRow(int id, int subId, String subj, int subCharset,
2898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                       long date, long dateSent, int type, int version,
2908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                       int textOnly, int msgBox,
2918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                       String contentLocation, String body,
2928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                                       int bodyCharset, String[] addresses, long threadId) {
2938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        ContentValues mmsRow = new ContentValues();
2948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms._ID, id);
2958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.SUBSCRIPTION_ID, subId);
2968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        if (subj != null) {
2978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            mmsRow.put(Telephony.Mms.SUBJECT, subj);
2988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            mmsRow.put(Telephony.Mms.SUBJECT_CHARSET, String.valueOf(subCharset));
2998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
3008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.DATE, String.valueOf(date));
3018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.DATE_SENT, String.valueOf(dateSent));
3028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.MESSAGE_TYPE, String.valueOf(type));
3038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.MMS_VERSION, String.valueOf(version));
3048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.TEXT_ONLY, textOnly);
3058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.MESSAGE_BOX, String.valueOf(msgBox));
3068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        if (contentLocation != null) {
3078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            mmsRow.put(Telephony.Mms.CONTENT_LOCATION, contentLocation);
3088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
3098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mmsRow.put(Telephony.Mms.THREAD_ID, threadId);
3108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).
3128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                appendPath("part").build();
3138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mCursors.put(partUri, createBodyCursor(body, bodyCharset));
3148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsAllContentValues.add(mmsRow);
3158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final Uri addrUri = Telephony.Mms.CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).
3178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                appendPath("addr").build();
3188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mCursors.put(addrUri, createAddrCursor(addresses));
3198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        return mmsRow;
3218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
3228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static final String APP_SMIL = "application/smil";
3248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static final String TEXT_PLAIN = "text/plain";
3258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    // Cursor with parts of Mms.
3278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private FakeCursor createBodyCursor(String body, int charset) {
3288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        List<ContentValues> table = new ArrayList<>();
3298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final String srcName = String.format("text.%06d.txt", 0);
3308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final String smilBody = String.format(TelephonyBackupAgent.sSmilTextPart, srcName);
3318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final String smil = String.format(TelephonyBackupAgent.sSmilTextOnly, smilBody);
3328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final ContentValues smilPart = new ContentValues();
3348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.SEQ, -1);
3358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.CONTENT_TYPE, APP_SMIL);
3368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.NAME, "smil.xml");
3378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.CONTENT_ID, "<smil>");
3388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.CONTENT_LOCATION, "smil.xml");
3398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        smilPart.put(Telephony.Mms.Part.TEXT, smil);
3408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsAllContentValues.add(smilPart);
3418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        final ContentValues bodyPart = new ContentValues();
3438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.SEQ, 0);
3448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.CONTENT_TYPE, TEXT_PLAIN);
3458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.NAME, srcName);
3468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.CONTENT_ID, "<"+srcName+">");
3478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.CONTENT_LOCATION, srcName);
3488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.CHARSET, charset);
3498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        bodyPart.put(Telephony.Mms.Part.TEXT, body);
3508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        table.add(bodyPart);
3518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsAllContentValues.add(bodyPart);
3528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        return new FakeCursor(table, TelephonyBackupAgent.MMS_TEXT_PROJECTION);
3548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
3558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    // Cursor with addresses of Mms.
3578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private FakeCursor createAddrCursor(String[] addresses) {
3588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        List<ContentValues> table = new ArrayList<>();
3598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        for (int i=0; i<addresses.length; ++i) {
3608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            ContentValues addr = new ContentValues();
3618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            addr.put(Telephony.Mms.Addr.TYPE, 10+i);
3628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            addr.put(Telephony.Mms.Addr.ADDRESS, addresses[i]);
363a632476534b877cdad602a27fe8ba01892d0bd83Roman Sorokin            addr.put(Telephony.Mms.Addr.CHARSET, 100+i);
3648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            mMmsAllContentValues.add(addr);
3658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            table.add(addr);
3668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
3678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        return new FakeCursor(table, TelephonyBackupAgent.MMS_ADDR_PROJECTION);
3688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
3698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
3718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with no sms in the provider.
3728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
3738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
3748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testBackupSms_NoSms() throws Exception {
3759037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
3768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString());
3778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
3788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
3808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with 3 sms in the provider with the limit per file 4.
3818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
3828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
3831d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    public void testBackupSms_AllSms() throws Exception {
3849037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 4;
3858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsTable.addAll(Arrays.asList(mSmsRows));
3869037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
3871d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        assertEquals(mAllSmsJson, mStringWriter.toString());
3888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
3898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
3908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
3918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with 3 sms in the provider with the limit per file 3.
3928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
3938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
3941d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    public void testBackupSms_AllSmsWithExactFileLimit() throws Exception {
3959037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 3;
3968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsTable.addAll(Arrays.asList(mSmsRows));
3979037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
3981d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        assertEquals(mAllSmsJson, mStringWriter.toString());
3998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with 3 sms in the provider with the limit per file 1.
4038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4051d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    public void testBackupSms_AllSmsOneMessagePerFile() throws Exception {
4069037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 1;
4078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mSmsTable.addAll(Arrays.asList(mSmsRows));
4081d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
4099037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
4108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mSmsJson[0] + "]", mStringWriter.toString());
4118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mStringWriter = new StringWriter();
4139037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
4148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mSmsJson[1] + "]", mStringWriter.toString());
4158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mStringWriter = new StringWriter();
4179037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter));
4188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mSmsJson[2] + "]", mStringWriter.toString());
4198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with no mms in the pvovider.
4238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testBackupMms_NoMms() throws Exception {
4269037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString());
4288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with all mms.
4328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testBackupMms_AllMms() throws Exception {
4359037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 4;
4368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsTable.addAll(Arrays.asList(mMmsRows));
4379037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4381d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        assertEquals(mAllMmsJson, mStringWriter.toString());
4398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with 3 mms in the provider with the limit per file 1.
4438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testBackupMms_OneMessagePerFile() throws Exception {
4469037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 1;
4478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsTable.addAll(Arrays.asList(mMmsRows));
4489037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mMmsJson[0] + "]", mStringWriter.toString());
4508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mStringWriter = new StringWriter();
4529037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mMmsJson[1] + "]", mStringWriter.toString());
4548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mStringWriter = new StringWriter();
4569037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals("[" + mMmsJson[2] + "]", mStringWriter.toString());
4588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test with 3 mms in the provider with the limit per file 3.
4628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testBackupMms_WithExactFileLimit() throws Exception {
4658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        mMmsTable.addAll(Arrays.asList(mMmsRows));
4669037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 3;
4679037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter));
4681d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        assertEquals(mAllMmsJson, mStringWriter.toString());
4698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test restore sms with the empty json array "[]".
4738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testRestoreSms_NoSms() throws Exception {
4768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        JsonReader jsonReader = new JsonReader(new StringReader(EMPTY_JSON_ARRAY));
4778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        FakeSmsProvider smsProvider = new FakeSmsProvider(null);
4789037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("sms", smsProvider);
4799037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader);
4808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals(0, smsProvider.getRowsAdded());
4818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test restore sms with three sms json object in the array.
4858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
4871d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    public void testRestoreSms_AllSms() throws Exception {
4889037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllSmsJson)));
4898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        FakeSmsProvider smsProvider = new FakeSmsProvider(mSmsRows);
4909037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("sms", smsProvider);
4919037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader);
4928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals(mSmsRows.length, smsProvider.getRowsAdded());
4933aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        assertEquals(mThreadProvider.mIsThreadArchived, mThreadProvider.mUpdateThreadsArchived);
4948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
4958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
4968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
4978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * Test restore mms with the empty json array "[]".
4988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * @throws Exception
4998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
5008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    public void testRestoreMms_NoMms() throws Exception {
5018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        JsonReader jsonReader = new JsonReader(new StringReader(EMPTY_JSON_ARRAY));
5028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        FakeMmsProvider mmsProvider = new FakeMmsProvider(null);
5039037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("mms", mmsProvider);
5049037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToProvider(jsonReader);
5058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        assertEquals(0, mmsProvider.getRowsAdded());
5068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
5078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
5088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
5099037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin     * Test restore sms with three mms json object in the array.
5109037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin     * @throws Exception
5119037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin     */
5129037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    public void testRestoreMms_AllMms() throws Exception {
5139037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllMmsJson)));
5149037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        FakeMmsProvider mmsProvider = new FakeMmsProvider(mMmsAllContentValues);
5159037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mMockContentResolver.addProvider("mms", mmsProvider);
5169037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.putMmsMessagesToProvider(jsonReader);
5179037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        assertEquals(18, mmsProvider.getRowsAdded());
5183aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        assertEquals(mThreadProvider.mIsThreadArchived, mThreadProvider.mUpdateThreadsArchived);
5199037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    }
5209037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin
5219037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    /**
52221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin     * Test with quota exceeded. Checking size of the backup before it hits quota and after.
52321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin     * It still backs up more than a quota since there is meta-info which matters with small amounts
52421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin     * of data. The agent does not take backup meta-info into consideration.
52521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin     * @throws Exception
52621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin     */
52721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    public void testBackup_WithQuotaExceeded() throws Exception {
5289037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        mTelephonyBackupAgent.mMaxMsgPerFile = 1;
52921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        final int backupSize = 6144;
53021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        final int backupSizeAfterFirstQuotaHit = 5120;
53121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        final int backupSizeAfterSecondQuotaHit = 4096;
53221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
53321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mSmsTable.addAll(Arrays.asList(mSmsRows));
53421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mMmsTable.addAll(Arrays.asList(mMmsRows));
53521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
53621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        FullBackupDataOutput fullBackupDataOutput = new FullBackupDataOutput();
53721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
53821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        assertEquals(backupSize, fullBackupDataOutput.getSize());
53921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
54021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.onQuotaExceeded(backupSize, backupSize - 100);
54121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        fullBackupDataOutput = new FullBackupDataOutput();
54221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
54321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        assertEquals(backupSizeAfterFirstQuotaHit, fullBackupDataOutput.getSize());
54421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
54521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.onQuotaExceeded(backupSizeAfterFirstQuotaHit,
54621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin                backupSizeAfterFirstQuotaHit - 200);
54721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        fullBackupDataOutput = new FullBackupDataOutput();
54821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput);
54921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        assertEquals(backupSizeAfterSecondQuotaHit, fullBackupDataOutput.getSize());
55021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin    }
55121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
5529037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    // Adding random keys to JSON to test handling it by the BackupAgent on restore.
5539037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin    private String addRandomDataToJson(String jsonString) throws JSONException {
5549037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        JSONArray jsonArray = new JSONArray(jsonString);
5559037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        JSONArray res = new JSONArray();
5569037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        for (int i = 0; i < jsonArray.length(); ++i) {
5579037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            JSONObject jsonObject = jsonArray.getJSONObject(i);
5589037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            jsonObject.put(UUID.randomUUID().toString(), UUID.randomUUID().toString());
5599037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin            res = res.put(jsonObject);
5609037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        }
5619037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin        return res.toString();
5621d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin    }
5631d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
5648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
5658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * class for checking sms insertion into the provider on restore.
5668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
5678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private class FakeSmsProvider extends MockContentProvider {
5688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private int nextRow = 0;
5698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private ContentValues[] mSms;
5708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
5718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public FakeSmsProvider(ContentValues[] sms) {
5728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            this.mSms = sms;
5738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
5748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
5758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
5768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public Uri insert(Uri uri, ContentValues values) {
5778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            assertEquals(Telephony.Sms.CONTENT_URI, uri);
5788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            ContentValues modifiedValues = new ContentValues(mSms[nextRow++]);
5798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            modifiedValues.remove(Telephony.Sms._ID);
5808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            modifiedValues.put(Telephony.Sms.READ, 1);
5818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            modifiedValues.put(Telephony.Sms.SEEN, 1);
5828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (mSubId2Phone.get(modifiedValues.getAsInteger(Telephony.Sms.SUBSCRIPTION_ID))
5838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    == null) {
5848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.put(Telephony.Sms.SUBSCRIPTION_ID, -1);
5858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
5868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
5878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            assertEquals(modifiedValues, values);
5888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return null;
5898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
5908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
5918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
59221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        public int bulkInsert(Uri uri, ContentValues[] values) {
59321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin            for (ContentValues cv : values) {
59421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin                insert(uri, cv);
59521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin            }
59621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin            return values.length;
59721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        }
59821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin
59921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        @Override
6008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
6018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                            String sortOrder) {
6028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return null;
6038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getRowsAdded() {
6068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return nextRow;
6078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
6098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
6118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * class for checking mms insertion into the provider on restore.
6128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
6138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private class FakeMmsProvider extends MockContentProvider {
6148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private int nextRow = 0;
6158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private List<ContentValues> mValues;
6168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private long mDummyMsgId = -1;
6178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        private long mMsgId = -1;
6188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public FakeMmsProvider(List<ContentValues> values) {
6208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            this.mValues = values;
6218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
6248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public Uri insert(Uri uri, ContentValues values) {
6258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            Uri retUri = Uri.parse("dummy_uri");
6268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            ContentValues modifiedValues = new ContentValues(mValues.get(nextRow++));
6278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (APP_SMIL.equals(values.get(Telephony.Mms.Part.CONTENT_TYPE))) {
6288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                // Smil part.
6298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                assertEquals(-1, mDummyMsgId);
6308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                mDummyMsgId = values.getAsLong(Telephony.Mms.Part.MSG_ID);
6318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (values.get(Telephony.Mms.Part.SEQ) != null) {
6348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                // Part of mms.
6358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon()
6368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .appendPath(String.valueOf(mDummyMsgId))
6378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .appendPath("part")
6388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .build();
6398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                assertEquals(expectedUri, uri);
6408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (values.get(Telephony.Mms.Part.MSG_ID) != null) {
6438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.put(Telephony.Mms.Part.MSG_ID, mDummyMsgId);
6448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (values.get(Telephony.Mms.SUBSCRIPTION_ID) != null) {
6488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                assertEquals(Telephony.Mms.CONTENT_URI, uri);
6498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                if (mSubId2Phone.get(modifiedValues.getAsInteger(Telephony.Sms.SUBSCRIPTION_ID))
6508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        == null) {
6518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    modifiedValues.put(Telephony.Sms.SUBSCRIPTION_ID, -1);
6528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                }
6538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                // Mms.
6548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.put(Telephony.Mms.READ, 1);
6558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.put(Telephony.Mms.SEEN, 1);
6568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                mMsgId = modifiedValues.getAsInteger(BaseColumns._ID);
6578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                retUri = Uri.withAppendedPath(Telephony.Mms.CONTENT_URI, String.valueOf(mMsgId));
6588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.remove(BaseColumns._ID);
6598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            if (values.get(Telephony.Mms.Addr.ADDRESS) != null) {
6628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                // Address.
6638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon()
6648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .appendPath(String.valueOf(mMsgId))
6658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .appendPath("addr")
6668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                        .build();
6678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                assertEquals(expectedUri, uri);
6688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                assertNotSame(-1, mMsgId);
6698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                modifiedValues.put(Telephony.Mms.Addr.MSG_ID, mMsgId);
6708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                mDummyMsgId = -1;
6718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            for (String key : modifiedValues.keySet()) {
67476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin                assertEquals("Key:"+key, modifiedValues.get(key), values.get(key));
6758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
6768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            assertEquals(modifiedValues.size(), values.size());
6778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return retUri;
6788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
6818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
6828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon()
6838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    .appendPath(String.valueOf(mDummyMsgId))
6848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    .appendPath("part")
6858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    .build();
6868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            assertEquals(expectedUri, uri);
6878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            ContentValues expected = new ContentValues();
6888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            expected.put(Telephony.Mms.Part.MSG_ID, mMsgId);
6898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            assertEquals(expected, values);
6908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return 2;
6918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
6948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
6958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                            String sortOrder) {
6968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return null;
6978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
6988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
6998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getRowsAdded() {
7008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return nextRow;
7018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
7028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
7038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
7048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
7058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * class that implements MmsSms provider for thread ids.
7068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
7078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static class ThreadProvider extends MockContentProvider {
7081d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        ArrayList<Set<Integer> > id2Thread = new ArrayList<>();
7091d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        ArrayList<String> id2Recipient = new ArrayList<>();
7103aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        Set<Integer> mIsThreadArchived = new HashSet<>();
7113aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        Set<Integer> mUpdateThreadsArchived = new HashSet<>();
7123aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin
7131d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
7141d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        public int getOrCreateThreadId(final String[] recipients) {
7151d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            Set<Integer> ids = new ArraySet<>();
7161d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            for (String rec : recipients) {
7171d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                if (!id2Recipient.contains(rec)) {
7181d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                    id2Recipient.add(rec);
7191d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                }
7201d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                ids.add(id2Recipient.indexOf(rec)+1);
7211d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            }
7221d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            if (!id2Thread.contains(ids)) {
7231d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                id2Thread.add(ids);
7241d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            }
7251d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            return id2Thread.indexOf(ids)+1;
7261d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        }
7278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
7283aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        public void setArchived(int threadId) {
7293aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            mIsThreadArchived.add(threadId);
7303aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        }
7313aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin
7321d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        private String getSpaceSepIds(int threadId) {
7331d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            String spaceSepIds = null;
7341d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            for (Integer id : id2Thread.get(threadId-1)) {
7351d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                spaceSepIds = (spaceSepIds == null ? "" : spaceSepIds + " ") + String.valueOf(id);
7361d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            }
7371d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            return spaceSepIds;
7381d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        }
7398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
7401d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin        private String getRecipient(int recipientId) {
7411d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            return id2Recipient.get(recipientId-1);
7428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
7438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
7448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
7458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
7468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                            String sortOrder) {
7471d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            if (uri.equals(TelephonyBackupAgent.ALL_THREADS_URI)) {
7481d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                final int threadId = Integer.parseInt(selectionArgs[0]);
7491d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                final String spaceSepIds = getSpaceSepIds(threadId);
7501d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                List<ContentValues> table = new ArrayList<>();
7511d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                ContentValues row = new ContentValues();
7521d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                row.put(Telephony.Threads.RECIPIENT_IDS, spaceSepIds);
7531d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                table.add(row);
7541d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                return new FakeCursor(table, projection);
7553aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            } else if (uri.toString().startsWith(Telephony.Threads.CONTENT_URI.toString())) {
7563aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                assertEquals(1, projection.length);
7573aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                assertEquals(Telephony.Threads.ARCHIVED, projection[0]);
7583aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                List<String> segments = uri.getPathSegments();
7593aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                final int threadId = Integer.parseInt(segments.get(segments.size() - 2));
7603aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                List<ContentValues> table = new ArrayList<>();
7613aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                ContentValues row = new ContentValues();
7623aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                row.put(Telephony.Threads.ARCHIVED, mIsThreadArchived.contains(threadId) ? 1 : 0);
7633aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                table.add(row);
7643aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                return new FakeCursor(table, projection);
7651d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            } else if (uri.toString().startsWith(
7661d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                    TelephonyBackupAgent.SINGLE_CANONICAL_ADDRESS_URI.toString())) {
7671d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                final int recipientId = (int)ContentUris.parseId(uri);
7681d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                final String recipient = getRecipient(recipientId);
7691d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                List<ContentValues> table = new ArrayList<>();
7701d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                ContentValues row = new ContentValues();
7711d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                row.put(Telephony.CanonicalAddressesColumns.ADDRESS, recipient);
7721d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                table.add(row);
7731d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
7741d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                return new FakeCursor(table,
7751d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                        projection != null
7761d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                                ? projection
7771d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                                : new String[] { Telephony.CanonicalAddressesColumns.ADDRESS });
7781d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            } else if (uri.toString().startsWith(
7791d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                    TelephonyBackupAgent.THREAD_ID_CONTENT_URI.toString())) {
7801d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                List<String> recipients = uri.getQueryParameters("recipient");
7811d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin
7821d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                final int threadId =
7831d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                        getOrCreateThreadId(recipients.toArray(new String[recipients.size()]));
7841d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                List<ContentValues> table = new ArrayList<>();
7851d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                ContentValues row = new ContentValues();
7861d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                row.put(BaseColumns._ID, String.valueOf(threadId));
7871d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                table.add(row);
7881d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin                return new FakeCursor(table, projection);
7893aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            } else {
7903aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin                fail("Unknown URI");
7913aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            }
7921d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin            return null;
7938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
7943aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin
7953aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        @Override
7963aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
7973aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            assertEquals(uri, Telephony.Threads.CONTENT_URI);
7983aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            assertEquals(values.getAsInteger(Telephony.Threads.ARCHIVED).intValue(), 1);
7993aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            final int threadId = Integer.parseInt(selectionArgs[0]);
8003aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            mUpdateThreadsArchived.add(threadId);
8013aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin            return 1;
8023aa281731a6f25cd36b88bca809b13d3f581d05fRoman Sorokin        }
8038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
8048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    /**
8068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     * general cursor for serving queries.
8078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin     */
8088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    private static class FakeCursor extends MockCursor {
8098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        String[] projection;
8108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        List<ContentValues> rows;
81121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin        int nextRow = 0;
8128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public FakeCursor(List<ContentValues> rows, String[] projection) {
8148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            this.projection = projection;
8158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            this.rows = rows;
8168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public void setProjection(String[] projection) {
8198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            this.projection = projection;
8208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getColumnCount() {
8248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return projection.length;
8258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public String getColumnName(int columnIndex) {
8298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return projection[columnIndex];
8308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public String getString(int columnIndex) {
8348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return rows.get(nextRow).getAsString(projection[columnIndex]);
8358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getInt(int columnIndex) {
8398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return rows.get(nextRow).getAsInteger(projection[columnIndex]);
8408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public long getLong(int columnIndex) {
8448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return rows.get(nextRow).getAsLong(projection[columnIndex]);
8458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public boolean isAfterLast() {
8498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return nextRow >= getCount();
8508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public boolean isLast() {
8548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return nextRow == getCount() - 1;
8558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public boolean moveToFirst() {
8598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            nextRow = 0;
8608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return getCount() > 0;
8618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public boolean moveToNext() {
8658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return getCount() > ++nextRow;
8668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getCount() {
8708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return rows.size();
8718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public int getColumnIndex(String columnName) {
8758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            for (int i=0; i<projection.length; ++i) {
8768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                if (columnName.equals(projection[i])) {
8778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                    return i;
8788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin                }
8798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            }
8808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin            return -1;
8818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin
8838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        @Override
8848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        public void close() {
8858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin        }
8868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin    }
8878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin}
888