TelephonyBackupAgentTest.java revision 9037d648d61f3d90726e43296f0b12c532e1f934
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; 518b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.List; 528b39acf181c547e87161873112d6c52a581fc778Roman Sorokinimport java.util.Map; 531d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokinimport java.util.Set; 549037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokinimport java.util.UUID; 558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin/** 588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Tests for testing backup/restore of SMS and text MMS messages. 598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * For backup it creates fake provider and checks resulting json array. 608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * For restore provides json array and checks inserts of the messages into provider. 618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin@TargetApi(Build.VERSION_CODES.M) 638b39acf181c547e87161873112d6c52a581fc778Roman Sorokinpublic class TelephonyBackupAgentTest extends AndroidTestCase { 641d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Map subscriptionId -> phone number */ 658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private SparseArray<String> mSubId2Phone; 661d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Map phone number -> subscriptionId */ 678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private ArrayMap<String, Integer> mPhone2SubId; 681d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Table being used for sms cursor */ 698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private final List<ContentValues> mSmsTable = new ArrayList<>(); 701d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Table begin used for mms cursor */ 718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private final List<ContentValues> mMmsTable = new ArrayList<>(); 721d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Table contains parts, addresses of mms */ 738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private final List<ContentValues> mMmsAllContentValues = new ArrayList<>(); 741d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Cursors being used to access sms, mms tables */ 758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private FakeCursor mSmsCursor, mMmsCursor; 761d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Test data with sms and mms */ 778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private ContentValues[] mSmsRows, mMmsRows; 781d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Json representation for the test data */ 798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private String[] mSmsJson, mMmsJson; 801d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* sms, mms json concatenated as json array */ 818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private String mAllSmsJson, mAllMmsJson; 828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private StringWriter mStringWriter; 841d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 859037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin /* Content resolver passed to the backupAgent */ 869037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin private MockContentResolver mMockContentResolver = new MockContentResolver(); 879037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin 881d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Map uri -> cursors. Being used for contentprovider. */ 898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private Map<Uri, FakeCursor> mCursors; 9076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin /* Content provider with threadIds.*/ 9176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin private ThreadProvider mThreadProvider = new ThreadProvider(); 928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static final String EMPTY_JSON_ARRAY = "[]"; 9421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 9521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin TelephonyBackupAgent mTelephonyBackupAgent; 9621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin protected void setUp() throws Exception { 998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin super.setUp(); 1001d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 1011d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Filling up subscription maps */ 1028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mStringWriter = new StringWriter(); 1038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSubId2Phone = new SparseArray<String>(); 1048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSubId2Phone.append(1, "+111111111111111"); 1058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSubId2Phone.append(3, "+333333333333333"); 1068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mPhone2SubId = new ArrayMap<>(); 1088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin for (int i=0; i<mSubId2Phone.size(); ++i) { 1098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mPhone2SubId.put(mSubId2Phone.valueAt(i), mSubId2Phone.keyAt(i)); 1108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 1118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 11221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mCursors = new HashMap<Uri, FakeCursor>(); 1131d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Bind tables to the cursors */ 1148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsCursor = new FakeCursor(mSmsTable, TelephonyBackupAgent.SMS_PROJECTION); 11521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mCursors.put(Telephony.Sms.CONTENT_URI, mSmsCursor); 1168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsCursor = new FakeCursor(mMmsTable, TelephonyBackupAgent.MMS_PROJECTION); 11721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mCursors.put(Telephony.Mms.CONTENT_URI, mMmsCursor); 1181d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 1198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1201d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin /* Generating test data */ 1218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsRows = new ContentValues[3]; 1228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsJson = new String[3]; 1238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsRows[0] = createSmsRow(1, 1, "+1232132214124", "sms 1", "sms subject", 9087978987l, 1248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 999999999, 3, 44, 1); 1258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsJson[0] = "{\"self_phone\":\"+111111111111111\",\"address\":" + 1268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"+1232132214124\",\"body\":\"sms 1\",\"subject\":\"sms subject\",\"date\":" + 1271d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin "\"9087978987\",\"date_sent\":\"999999999\",\"status\":\"3\",\"type\":\"44\"," + 12876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"+123 (213) 2214124\"]}"; 12976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin mThreadProvider.getOrCreateThreadId(new String[]{"+123 (213) 2214124"}); 1308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsRows[1] = createSmsRow(2, 2, "+1232132214124", "sms 2", null, 9087978987l, 999999999, 1328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 0, 4, 1); 1338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsJson[1] = "{\"address\":\"+1232132214124\",\"body\":\"sms 2\",\"date\":" + 1341d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin "\"9087978987\",\"date_sent\":\"999999999\",\"status\":\"0\",\"type\":\"4\"," + 13576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"+123 (213) 2214124\"]}"; 1368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsRows[2] = createSmsRow(4, 3, "+1232221412433 +1232221412444", "sms 3", null, 1388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 111111111111l, 999999999, 2, 3, 2); 1398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsJson[2] = "{\"self_phone\":\"+333333333333333\",\"address\":" + 1408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"+1232221412433 +1232221412444\",\"body\":\"sms 3\",\"date\":\"111111111111\"," + 1418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"date_sent\":" + 1421d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin "\"999999999\",\"status\":\"2\",\"type\":\"3\"," + 14376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"+1232221412433\",\"+1232221412444\"]}"; 14476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin mThreadProvider.getOrCreateThreadId(new String[]{"+1232221412433", "+1232221412444"}); 1458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1461d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin mAllSmsJson = makeJsonArray(mSmsJson); 1478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsRows = new ContentValues[3]; 1518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsJson = new String[3]; 1528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsRows[0] = createMmsRow(1 /*id*/, 1 /*subid*/, "Subject 1" /*subject*/, 1538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 100 /*subcharset*/, 111111 /*date*/, 111112 /*datesent*/, 3 /*type*/, 1548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 17 /*version*/, 1 /*textonly*/, 1558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 11 /*msgBox*/, "location 1" /*contentLocation*/, "MMs body 1" /*body*/, 1568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 111 /*body charset*/, 15776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin new String[]{"+111 (111) 11111111", "+11121212", "example@example.com", 15876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "+999999999"} /*addresses*/, 15976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin 3 /*threadId*/); 1608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsJson[0] = "{\"self_phone\":\"+111111111111111\",\"sub\":\"Subject 1\"," + 1628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"date\":\"111111\",\"date_sent\":\"111112\",\"m_type\":\"3\",\"v\":\"17\"," + 16376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"msg_box\":\"11\",\"ct_l\":\"location 1\"," + 16476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"+11121212\",\"example@example.com\",\"+999999999\"]," + 16576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"mms_addresses\":" + 16676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "[{\"type\":10,\"address\":\"+111 (111) 11111111\",\"charset\":100}," + 16776422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "{\"type\":11,\"address\":\"+11121212\",\"charset\":101},{\"type\":12,\"address\":"+ 16876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"example@example.com\",\"charset\":102},{\"type\":13,\"address\":\"+999999999\"" + 16976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin ",\"charset\":103}],\"mms_body\":\"MMs body 1\",\"mms_charset\":111,\"" + 1708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "sub_cs\":\"100\"}"; 17176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin mThreadProvider.getOrCreateThreadId(new String[]{"+11121212", "example@example.com", 17276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "+999999999"}); 1738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsRows[1] = createMmsRow(2 /*id*/, 2 /*subid*/, null /*subject*/, 100 /*subcharset*/, 1758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 111122 /*date*/, 1111112 /*datesent*/, 4 /*type*/, 18 /*version*/, 1 /*textonly*/, 1768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 222 /*msgBox*/, "location 2" /*contentLocation*/, "MMs body 2" /*body*/, 1778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 121 /*body charset*/, 17876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin new String[]{"+7 (333) ", "example@example.com", "+999999999"} /*addresses*/, 17976422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin 4 /*threadId*/); 1808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsJson[1] = "{\"date\":\"111122\",\"date_sent\":\"1111112\",\"m_type\":\"4\"," + 18176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"v\":\"18\",\"msg_box\":\"222\",\"ct_l\":\"location 2\"," + 18276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"example@example.com\",\"+999999999\"]," + 18376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"mms_addresses\":" + 18476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "[{\"type\":10,\"address\":\"+7 (333) \",\"charset\":100}," + 18576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "{\"type\":11,\"address\":\"example@example.com\",\"charset\":101}," + 18676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "{\"type\":12,\"address\":\"+999999999\",\"charset\":102}]," + 1878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"mms_body\":\"MMs body 2\",\"mms_charset\":121}"; 18876422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin mThreadProvider.getOrCreateThreadId(new String[]{"example@example.com", "+999999999"}); 1898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 19076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin mMmsRows[2] = createMmsRow(9 /*id*/, 3 /*subid*/, "Subject 10" /*subject*/, 1918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 10 /*subcharset*/, 111133 /*date*/, 1111132 /*datesent*/, 5 /*type*/, 1928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 19 /*version*/, 1 /*textonly*/, 1938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 333 /*msgBox*/, null /*contentLocation*/, "MMs body 3" /*body*/, 19476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin 131 /*body charset*/, 19576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin new String[]{"333 333333333333", "+1232132214124"} /*addresses*/, 19676422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin 1 /*threadId*/); 1978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 1988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsJson[2] = "{\"self_phone\":\"+333333333333333\",\"sub\":\"Subject 10\"," + 1998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"date\":\"111133\",\"date_sent\":\"1111132\",\"m_type\":\"5\",\"v\":\"19\"," + 20076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"msg_box\":\"333\"," + 20176422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"recipients\":[\"+123 (213) 2214124\"]," + 20276422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"mms_addresses\":" + 20376422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "[{\"type\":10,\"address\":\"333 333333333333\",\"charset\":100}," + 20476422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "{\"type\":11,\"address\":\"+1232132214124\",\"charset\":101}]," + 20576422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin "\"mms_body\":\"MMs body 3\",\"mms_charset\":131," + 2068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin "\"sub_cs\":\"10\"}"; 2071d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin mAllMmsJson = makeJsonArray(mMmsJson); 2088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2099037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin ContentProvider contentProvider = new MockContentProvider() { 2108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 2118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Cursor query(Uri uri, String[] projection, String selection, 2128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String[] selectionArgs, String sortOrder) { 2138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (mCursors.containsKey(uri)) { 2148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin FakeCursor fakeCursor = mCursors.get(uri); 2158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (projection != null) { 2168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin fakeCursor.setProjection(projection); 2178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 21821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin fakeCursor.nextRow = 0; 2198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return fakeCursor; 2208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2219037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin fail("No cursor for " + uri.toString()); 2229037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin return null; 2238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin }; 2258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2269037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("sms", contentProvider); 2279037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("mms", contentProvider); 2289037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("mms-sms", mThreadProvider); 2299037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin 2309037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent = new TelephonyBackupAgent(); 2319037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.attach(new ContextWrapper(getContext()) { 2329037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin @Override 2339037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin public ContentResolver getContentResolver() { 2349037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin return mMockContentResolver; 2359037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin } 2369037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin }); 2379037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin 2389037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin 23921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.clearSharedPreferences(); 2409037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.setContentResolver(mMockContentResolver); 2419037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.setSubId(mSubId2Phone, mPhone2SubId); 24221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin } 24321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 24421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin @Override 24521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin protected void tearDown() throws Exception { 24621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.clearSharedPreferences(); 24721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin super.tearDown(); 2488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2501d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin private static String makeJsonArray(String[] json) { 2518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin StringBuilder stringBuilder = new StringBuilder("["); 2528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin for (int i=0; i<json.length; ++i) { 2538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (i > 0) { 2548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin stringBuilder.append(","); 2558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin stringBuilder.append(json[i]); 2578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin stringBuilder.append("]"); 2598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return stringBuilder.toString(); 2608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static ContentValues createSmsRow(int id, int subId, String address, String body, 2638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String subj, long date, long dateSent, 2648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin int status, int type, long threadId) { 2658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues smsRow = new ContentValues(); 2668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms._ID, id); 2678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.SUBSCRIPTION_ID, subId); 2688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (address != null) { 2698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.ADDRESS, address); 2708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (body != null) { 2728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.BODY, body); 2738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (subj != null) { 2758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.SUBJECT, subj); 2768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.DATE, String.valueOf(date)); 2788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.DATE_SENT, String.valueOf(dateSent)); 2798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.STATUS, String.valueOf(status)); 2808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.TYPE, String.valueOf(type)); 2818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smsRow.put(Telephony.Sms.THREAD_ID, threadId); 2828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return smsRow; 2848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 2868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private ContentValues createMmsRow(int id, int subId, String subj, int subCharset, 2878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin long date, long dateSent, int type, int version, 2888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin int textOnly, int msgBox, 2898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String contentLocation, String body, 2908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin int bodyCharset, String[] addresses, long threadId) { 2918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues mmsRow = new ContentValues(); 2928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms._ID, id); 2938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.SUBSCRIPTION_ID, subId); 2948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (subj != null) { 2958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.SUBJECT, subj); 2968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.SUBJECT_CHARSET, String.valueOf(subCharset)); 2978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 2988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.DATE, String.valueOf(date)); 2998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.DATE_SENT, String.valueOf(dateSent)); 3008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.MESSAGE_TYPE, String.valueOf(type)); 3018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.MMS_VERSION, String.valueOf(version)); 3028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.TEXT_ONLY, textOnly); 3038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.MESSAGE_BOX, String.valueOf(msgBox)); 3048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (contentLocation != null) { 3058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.CONTENT_LOCATION, contentLocation); 3068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mmsRow.put(Telephony.Mms.THREAD_ID, threadId); 3088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final Uri partUri = Telephony.Mms.CONTENT_URI.buildUpon().appendPath(String.valueOf(id)). 3108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin appendPath("part").build(); 3118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mCursors.put(partUri, createBodyCursor(body, bodyCharset)); 3128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsAllContentValues.add(mmsRow); 3138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final Uri addrUri = Telephony.Mms.CONTENT_URI.buildUpon().appendPath(String.valueOf(id)). 3158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin appendPath("addr").build(); 3168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mCursors.put(addrUri, createAddrCursor(addresses)); 3178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return mmsRow; 3198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static final String APP_SMIL = "application/smil"; 3228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static final String TEXT_PLAIN = "text/plain"; 3238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Cursor with parts of Mms. 3258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private FakeCursor createBodyCursor(String body, int charset) { 3268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin List<ContentValues> table = new ArrayList<>(); 3278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final String srcName = String.format("text.%06d.txt", 0); 3288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final String smilBody = String.format(TelephonyBackupAgent.sSmilTextPart, srcName); 3298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final String smil = String.format(TelephonyBackupAgent.sSmilTextOnly, smilBody); 3308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final ContentValues smilPart = new ContentValues(); 3328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.SEQ, -1); 3338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.CONTENT_TYPE, APP_SMIL); 3348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.NAME, "smil.xml"); 3358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.CONTENT_ID, "<smil>"); 3368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.CONTENT_LOCATION, "smil.xml"); 3378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin smilPart.put(Telephony.Mms.Part.TEXT, smil); 3388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsAllContentValues.add(smilPart); 3398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final ContentValues bodyPart = new ContentValues(); 3418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.SEQ, 0); 3428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.CONTENT_TYPE, TEXT_PLAIN); 3438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.NAME, srcName); 3448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.CONTENT_ID, "<"+srcName+">"); 3458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.CONTENT_LOCATION, srcName); 3468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.CHARSET, charset); 3478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin bodyPart.put(Telephony.Mms.Part.TEXT, body); 3488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin table.add(bodyPart); 3498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsAllContentValues.add(bodyPart); 3508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return new FakeCursor(table, TelephonyBackupAgent.MMS_TEXT_PROJECTION); 3528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Cursor with addresses of Mms. 3558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private FakeCursor createAddrCursor(String[] addresses) { 3568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin List<ContentValues> table = new ArrayList<>(); 3578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin for (int i=0; i<addresses.length; ++i) { 3588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues addr = new ContentValues(); 3598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin addr.put(Telephony.Mms.Addr.TYPE, 10+i); 3608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin addr.put(Telephony.Mms.Addr.ADDRESS, addresses[i]); 361a632476534b877cdad602a27fe8ba01892d0bd83Roman Sorokin addr.put(Telephony.Mms.Addr.CHARSET, 100+i); 3628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsAllContentValues.add(addr); 3638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin table.add(addr); 3648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return new FakeCursor(table, TelephonyBackupAgent.MMS_ADDR_PROJECTION); 3668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 3698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with no sms in the provider. 3708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 3718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 3728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testBackupSms_NoSms() throws Exception { 3739037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 3748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString()); 3758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 3788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with 3 sms in the provider with the limit per file 4. 3798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 3808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 3811d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin public void testBackupSms_AllSms() throws Exception { 3829037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 4; 3838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsTable.addAll(Arrays.asList(mSmsRows)); 3849037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 3851d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin assertEquals(mAllSmsJson, mStringWriter.toString()); 3868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 3898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with 3 sms in the provider with the limit per file 3. 3908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 3918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 3921d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin public void testBackupSms_AllSmsWithExactFileLimit() throws Exception { 3939037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 3; 3948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsTable.addAll(Arrays.asList(mSmsRows)); 3959037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 3961d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin assertEquals(mAllSmsJson, mStringWriter.toString()); 3978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 3988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 3998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with 3 sms in the provider with the limit per file 1. 4018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4031d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin public void testBackupSms_AllSmsOneMessagePerFile() throws Exception { 4049037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 1; 4058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mSmsTable.addAll(Arrays.asList(mSmsRows)); 4061d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 4079037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 4088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mSmsJson[0] + "]", mStringWriter.toString()); 4098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mStringWriter = new StringWriter(); 4119037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 4128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mSmsJson[1] + "]", mStringWriter.toString()); 4138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mStringWriter = new StringWriter(); 4159037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToJson(mSmsCursor, new JsonWriter(mStringWriter)); 4168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mSmsJson[2] + "]", mStringWriter.toString()); 4178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with no mms in the pvovider. 4218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testBackupMms_NoMms() throws Exception { 4249037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(EMPTY_JSON_ARRAY, mStringWriter.toString()); 4268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with all mms. 4308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testBackupMms_AllMms() throws Exception { 4339037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 4; 4348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsTable.addAll(Arrays.asList(mMmsRows)); 4359037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4361d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin assertEquals(mAllMmsJson, mStringWriter.toString()); 4378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with 3 mms in the provider with the limit per file 1. 4418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testBackupMms_OneMessagePerFile() throws Exception { 4449037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 1; 4458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsTable.addAll(Arrays.asList(mMmsRows)); 4469037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mMmsJson[0] + "]", mStringWriter.toString()); 4488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mStringWriter = new StringWriter(); 4509037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mMmsJson[1] + "]", mStringWriter.toString()); 4528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mStringWriter = new StringWriter(); 4549037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals("[" + mMmsJson[2] + "]", mStringWriter.toString()); 4568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test with 3 mms in the provider with the limit per file 3. 4608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testBackupMms_WithExactFileLimit() throws Exception { 4638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMmsTable.addAll(Arrays.asList(mMmsRows)); 4649037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 3; 4659037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToJson(mMmsCursor, new JsonWriter(mStringWriter)); 4661d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin assertEquals(mAllMmsJson, mStringWriter.toString()); 4678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test restore sms with the empty json array "[]". 4718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testRestoreSms_NoSms() throws Exception { 4748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin JsonReader jsonReader = new JsonReader(new StringReader(EMPTY_JSON_ARRAY)); 4758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin FakeSmsProvider smsProvider = new FakeSmsProvider(null); 4769037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("sms", smsProvider); 4779037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader); 4788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(0, smsProvider.getRowsAdded()); 4798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test restore sms with three sms json object in the array. 4838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4851d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin public void testRestoreSms_AllSms() throws Exception { 4869037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllSmsJson))); 4878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin FakeSmsProvider smsProvider = new FakeSmsProvider(mSmsRows); 4889037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("sms", smsProvider); 4899037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putSmsMessagesToProvider(jsonReader); 4908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(mSmsRows.length, smsProvider.getRowsAdded()); 4918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 4928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 4938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 4948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * Test restore mms with the empty json array "[]". 4958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * @throws Exception 4968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 4978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void testRestoreMms_NoMms() throws Exception { 4988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin JsonReader jsonReader = new JsonReader(new StringReader(EMPTY_JSON_ARRAY)); 4998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin FakeMmsProvider mmsProvider = new FakeMmsProvider(null); 5009037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("mms", mmsProvider); 5019037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToProvider(jsonReader); 5028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(0, mmsProvider.getRowsAdded()); 5038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 5048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 5058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 5069037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin * Test restore sms with three mms json object in the array. 5079037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin * @throws Exception 5089037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin */ 5099037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin public void testRestoreMms_AllMms() throws Exception { 5109037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin JsonReader jsonReader = new JsonReader(new StringReader(addRandomDataToJson(mAllMmsJson))); 5119037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin FakeMmsProvider mmsProvider = new FakeMmsProvider(mMmsAllContentValues); 5129037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mMockContentResolver.addProvider("mms", mmsProvider); 5139037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.putMmsMessagesToProvider(jsonReader); 5149037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin assertEquals(18, mmsProvider.getRowsAdded()); 5159037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin } 5169037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin 5179037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin /** 51821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin * Test with quota exceeded. Checking size of the backup before it hits quota and after. 51921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin * It still backs up more than a quota since there is meta-info which matters with small amounts 52021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin * of data. The agent does not take backup meta-info into consideration. 52121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin * @throws Exception 52221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin */ 52321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin public void testBackup_WithQuotaExceeded() throws Exception { 5249037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin mTelephonyBackupAgent.mMaxMsgPerFile = 1; 52521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin final int backupSize = 6144; 52621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin final int backupSizeAfterFirstQuotaHit = 5120; 52721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin final int backupSizeAfterSecondQuotaHit = 4096; 52821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 52921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mSmsTable.addAll(Arrays.asList(mSmsRows)); 53021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mMmsTable.addAll(Arrays.asList(mMmsRows)); 53121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 53221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin FullBackupDataOutput fullBackupDataOutput = new FullBackupDataOutput(); 53321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput); 53421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin assertEquals(backupSize, fullBackupDataOutput.getSize()); 53521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 53621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.onQuotaExceeded(backupSize, backupSize - 100); 53721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin fullBackupDataOutput = new FullBackupDataOutput(); 53821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput); 53921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin assertEquals(backupSizeAfterFirstQuotaHit, fullBackupDataOutput.getSize()); 54021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 54121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.onQuotaExceeded(backupSizeAfterFirstQuotaHit, 54221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin backupSizeAfterFirstQuotaHit - 200); 54321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin fullBackupDataOutput = new FullBackupDataOutput(); 54421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin mTelephonyBackupAgent.onFullBackup(fullBackupDataOutput); 54521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin assertEquals(backupSizeAfterSecondQuotaHit, fullBackupDataOutput.getSize()); 54621736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin } 54721736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 5489037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin // Adding random keys to JSON to test handling it by the BackupAgent on restore. 5499037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin private String addRandomDataToJson(String jsonString) throws JSONException { 5509037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin JSONArray jsonArray = new JSONArray(jsonString); 5519037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin JSONArray res = new JSONArray(); 5529037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin for (int i = 0; i < jsonArray.length(); ++i) { 5539037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin JSONObject jsonObject = jsonArray.getJSONObject(i); 5549037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin jsonObject.put(UUID.randomUUID().toString(), UUID.randomUUID().toString()); 5559037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin res = res.put(jsonObject); 5569037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin } 5579037d648d61f3d90726e43296f0b12c532e1f934Roman Sorokin return res.toString(); 5581d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 5591d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 5608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 5618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * class for checking sms insertion into the provider on restore. 5628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 5638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private class FakeSmsProvider extends MockContentProvider { 5648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private int nextRow = 0; 5658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private ContentValues[] mSms; 5668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 5678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public FakeSmsProvider(ContentValues[] sms) { 5688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin this.mSms = sms; 5698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 5708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 5718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 5728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Uri insert(Uri uri, ContentValues values) { 5738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(Telephony.Sms.CONTENT_URI, uri); 5748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues modifiedValues = new ContentValues(mSms[nextRow++]); 5758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.remove(Telephony.Sms._ID); 5768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Sms.READ, 1); 5778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Sms.SEEN, 1); 5788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (mSubId2Phone.get(modifiedValues.getAsInteger(Telephony.Sms.SUBSCRIPTION_ID)) 5798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin == null) { 5808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Sms.SUBSCRIPTION_ID, -1); 5818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 5828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 5838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(modifiedValues, values); 5848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return null; 5858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 5868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 5878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 58821736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin public int bulkInsert(Uri uri, ContentValues[] values) { 58921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin for (ContentValues cv : values) { 59021736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin insert(uri, cv); 59121736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin } 59221736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin return values.length; 59321736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin } 59421736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin 59521736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin @Override 5968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 5978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String sortOrder) { 5988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return null; 5998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getRowsAdded() { 6028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return nextRow; 6038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 6078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * class for checking mms insertion into the provider on restore. 6088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 6098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private class FakeMmsProvider extends MockContentProvider { 6108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private int nextRow = 0; 6118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private List<ContentValues> mValues; 6128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private long mDummyMsgId = -1; 6138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private long mMsgId = -1; 6148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public FakeMmsProvider(List<ContentValues> values) { 6168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin this.mValues = values; 6178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 6208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Uri insert(Uri uri, ContentValues values) { 6218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin Uri retUri = Uri.parse("dummy_uri"); 6228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues modifiedValues = new ContentValues(mValues.get(nextRow++)); 6238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (APP_SMIL.equals(values.get(Telephony.Mms.Part.CONTENT_TYPE))) { 6248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Smil part. 6258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(-1, mDummyMsgId); 6268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mDummyMsgId = values.getAsLong(Telephony.Mms.Part.MSG_ID); 6278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (values.get(Telephony.Mms.Part.SEQ) != null) { 6308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Part of mms. 6318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon() 6328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath(String.valueOf(mDummyMsgId)) 6338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath("part") 6348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .build(); 6358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(expectedUri, uri); 6368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (values.get(Telephony.Mms.Part.MSG_ID) != null) { 6398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Mms.Part.MSG_ID, mDummyMsgId); 6408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (values.get(Telephony.Mms.SUBSCRIPTION_ID) != null) { 6448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(Telephony.Mms.CONTENT_URI, uri); 6458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (mSubId2Phone.get(modifiedValues.getAsInteger(Telephony.Sms.SUBSCRIPTION_ID)) 6468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin == null) { 6478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Sms.SUBSCRIPTION_ID, -1); 6488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Mms. 6508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Mms.READ, 1); 6518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Mms.SEEN, 1); 6528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mMsgId = modifiedValues.getAsInteger(BaseColumns._ID); 6538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin retUri = Uri.withAppendedPath(Telephony.Mms.CONTENT_URI, String.valueOf(mMsgId)); 6548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.remove(BaseColumns._ID); 6558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6568b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6578b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (values.get(Telephony.Mms.Addr.ADDRESS) != null) { 6588b39acf181c547e87161873112d6c52a581fc778Roman Sorokin // Address. 6598b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon() 6608b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath(String.valueOf(mMsgId)) 6618b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath("addr") 6628b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .build(); 6638b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(expectedUri, uri); 6648b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertNotSame(-1, mMsgId); 6658b39acf181c547e87161873112d6c52a581fc778Roman Sorokin modifiedValues.put(Telephony.Mms.Addr.MSG_ID, mMsgId); 6668b39acf181c547e87161873112d6c52a581fc778Roman Sorokin mDummyMsgId = -1; 6678b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6688b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6698b39acf181c547e87161873112d6c52a581fc778Roman Sorokin for (String key : modifiedValues.keySet()) { 67076422e0ed1bc5b68f857094a05b5fec8b507f36eRoman Sorokin assertEquals("Key:"+key, modifiedValues.get(key), values.get(key)); 6718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(modifiedValues.size(), values.size()); 6738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return retUri; 6748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 6778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 6788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin final Uri expectedUri = Telephony.Mms.CONTENT_URI.buildUpon() 6798b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath(String.valueOf(mDummyMsgId)) 6808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .appendPath("part") 6818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin .build(); 6828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(expectedUri, uri); 6838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin ContentValues expected = new ContentValues(); 6848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin expected.put(Telephony.Mms.Part.MSG_ID, mMsgId); 6858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin assertEquals(expected, values); 6868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return 2; 6878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 6908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 6918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String sortOrder) { 6928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return null; 6938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 6958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getRowsAdded() { 6968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return nextRow; 6978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 6998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 7018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * class that implements MmsSms provider for thread ids. 7028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 7038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static class ThreadProvider extends MockContentProvider { 7041d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ArrayList<Set<Integer> > id2Thread = new ArrayList<>(); 7051d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ArrayList<String> id2Recipient = new ArrayList<>(); 7061d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 7071d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin public int getOrCreateThreadId(final String[] recipients) { 7081d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin Set<Integer> ids = new ArraySet<>(); 7091d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin for (String rec : recipients) { 7101d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin if (!id2Recipient.contains(rec)) { 7111d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin id2Recipient.add(rec); 7121d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7131d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ids.add(id2Recipient.indexOf(rec)+1); 7141d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7151d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin if (!id2Thread.contains(ids)) { 7161d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin id2Thread.add(ids); 7171d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7181d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return id2Thread.indexOf(ids)+1; 7191d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7211d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin private String getSpaceSepIds(int threadId) { 7221d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin String spaceSepIds = null; 7231d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin for (Integer id : id2Thread.get(threadId-1)) { 7241d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin spaceSepIds = (spaceSepIds == null ? "" : spaceSepIds + " ") + String.valueOf(id); 7251d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7261d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return spaceSepIds; 7271d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } 7288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7291d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin private String getRecipient(int recipientId) { 7301d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return id2Recipient.get(recipientId-1); 7318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 7348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 7358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String sortOrder) { 7361d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin if (uri.equals(TelephonyBackupAgent.ALL_THREADS_URI)) { 7371d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin final int threadId = Integer.parseInt(selectionArgs[0]); 7381d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin final String spaceSepIds = getSpaceSepIds(threadId); 7391d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin List<ContentValues> table = new ArrayList<>(); 7401d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ContentValues row = new ContentValues(); 7411d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin row.put(Telephony.Threads.RECIPIENT_IDS, spaceSepIds); 7421d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin table.add(row); 7431d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return new FakeCursor(table, projection); 7441d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } else if (uri.toString().startsWith( 7451d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin TelephonyBackupAgent.SINGLE_CANONICAL_ADDRESS_URI.toString())) { 7461d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin final int recipientId = (int)ContentUris.parseId(uri); 7471d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin final String recipient = getRecipient(recipientId); 7481d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin List<ContentValues> table = new ArrayList<>(); 7491d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ContentValues row = new ContentValues(); 7501d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin row.put(Telephony.CanonicalAddressesColumns.ADDRESS, recipient); 7511d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin table.add(row); 7521d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 7531d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return new FakeCursor(table, 7541d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin projection != null 7551d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ? projection 7561d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin : new String[] { Telephony.CanonicalAddressesColumns.ADDRESS }); 7571d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin } else if (uri.toString().startsWith( 7581d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin TelephonyBackupAgent.THREAD_ID_CONTENT_URI.toString())) { 7591d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin List<String> recipients = uri.getQueryParameters("recipient"); 7601d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin 7611d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin final int threadId = 7621d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin getOrCreateThreadId(recipients.toArray(new String[recipients.size()])); 7631d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin List<ContentValues> table = new ArrayList<>(); 7641d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin ContentValues row = new ContentValues(); 7651d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin row.put(BaseColumns._ID, String.valueOf(threadId)); 7661d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin table.add(row); 7671d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return new FakeCursor(table, projection); 7681d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin }; 7691d42223c7e497b5513fa0cc5e65ffc405b432989Roman Sorokin return null; 7708b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7718b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7728b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7738b39acf181c547e87161873112d6c52a581fc778Roman Sorokin /** 7748b39acf181c547e87161873112d6c52a581fc778Roman Sorokin * general cursor for serving queries. 7758b39acf181c547e87161873112d6c52a581fc778Roman Sorokin */ 7768b39acf181c547e87161873112d6c52a581fc778Roman Sorokin private static class FakeCursor extends MockCursor { 7778b39acf181c547e87161873112d6c52a581fc778Roman Sorokin String[] projection; 7788b39acf181c547e87161873112d6c52a581fc778Roman Sorokin List<ContentValues> rows; 77921736c3871d5c4cd3a6322d65d635057d0a61937Roman Sorokin int nextRow = 0; 7808b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7818b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public FakeCursor(List<ContentValues> rows, String[] projection) { 7828b39acf181c547e87161873112d6c52a581fc778Roman Sorokin this.projection = projection; 7838b39acf181c547e87161873112d6c52a581fc778Roman Sorokin this.rows = rows; 7848b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7858b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7868b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void setProjection(String[] projection) { 7878b39acf181c547e87161873112d6c52a581fc778Roman Sorokin this.projection = projection; 7888b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7898b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7908b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 7918b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getColumnCount() { 7928b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return projection.length; 7938b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7948b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 7958b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 7968b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public String getColumnName(int columnIndex) { 7978b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return projection[columnIndex]; 7988b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 7998b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8008b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8018b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public String getString(int columnIndex) { 8028b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return rows.get(nextRow).getAsString(projection[columnIndex]); 8038b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8048b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8058b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8068b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getInt(int columnIndex) { 8078b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return rows.get(nextRow).getAsInteger(projection[columnIndex]); 8088b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8098b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8108b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8118b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public long getLong(int columnIndex) { 8128b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return rows.get(nextRow).getAsLong(projection[columnIndex]); 8138b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8148b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8158b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8168b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public boolean isAfterLast() { 8178b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return nextRow >= getCount(); 8188b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8198b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8208b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8218b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public boolean isLast() { 8228b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return nextRow == getCount() - 1; 8238b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8248b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8258b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8268b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public boolean moveToFirst() { 8278b39acf181c547e87161873112d6c52a581fc778Roman Sorokin nextRow = 0; 8288b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return getCount() > 0; 8298b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8308b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8318b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8328b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public boolean moveToNext() { 8338b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return getCount() > ++nextRow; 8348b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8358b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8368b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8378b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getCount() { 8388b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return rows.size(); 8398b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8408b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8418b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8428b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public int getColumnIndex(String columnName) { 8438b39acf181c547e87161873112d6c52a581fc778Roman Sorokin for (int i=0; i<projection.length; ++i) { 8448b39acf181c547e87161873112d6c52a581fc778Roman Sorokin if (columnName.equals(projection[i])) { 8458b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return i; 8468b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8478b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8488b39acf181c547e87161873112d6c52a581fc778Roman Sorokin return -1; 8498b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8508b39acf181c547e87161873112d6c52a581fc778Roman Sorokin 8518b39acf181c547e87161873112d6c52a581fc778Roman Sorokin @Override 8528b39acf181c547e87161873112d6c52a581fc778Roman Sorokin public void close() { 8538b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8548b39acf181c547e87161873112d6c52a581fc778Roman Sorokin } 8558b39acf181c547e87161873112d6c52a581fc778Roman Sorokin} 856