diff --git a/src/com/android/contacts/RecentCallsListActivity.java b/src/com/android/contacts/RecentCallsListActivity.java
index decce7b..d892def 100644
--- a/src/com/android/contacts/RecentCallsListActivity.java
+++ b/src/com/android/contacts/RecentCallsListActivity.java
@@ -453,7 +453,11 @@
                 // Format the cached call_log phone number
                 formattedNumber = formatPhoneNumber(number);
             }
-            // Set the text lines
+            // Set the text lines and call icon.
+            // Assumes the call back feature is on most of the
+            // time. For private and unknown numbers: hide it.
+            views.callView.setVisibility(View.VISIBLE);
+
             if (!TextUtils.isEmpty(name)) {
                 views.line1View.setText(name);
                 views.labelView.setVisibility(View.VISIBLE);
@@ -470,8 +474,10 @@
             } else {
                 if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
                     number = getString(R.string.unknown);
+                    views.callView.setVisibility(View.INVISIBLE);
                 } else if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
                     number = getString(R.string.private_num);
+                    views.callView.setVisibility(View.INVISIBLE);
                 } else if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
                     number = getString(R.string.payphone);
                 } else if (number.equals(mVoiceMailNumber)) {
diff --git a/tests/src/com/android/contacts/RecentCallsListActivityTests.java b/tests/src/com/android/contacts/RecentCallsListActivityTests.java
new file mode 100644
index 0000000..86bd338
--- /dev/null
+++ b/tests/src/com/android/contacts/RecentCallsListActivityTests.java
@@ -0,0 +1,349 @@
+/*
+ * 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.contacts;
+
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.CallLog.Calls;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.View;
+import android.widget.FrameLayout;
+import com.android.contacts.RecentCallsListActivity;
+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
+ */
+
+public class RecentCallsListActivityTests extends ActivityInstrumentationTestCase2<RecentCallsListActivity> {
+    static private final String TAG = "RecentCallsListActivityTests";
+    static private final String[] CALL_LOG_PROJECTION = new String[] {
+            Calls._ID,
+            Calls.NUMBER,
+            Calls.DATE,
+            Calls.DURATION,
+            Calls.TYPE,
+            Calls.CACHED_NAME,
+            Calls.CACHED_NUMBER_TYPE,
+            Calls.CACHED_NUMBER_LABEL
+    };
+    static private final int RAND_DURATION = -1;
+    static private final long NOW = -1L;
+
+    // We get the call list activity and assign is a frame to build
+    // its list.  mAdapter is an inner class of
+    // RecentCallsListActivity to build the rows (view) in the call
+    // list. We reuse it with our own in-mem DB.
+    private RecentCallsListActivity mActivity;
+    private FrameLayout mParentView;
+    private RecentCallsListActivity.RecentCallsAdapter 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 RecentCallsListActivity.RecentCallsListItemViews mItem;
+    // The list of views representing the data in the DB. View are in
+    // reverse order compare to the DB.
+    private View[] mList;
+
+    public RecentCallsListActivityTests() {
+        super("com.android.contacts", RecentCallsListActivity.class);
+        mIndex = 1;
+        mRnd = new Random();
+    }
+
+    @Override
+    public void setUp() {
+        mActivity = (RecentCallsListActivity) getActivity();
+        mVoicemail = mActivity.mVoiceMailNumber;
+        mAdapter = mActivity.mAdapter;
+        mParentView = new FrameLayout(mActivity);
+        mCursor = new MatrixCursor(CALL_LOG_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.
+     */
+    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();
+    }
+
+    //
+    // HELPERS to check conditions on the DB/views
+    //
+    /**
+     * Check the date of the current list item.
+     * @param date That should be present in the call log list
+     *             item. Only NOW is supported.
+     */
+    private void checkDate(long date) {
+        if (NOW == date) {
+            assertEquals("0 mins ago", mItem.dateView.getText());
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Checks the right icon is used to represent the call type
+     * (missed, incoming, outgoing.) in the current item.
+     */
+    private void checkCallType(int type) {
+        Bitmap icon = ((BitmapDrawable) mItem.iconView.getDrawable()).getBitmap();
+        assertEquals(mCallTypeIcons.get(type), icon);
+    }
+
+    /**
+     * 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 = (RecentCallsListActivity.RecentCallsListItemViews) mList[i].getTag();
+
+            // callView tag is the phone number.
+            String number = (String) mItem.callView.getTag();
+
+            if (CallerInfo.PRIVATE_NUMBER.equals(number) ||
+                CallerInfo.UNKNOWN_NUMBER.equals(number)) {
+                assertFalse(View.VISIBLE == mItem.callView.getVisibility());
+            } else {
+                assertEquals(View.VISIBLE, mItem.callView.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.contacts");
+        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_log_list_incoming_call"));
+        mCallTypeIcons.put(Calls.MISSED_TYPE, getBitmap("ic_call_log_list_missed_call"));
+        mCallTypeIcons.put(Calls.OUTGOING_TYPE, getBitmap("ic_call_log_list_outgoing_call"));
+    }
+
+    //
+    // 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.newView(mActivity, mCursor, mParentView);
+            }
+            mAdapter.bindView(mList[i], mActivity, mCursor);
+            mCursor.moveToPrevious();
+            i++;
+        }
+    }
+
+    //
+    // 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.
+     * @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 Eigher Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
+     */
+    private void insert(String number, long date, int duration, int type) {
+        MatrixCursor.RowBuilder row = mCursor.newRow();
+        row.add(mIndex);
+        mIndex ++;
+        row.add(number);
+        if (NOW == date) {
+            row.add(new Date().getTime());
+        }
+        if (duration < 0) {
+            duration = mRnd.nextInt(10 * 60);  // 0 - 10 minutes random.
+        }
+        row.add(duration);  // duration
+        if (mVoicemail.equals(number)) {
+            assertEquals(Calls.OUTGOING_TYPE, type);
+        }
+        row.add(type);  // type
+        row.add("");    // cached name
+        row.add(0);     // cached number type
+        row.add("");    // cached number label
+    }
+
+    /**
+     * 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 voicemail 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 insertVoicemail(long date, int duration) {
+        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) {
+                insertVoicemail(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;
+    }
+}
