| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.dialer.calllog; |
| |
| import android.app.FragmentManager; |
| import android.app.FragmentTransaction; |
| import android.content.ComponentName; |
| import android.content.ContentUris; |
| import android.content.Intent; |
| import android.content.res.Resources; |
| import android.database.MatrixCursor; |
| import android.graphics.Bitmap; |
| import android.graphics.drawable.BitmapDrawable; |
| import android.net.Uri; |
| import android.provider.CallLog.Calls; |
| import android.provider.ContactsContract.CommonDataKinds.Phone; |
| import android.provider.VoicemailContract; |
| import android.telephony.PhoneNumberUtils; |
| import android.telephony.TelephonyManager; |
| import android.test.ActivityInstrumentationTestCase2; |
| import android.test.suitebuilder.annotation.LargeTest; |
| import android.test.suitebuilder.annotation.MediumTest; |
| import android.view.View; |
| import android.widget.FrameLayout; |
| |
| import com.android.contacts.common.test.FragmentTestActivity; |
| import com.android.dialer.CallDetailActivity; |
| import com.android.dialer.R; |
| import com.android.internal.telephony.CallerInfo; |
| |
| import java.util.Date; |
| import java.util.Formatter; |
| import java.util.HashMap; |
| import java.util.Random; |
| |
| /** |
| * Tests for the contact call list activity. |
| * |
| * Running all tests: |
| * |
| * runtest contacts |
| * or |
| * adb shell am instrument \ |
| * -w com.android.contacts.tests/android.test.InstrumentationTestRunner |
| */ |
| @LargeTest |
| public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> { |
| private static final int RAND_DURATION = -1; |
| private static final long NOW = -1L; |
| |
| /** A test value for the URI of a contact. */ |
| private static final Uri TEST_LOOKUP_URI = Uri.parse("content://contacts/2"); |
| /** A test value for the country ISO of the phone number in the call log. */ |
| private static final String TEST_COUNTRY_ISO = "US"; |
| /** A phone number to be used in tests. */ |
| private static final String TEST_NUMBER = "12125551000"; |
| /** The formatted version of {@link #TEST_NUMBER}. */ |
| private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000"; |
| |
| /** The activity in which we are hosting the fragment. */ |
| private FragmentTestActivity mActivity; |
| private CallLogFragment mFragment; |
| private FrameLayout mParentView; |
| /** |
| * The adapter used by the fragment to build the rows in the call log. We use it with our own in |
| * memory database. |
| */ |
| private CallLogAdapter mAdapter; |
| private String mVoicemail; |
| |
| // In memory array to hold the rows corresponding to the 'calls' table. |
| private MatrixCursor mCursor; |
| private int mIndex; // Of the next row. |
| |
| private Random mRnd; |
| |
| // References to the icons bitmaps used to build the list are stored in a |
| // map mIcons. The keys to retrieve the icons are: |
| // Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE and Calls.MISSED_TYPE. |
| private HashMap<Integer, Bitmap> mCallTypeIcons; |
| |
| // An item in the call list. All the methods performing checks use it. |
| private CallLogListItemViews mItem; |
| // The list of views representing the data in the DB. View are in |
| // reverse order compare to the DB. |
| private View[] mList; |
| |
| public CallLogFragmentTest() { |
| super("com.android.dialer", FragmentTestActivity.class); |
| mIndex = 1; |
| mRnd = new Random(); |
| } |
| |
| @Override |
| public void setUp() { |
| mActivity = getActivity(); |
| // Needed by the CallLogFragment. |
| mActivity.setTheme(R.style.DialtactsTheme); |
| |
| // Create the fragment and load it into the activity. |
| mFragment = new CallLogFragment(); |
| FragmentManager fragmentManager = mActivity.getFragmentManager(); |
| FragmentTransaction transaction = fragmentManager.beginTransaction(); |
| transaction.add(FragmentTestActivity.LAYOUT_ID, mFragment); |
| transaction.commit(); |
| // Wait for the fragment to be loaded. |
| getInstrumentation().waitForIdleSync(); |
| |
| mVoicemail = TelephonyManager.getDefault().getVoiceMailNumber(); |
| mAdapter = mFragment.getAdapter(); |
| // Do not process requests for details during tests. This would start a background thread, |
| // which makes the tests flaky. |
| mAdapter.disableRequestProcessingForTest(); |
| mAdapter.stopRequestProcessing(); |
| mParentView = new FrameLayout(mActivity); |
| mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION); |
| buildIconMap(); |
| } |
| |
| /** |
| * Checks that the call icon is not visible for private and |
| * unknown numbers. |
| * Use 2 passes, one where new views are created and one where |
| * half of the total views are updated and the other half created. |
| */ |
| @MediumTest |
| public void testCallViewIsNotVisibleForPrivateAndUnknownNumbers() { |
| final int SIZE = 100; |
| mList = new View[SIZE]; |
| |
| // Insert the first batch of entries. |
| mCursor.moveToFirst(); |
| insertRandomEntries(SIZE / 2); |
| int startOfSecondBatch = mCursor.getPosition(); |
| |
| buildViewListFromDb(); |
| checkCallStatus(); |
| |
| // Append the rest of the entries. We keep the first set of |
| // views around so they get updated and not built from |
| // scratch, this exposes some bugs that are not there when the |
| // call log is launched for the 1st time but show up when the |
| // call log gets updated afterwards. |
| mCursor.move(startOfSecondBatch); |
| insertRandomEntries(SIZE / 2); |
| |
| buildViewListFromDb(); |
| checkCallStatus(); |
| } |
| |
| @MediumTest |
| public void testCallAndGroupViews_GroupView() { |
| mCursor.moveToFirst(); |
| insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newGroupView(getActivity(), mParentView); |
| mAdapter.bindGroupView(view, getActivity(), mCursor, 3, false); |
| assertNotNull(view.findViewById(R.id.secondary_action_icon)); |
| } |
| |
| @MediumTest |
| public void testCallAndGroupViews_StandAloneView() { |
| mCursor.moveToFirst(); |
| insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| assertNotNull(view.findViewById(R.id.secondary_action_icon)); |
| } |
| |
| @MediumTest |
| public void testCallAndGroupViews_ChildView() { |
| mCursor.moveToFirst(); |
| insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newChildView(getActivity(), mParentView); |
| mAdapter.bindChildView(view, getActivity(), mCursor); |
| assertNotNull(view.findViewById(R.id.secondary_action_icon)); |
| } |
| |
| @MediumTest |
| public void testBindView_NumberOnlyNoCache() { |
| mCursor.moveToFirst(); |
| insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, TEST_NUMBER); |
| } |
| |
| @MediumTest |
| public void testBindView_NumberOnlyDbCachedFormattedNumber() { |
| mCursor.moveToFirst(); |
| Object[] values = getValuesToInsert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| values[CallLogQuery.CACHED_FORMATTED_NUMBER] = TEST_FORMATTED_NUMBER; |
| insertValues(values); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, TEST_FORMATTED_NUMBER); |
| } |
| |
| @MediumTest |
| public void testBindView_WithCachedName() { |
| mCursor.moveToFirst(); |
| insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_HOME, ""); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, "John Doe"); |
| assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME)); |
| } |
| |
| @MediumTest |
| public void testBindView_UriNumber() { |
| mCursor.moveToFirst(); |
| insertWithCachedValues("sip:johndoe@gmail.com", NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_HOME, ""); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, "John Doe"); |
| assertNumberAndLabelAre(views, "sip:johndoe@gmail.com", null); |
| } |
| |
| @MediumTest |
| public void testBindView_HomeLabel() { |
| mCursor.moveToFirst(); |
| insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_HOME, ""); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, "John Doe"); |
| assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME)); |
| } |
| |
| @MediumTest |
| public void testBindView_WorkLabel() { |
| mCursor.moveToFirst(); |
| insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_WORK, ""); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, "John Doe"); |
| assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_WORK)); |
| } |
| |
| @MediumTest |
| public void testBindView_CustomLabel() { |
| mCursor.moveToFirst(); |
| String numberLabel = "My label"; |
| insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_CUSTOM, numberLabel); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertNameIs(views, "John Doe"); |
| assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, numberLabel); |
| } |
| |
| @MediumTest |
| public void testBindView_WithQuickContactBadge() { |
| mCursor.moveToFirst(); |
| insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE, |
| "John Doe", Phone.TYPE_HOME, ""); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertTrue(views.quickContactView.isEnabled()); |
| } |
| |
| @MediumTest |
| public void testBindView_WithoutQuickContactBadge() { |
| mCursor.moveToFirst(); |
| insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| assertFalse(views.quickContactView.isEnabled()); |
| } |
| |
| @MediumTest |
| public void testBindView_CallButton() { |
| mCursor.moveToFirst(); |
| insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag(); |
| Intent intent = intentProvider.getIntent(mActivity); |
| // Starts a call. |
| assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction()); |
| // To the entry's number. |
| assertEquals(Uri.parse("tel:" + TEST_NUMBER), intent.getData()); |
| } |
| |
| @MediumTest |
| public void testBindView_PlayButton() { |
| mCursor.moveToFirst(); |
| insertVoicemail(TEST_NUMBER, NOW, 0); |
| View view = mAdapter.newStandAloneView(getActivity(), mParentView); |
| mAdapter.bindStandAloneView(view, getActivity(), mCursor); |
| |
| CallLogListItemViews views = (CallLogListItemViews) view.getTag(); |
| IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag(); |
| Intent intent = intentProvider.getIntent(mActivity); |
| // Starts the call detail activity. |
| assertEquals(new ComponentName(mActivity, CallDetailActivity.class), |
| intent.getComponent()); |
| // With the given entry. |
| assertEquals(ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, 1), |
| intent.getData()); |
| // With the URI of the voicemail. |
| assertEquals( |
| ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, 1), |
| intent.getParcelableExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI)); |
| // And starts playback. |
| assertTrue( |
| intent.getBooleanExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, false)); |
| } |
| |
| /** Returns the label associated with a given phone type. */ |
| private CharSequence getTypeLabel(int phoneType) { |
| return Phone.getTypeLabel(getActivity().getResources(), phoneType, ""); |
| } |
| |
| // |
| // HELPERS to check conditions on the DB/views |
| // |
| /** |
| * Go over all the views in the list and check that the Call |
| * icon's visibility matches the nature of the number. |
| */ |
| private void checkCallStatus() { |
| for (int i = 0; i < mList.length; i++) { |
| if (null == mList[i]) { |
| break; |
| } |
| mItem = (CallLogListItemViews) mList[i].getTag(); |
| String number = getPhoneNumberForListEntry(i); |
| if (CallerInfo.PRIVATE_NUMBER.equals(number) || |
| CallerInfo.UNKNOWN_NUMBER.equals(number)) { |
| assertFalse(View.VISIBLE == mItem.secondaryActionView.getVisibility()); |
| } else { |
| assertEquals(View.VISIBLE, mItem.secondaryActionView.getVisibility()); |
| } |
| } |
| } |
| |
| |
| // |
| // HELPERS to setup the tests. |
| // |
| |
| /** |
| * Get the Bitmap from the icons in the contacts package. |
| */ |
| private Bitmap getBitmap(String resName) { |
| Resources r = mActivity.getResources(); |
| int resid = r.getIdentifier(resName, "drawable", "com.android.dialer"); |
| BitmapDrawable d = (BitmapDrawable) r.getDrawable(resid); |
| assertNotNull(d); |
| return d.getBitmap(); |
| } |
| |
| /** |
| * Fetch all the icons we need in tests from the contacts app and store them in a map. |
| */ |
| private void buildIconMap() { |
| mCallTypeIcons = new HashMap<Integer, Bitmap>(3); |
| |
| mCallTypeIcons.put(Calls.INCOMING_TYPE, getBitmap("ic_call_incoming_holo_dark")); |
| mCallTypeIcons.put(Calls.MISSED_TYPE, getBitmap("ic_call_missed_holo_dark")); |
| mCallTypeIcons.put(Calls.OUTGOING_TYPE, getBitmap("ic_call_outgoing_holo_dark")); |
| } |
| |
| // |
| // HELPERS to build/update the call entries (views) from the DB. |
| // |
| |
| /** |
| * Read the DB and foreach call either update the existing view if |
| * one exists already otherwise create one. |
| * The list is build from a DESC view of the DB (last inserted entry is first). |
| */ |
| private void buildViewListFromDb() { |
| int i = 0; |
| mCursor.moveToLast(); |
| while(!mCursor.isBeforeFirst()) { |
| if (null == mList[i]) { |
| mList[i] = mAdapter.newStandAloneView(mActivity, mParentView); |
| } |
| mAdapter.bindStandAloneView(mList[i], mActivity, mCursor); |
| mCursor.moveToPrevious(); |
| i++; |
| } |
| } |
| |
| /** Returns the number associated with the given entry in {{@link #mList}. */ |
| private String getPhoneNumberForListEntry(int index) { |
| // The entries are added backward, so count from the end of the cursor. |
| mCursor.moveToPosition(mCursor.getCount() - index - 1); |
| return mCursor.getString(CallLogQuery.NUMBER); |
| } |
| |
| // |
| // HELPERS to insert numbers in the call log DB. |
| // |
| |
| /** |
| * Insert a certain number of random numbers in the DB. Makes sure |
| * there is at least one private and one unknown number in the DB. |
| * @param num Of entries to be inserted. |
| */ |
| private void insertRandomEntries(int num) { |
| if (num < 10) { |
| throw new IllegalArgumentException("num should be >= 10"); |
| } |
| boolean privateOrUnknownOrVm[]; |
| privateOrUnknownOrVm = insertRandomRange(0, num - 2); |
| |
| if (privateOrUnknownOrVm[0] && privateOrUnknownOrVm[1]) { |
| insertRandomRange(num - 2, num); |
| } else { |
| insertPrivate(NOW, RAND_DURATION); |
| insertUnknown(NOW, RAND_DURATION); |
| } |
| } |
| |
| /** |
| * Insert a new call entry in the test DB. |
| * |
| * It includes the values for the cached contact associated with the number. |
| * |
| * @param number The phone number. For unknown and private numbers, |
| * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE. |
| * @param cachedName the name of the contact with this number |
| * @param cachedNumberType the type of the number, from the contact with this number |
| * @param cachedNumberLabel the label of the number, from the contact with this number |
| */ |
| private void insertWithCachedValues(String number, long date, int duration, int type, |
| String cachedName, int cachedNumberType, String cachedNumberLabel) { |
| insert(number, date, duration, type); |
| ContactInfo contactInfo = new ContactInfo(); |
| contactInfo.lookupUri = TEST_LOOKUP_URI; |
| contactInfo.name = cachedName; |
| contactInfo.type = cachedNumberType; |
| contactInfo.label = cachedNumberLabel; |
| String formattedNumber = PhoneNumberUtils.formatNumber(number, TEST_COUNTRY_ISO); |
| if (formattedNumber == null) { |
| formattedNumber = number; |
| } |
| contactInfo.formattedNumber = formattedNumber; |
| contactInfo.normalizedNumber = number; |
| contactInfo.photoId = 0; |
| mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo); |
| } |
| |
| /** |
| * Insert a new call entry in the test DB. |
| * @param number The phone number. For unknown and private numbers, |
| * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE. |
| */ |
| private void insert(String number, long date, int duration, int type) { |
| insertValues(getValuesToInsert(number, date, duration, type)); |
| } |
| |
| /** Inserts the given values in the cursor. */ |
| private void insertValues(Object[] values) { |
| mCursor.addRow(values); |
| ++mIndex; |
| } |
| |
| /** |
| * Returns the values for a new call entry. |
| * |
| * @param number The phone number. For unknown and private numbers, |
| * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE. |
| */ |
| private Object[] getValuesToInsert(String number, long date, int duration, int type) { |
| Object[] values = CallLogQueryTestUtils.createTestExtendedValues(); |
| values[CallLogQuery.ID] = mIndex; |
| values[CallLogQuery.NUMBER] = number; |
| values[CallLogQuery.DATE] = date == NOW ? new Date().getTime() : date; |
| values[CallLogQuery.DURATION] = duration < 0 ? mRnd.nextInt(10 * 60) : duration; |
| if (mVoicemail != null && mVoicemail.equals(number)) { |
| assertEquals(Calls.OUTGOING_TYPE, type); |
| } |
| values[CallLogQuery.CALL_TYPE] = type; |
| values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO; |
| values[CallLogQuery.SECTION] = CallLogQuery.SECTION_OLD_ITEM; |
| return values; |
| } |
| |
| /** |
| * Insert a new voicemail entry in the test DB. |
| * @param number The phone number. For unknown and private numbers, |
| * use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| */ |
| private void insertVoicemail(String number, long date, int duration) { |
| Object[] values = getValuesToInsert(number, date, duration, Calls.VOICEMAIL_TYPE); |
| // Must have the same index as the row. |
| values[CallLogQuery.VOICEMAIL_URI] = |
| ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, mIndex); |
| insertValues(values); |
| } |
| |
| /** |
| * Insert a new private call entry in the test DB. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| */ |
| private void insertPrivate(long date, int duration) { |
| insert(CallerInfo.PRIVATE_NUMBER, date, duration, Calls.INCOMING_TYPE); |
| } |
| |
| /** |
| * Insert a new unknown call entry in the test DB. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| */ |
| private void insertUnknown(long date, int duration) { |
| insert(CallerInfo.UNKNOWN_NUMBER, date, duration, Calls.INCOMING_TYPE); |
| } |
| |
| /** |
| * Insert a new call to voicemail entry in the test DB. |
| * @param date In millisec since epoch. Use NOW to use the current time. |
| * @param duration In seconds of the call. Use RAND_DURATION to pick a random one. |
| */ |
| private void insertCalltoVoicemail(long date, int duration) { |
| // mVoicemail may be null |
| if (mVoicemail != null) { |
| insert(mVoicemail, date, duration, Calls.OUTGOING_TYPE); |
| } |
| } |
| |
| /** |
| * Insert a range [start, end) of random numbers in the DB. For |
| * each row, there is a 1/10 probability that the number will be |
| * marked as PRIVATE or UNKNOWN or VOICEMAIL. For regular numbers, a number is |
| * inserted, its last 4 digits will be the number of the iteration |
| * in the range. |
| * @param start Of the range. |
| * @param end Of the range (excluded). |
| * @return An array with 2 booleans [0 = private number, 1 = |
| * unknown number, 2 = voicemail] to indicate if at least one |
| * private or unknown or voicemail number has been inserted. Since |
| * the numbers are random some tests may want to enforce the |
| * insertion of such numbers. |
| */ |
| // TODO: Should insert numbers with contact entries too. |
| private boolean[] insertRandomRange(int start, int end) { |
| boolean[] privateOrUnknownOrVm = new boolean[] {false, false, false}; |
| |
| for (int i = start; i < end; i++ ) { |
| int type = mRnd.nextInt(10); |
| |
| if (0 == type) { |
| insertPrivate(NOW, RAND_DURATION); |
| privateOrUnknownOrVm[0] = true; |
| } else if (1 == type) { |
| insertUnknown(NOW, RAND_DURATION); |
| privateOrUnknownOrVm[1] = true; |
| } else if (2 == type) { |
| insertCalltoVoicemail(NOW, RAND_DURATION); |
| privateOrUnknownOrVm[2] = true; |
| } else { |
| int inout = mRnd.nextBoolean() ? Calls.OUTGOING_TYPE : Calls.INCOMING_TYPE; |
| String number = new Formatter().format("1800123%04d", i).toString(); |
| insert(number, NOW, RAND_DURATION, inout); |
| } |
| } |
| return privateOrUnknownOrVm; |
| } |
| |
| /** Asserts that the name text view is shown and contains the given text. */ |
| private void assertNameIs(CallLogListItemViews views, String name) { |
| assertEquals(View.VISIBLE, views.phoneCallDetailsViews.nameView.getVisibility()); |
| assertEquals(name, views.phoneCallDetailsViews.nameView.getText()); |
| } |
| |
| /** Asserts that the number and label text view contains the given text. */ |
| private void assertNumberAndLabelAre(CallLogListItemViews views, CharSequence number, |
| CharSequence label) { |
| assertEquals(View.VISIBLE, views.phoneCallDetailsViews.numberView.getVisibility()); |
| assertEquals(number, views.phoneCallDetailsViews.numberView.getText().toString()); |
| |
| assertEquals(label == null ? View.GONE : View.VISIBLE, |
| views.phoneCallDetailsViews.labelView.getVisibility()); |
| if (label != null) { |
| assertEquals(label, views.phoneCallDetailsViews.labelView.getText().toString()); |
| } |
| } |
| } |