Merge "Remove use of private style"
diff --git a/res/layout/contact_tile_row_regular.xml b/res/layout/contact_tile_row_regular.xml
new file mode 100644
index 0000000..79b670a
--- /dev/null
+++ b/res/layout/contact_tile_row_regular.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contactTile_row_regular"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <RelativeLayout android:id="@+id/contactTile_row_left"
+        style="@style/ContactTileRegularLayout">
+        <ImageView android:id="@+id/contactTile_left_image"
+            style="@style/ContactTileRegularImage" />
+        <TextView android:id="@+id/contactTile_left_name"
+            style="@style/ContactTileRegularText" />
+    </RelativeLayout>
+
+    <RelativeLayout android:id="@+id/contactTile_row_right"
+        style="@style/ContactTileRegularLayout">
+        <ImageView android:id="@+id/contactTile_right_image"
+            style="@style/ContactTileRegularImage" />
+        <TextView android:id="@+id/contactTile_right_name"
+            style="@style/ContactTileRegularText" />
+    </RelativeLayout>
+
+</LinearLayout>
diff --git a/res/layout/strequent_fragment.xml b/res/layout/strequent_fragment.xml
new file mode 100644
index 0000000..348fd0c
--- /dev/null
+++ b/res/layout/strequent_fragment.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/strequent_list"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:divider="@null"
+/>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ace8869..9a60815 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -48,4 +48,8 @@
 
     <!-- Color of the text indicating the type of entry (e.g. Home, Work etc) -->
     <color name="detail_header_view_text_color">#FFFFFF</color>
+
+    <!--  Color of the text foreground and background of Regular Sized ContactTile -->
+    <color name="contact_tile_regular_text">#2B1B17</color>
+    <color name="contact_tile_regular_text_background">#FFFFFF</color>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 5ade9f6..f539a6d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -271,4 +271,52 @@
         <item name="android:gravity">center_vertical</item>
         <item name="android:paddingTop">5dip</item>
     </style>
+
+    <style name="ContactTileRegularText">
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_alignParentBottom">true</item>
+        <item name="android:background">@color/contact_tile_regular_text</item>
+        <item name="android:textColor">@color/contact_tile_regular_text_background</item>
+        <item name="android:textSize">17sp</item>
+        <item name="android:alpha">0.7</item>
+        <item name="android:gravity">center_horizontal</item>
+    </style>
+
+    <style name="ContactTileRegularImage">
+        <item name="android:layout_width">160dip</item>
+        <item name="android:layout_height">160dip</item>
+        <item name="android:layout_alignParentTop">true</item>
+        <item name="android:layout_alignParentLeft">true</item>
+        <item name="android:scaleType">centerCrop</item>
+    </style>
+
+    <style name="ContactTileRegularLayout">
+        <item name="android:layout_width">155dip</item>
+        <item name="android:layout_height">160dip</item>
+        <item name="android:focusable">true</item>
+        <item name="android:padding">5dip</item>
+        <item name="android:background">@drawable/list_selector</item>
+    </style>
+
+    <style name="ContactTileSmallText">
+        <item name="android:layout_width">80dip</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:paddingTop">8dip</item>
+        <item name="android:paddingLeft">4dip</item>
+    </style>
+
+    <style name="ContactTileSmallImage">
+        <item name="android:layout_width">80dip</item>
+        <item name="android:layout_height">80dip</item>
+        <item name="android:scaleType">centerCrop</item>
+    </style>
+
+    <style name="ContactTileSmallLayout">
+        <item name="android:layout_width">160dip</item>
+        <item name="android:layout_height">80dip</item>
+        <item name="android:focusable">true</item>
+        <item name="android:padding">5dip</item>
+        <item name="android:background">@drawable/list_selector</item>
+    </style>
 </resources>
diff --git a/src/com/android/contacts/StrequentMetaDataLoader.java b/src/com/android/contacts/StrequentMetaDataLoader.java
new file mode 100644
index 0000000..203b25f
--- /dev/null
+++ b/src/com/android/contacts/StrequentMetaDataLoader.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.CursorLoader;
+import android.provider.ContactsContract.Contacts;
+
+/**
+ * Strequent meta-data loader.  Loads all starred and frequent contacts from the database.
+ */
+public final class StrequentMetaDataLoader extends CursorLoader {
+
+    public final static int CONTACT_ID = 0;
+    public final static int DISPLAY_NAME = 1;
+    public final static int STARRED = 2;
+    public final static int PHOTO_URI = 3;
+    public final static int PHOTO_ID = 4;
+
+    private static final String[] COLUMNS = new String[] {
+        Contacts._ID,
+        Contacts.DISPLAY_NAME,
+        Contacts.STARRED,
+        Contacts.PHOTO_URI,
+        Contacts.PHOTO_ID
+    };
+
+    public StrequentMetaDataLoader(Context context) {
+        super(context, Contacts.CONTENT_STREQUENT_URI, COLUMNS, null, null, null);
+    }
+}
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 52a2539..3766e47 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -225,24 +225,7 @@
         tab.setIcon(R.drawable.ic_tab_starred);
         tab.setTabListener(new TabChangeListener(mStrequentFragment));
         getActionBar().addTab(tab);
-
-        // TODO: We should not artificially create Intents and put them into the Fragment.
-        // It would be nicer to directly pass in the UI constant
-        Intent intent = new Intent(UI.LIST_STREQUENT_ACTION);
-        intent.setClass(this, PeopleActivity.class);
-
-        ContactsIntentResolver resolver = new ContactsIntentResolver(this);
-        ContactsRequest request = resolver.resolveIntent(intent);
-        final ContactListFilter filter = ContactListFilter.createFilterWithType(
-                ContactListFilter.FILTER_TYPE_STARRED);
-        mStrequentFragment.setFilter(filter, false);
-        mStrequentFragment.setSearchMode(request.isSearchMode());
-        mStrequentFragment.setQueryString(request.getQueryString(), false);
-        mStrequentFragment.setContactsRequest(request);
-        mStrequentFragment.setDirectorySearchMode(request.isDirectorySearchEnabled()
-                ? DirectoryListLoader.SEARCH_MODE_DEFAULT
-                : DirectoryListLoader.SEARCH_MODE_NONE);
-        mStrequentFragment.setOnContactListActionListener(mListFragmentListener);
+        mStrequentFragment.setListener(mStrequentListener);
     }
 
     /**
@@ -505,6 +488,14 @@
         }
     };
 
+    private StrequentContactListFragment.Listener mStrequentListener =
+            new StrequentContactListFragment.Listener() {
+        @Override
+        public void onContactSelected(Uri contactUri) {
+            getPhoneNumberCallInteraction().startInteraction(contactUri);
+        }
+    };
+
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         // For now, create the menu in here. It would be nice to do this in the Fragment,
diff --git a/src/com/android/contacts/list/StrequentAdapter.java b/src/com/android/contacts/list/StrequentAdapter.java
new file mode 100644
index 0000000..4c6109a
--- /dev/null
+++ b/src/com/android/contacts/list/StrequentAdapter.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2011 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.list;
+
+import com.android.contacts.ContactPhotoManager;
+import com.android.contacts.R;
+import com.android.contacts.StrequentMetaDataLoader;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Arranges contacts in {@link StrequentFragment} (aka favorites) according to if the contact
+ * is starred or not. Also shows two contacts per row.
+ */
+public class StrequentAdapter extends BaseAdapter implements OnClickListener {
+
+    private LayoutInflater mInflater;
+    private ArrayList<StrequentEntry> mAllEntries;
+    private ContactPhotoManager mPhotoManager;
+    private Listener mListener;
+    private int mMostFrequentCount;
+    private int mStarredCount;
+    private static final int NUMCOLS = 2;
+
+    public StrequentAdapter(Context context, Listener listener) {
+        mInflater = LayoutInflater.from(context);
+        mPhotoManager = ContactPhotoManager.createContactPhotoManager(context);
+        mListener = listener;
+    }
+
+    public void setCursor(Cursor cursor){
+        populateStrequentEntries(cursor);
+    }
+
+    private void populateStrequentEntries(Cursor cursor) {
+        mAllEntries = new ArrayList<StrequentEntry>();
+        mMostFrequentCount = mStarredCount = 0;
+
+        while (cursor.moveToNext()) {
+            StrequentEntry contact = new StrequentEntry();
+
+            contact.id = cursor.getLong(StrequentMetaDataLoader.CONTACT_ID);
+            contact.photoId = cursor.getLong(StrequentMetaDataLoader.PHOTO_ID);
+            contact.name = cursor.getString(StrequentMetaDataLoader.DISPLAY_NAME);
+
+            // Adding Starred Contact
+            if (cursor.getInt(StrequentMetaDataLoader.STARRED) == 1) {
+                mStarredCount++;
+            } else {
+                mMostFrequentCount++;
+            }
+            mAllEntries.add(contact);
+        }
+        this.notifyDataSetChanged();
+    }
+
+    @Override
+    public int getCount() {
+        return mAllEntries.size() / NUMCOLS;
+    }
+
+    @Override
+    public Object getItem(int position) {
+        return mAllEntries.get(position);
+    }
+
+    @Override
+    public long getItemId(int position) {
+        return mAllEntries.get(position).id;
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder holder;
+        // Note: For now, every row except for the last row will have 2 columns
+        int index = position * NUMCOLS;
+
+        // Try to recycle convertView
+        if (convertView != null) {
+            holder = (ViewHolder) convertView.getTag();
+        } else {
+            // Must create new View
+            convertView = mInflater.inflate(R.layout.contact_tile_row_regular, null);
+            holder = new ViewHolder(convertView);
+
+            holder.getLayoutLeft().setOnClickListener(this);
+            holder.getLayoutRight().setOnClickListener(this);
+
+            convertView.setTag(holder);
+        }
+
+        holder.getTextLeft().setText(mAllEntries.get(index).name);
+        mPhotoManager.loadPhoto(holder.getImageLeft(), mAllEntries.get(index).photoId);
+        holder.getLayoutLeft().setTag(mAllEntries.get(index));
+
+        if (++index < mAllEntries.size()) {
+            holder.getTextRight().setText(mAllEntries.get(index).name);
+            mPhotoManager.loadPhoto(holder.mImageRight, mAllEntries.get(index).photoId);
+            holder.getLayoutRight().setTag(mAllEntries.get(index));
+        } else {
+            holder.getTextRight().setText(null);
+            holder.getImageRight().setImageBitmap(null);
+            holder.getLayoutRight().setOnClickListener(null);
+        }
+
+        return convertView;
+    }
+
+    @Override
+    public int getViewTypeCount() {
+        return 1;
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        return 1;
+    }
+
+    /**
+     * Class it hold views for layout to help make wonderful listview faster
+     */
+    private static class ViewHolder {
+        private TextView mTextLeft, mTextRight;
+        private ImageView mImageLeft, mImageRight;
+        private View mLayoutLeft, mLayoutRight;
+
+        public ViewHolder(View convertView){
+            // Left Column
+            mTextLeft = (TextView) convertView.findViewById(R.id.contactTile_left_name);
+            mImageLeft = (ImageView) convertView.findViewById(R.id.contactTile_left_image);
+            mLayoutLeft = convertView.findViewById(R.id.contactTile_row_left);
+
+            // Right Column
+            mTextRight = (TextView) convertView.findViewById(R.id.contactTile_right_name);
+            mImageRight = (ImageView) convertView.findViewById(R.id.contactTile_right_image);
+            mLayoutRight = convertView.findViewById(R.id.contactTile_row_right);
+        }
+
+        public TextView getTextLeft() {
+            return mTextLeft;
+        }
+
+        public void setTextLeft(TextView textLeft) {
+            this.mTextLeft = textLeft;
+        }
+
+        public TextView getTextRight() {
+            return mTextRight;
+        }
+
+        public void setTextRight(TextView textRight) {
+            this.mTextRight = textRight;
+        }
+
+        public ImageView getImageLeft() {
+            return mImageLeft;
+        }
+
+        public void setImageLeft(ImageView imageLeft) {
+            this.mImageLeft = imageLeft;
+        }
+
+        public ImageView getImageRight() {
+            return mImageRight;
+        }
+
+        public void setImageRight(ImageView imageRight) {
+            this.mImageRight = imageRight;
+        }
+
+        public View getLayoutLeft() {
+            return mLayoutLeft;
+        }
+
+        public void setLayoutLeft(View layoutLeft) {
+            this.mLayoutLeft = layoutLeft;
+        }
+
+        public View getLayoutRight() {
+            return mLayoutRight;
+        }
+
+        public void setLayoutRight(View layoutRight) {
+            this.mLayoutRight = layoutRight;
+        }
+    }
+
+    /**
+     * Class to hold contact information
+     */
+    private static class StrequentEntry {
+        public long id;
+        public long photoId;
+        public String name;
+    }
+
+    @Override
+    public void onClick(View v) {
+        StrequentEntry entry = (StrequentEntry)v.getTag();
+        Uri data = Uri.withAppendedPath(Contacts.CONTENT_URI, String.valueOf(entry.id));
+        mListener.onContactSelected(data);
+    }
+
+    public interface Listener {
+        public void onContactSelected(Uri contactUri);
+    }
+}
diff --git a/src/com/android/contacts/list/StrequentContactListFragment.java b/src/com/android/contacts/list/StrequentContactListFragment.java
index 393e698..47cc7be 100644
--- a/src/com/android/contacts/list/StrequentContactListFragment.java
+++ b/src/com/android/contacts/list/StrequentContactListFragment.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -16,94 +16,94 @@
 package com.android.contacts.list;
 
 import com.android.contacts.R;
+import com.android.contacts.StrequentMetaDataLoader;
 
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.OnClickListener;
+import android.widget.ListView;
 
 /**
  * Fragment containing a list of starred contacts followed by a list of frequently contacted.
  */
-public class StrequentContactListFragment extends ContactBrowseListFragment
-        implements OnClickListener {
+public class StrequentContactListFragment extends Fragment {
+    public interface Listener {
+        public void onContactSelected(Uri contactUri);
+    }
 
-    private static final int CALL_BUTTON_ID = android.R.id.button1;
+    private static int LOADER_STREQUENT = 1;
 
-    private boolean mStarredContactsIncluded = true;
-    private boolean mFrequentlyContactedContactsIncluded = true;
+    private Listener mListener;
+    private StrequentAdapter mAdapter;
+    private ListView mListView;
+    private Context mContext;
 
-    public StrequentContactListFragment() {
-        setSectionHeaderDisplayEnabled(false);
-        setPhotoLoaderEnabled(true);
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        mAdapter = new StrequentAdapter(getActivity(), mAdapterListener);
+        mContext = activity;
     }
 
     @Override
-    protected boolean isNameHighlighingEnabled() {
-        // Since the list is not ordered alphabetically, we don't need to highlight the part
-        // that is used for sorting.
-        return false;
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View v = inflater.inflate(R.layout.strequent_fragment, container, false);
+        mListView = (ListView) v.findViewById(R.id.strequent_list);
+        mListView.setItemsCanFocus(true);
+        return v;
     }
 
-    public void setStarredContactsIncluded(boolean flag) {
-        mStarredContactsIncluded = flag;
-        configureAdapter();
-    }
-
-    public void setFrequentlyContactedContactsIncluded(boolean flag) {
-        mFrequentlyContactedContactsIncluded = flag;
-        configureAdapter();
+    public void setListener(Listener listener) {
+        mListener = listener;
     }
 
     @Override
-    protected void onItemClick(int position, long id) {
-        ContactListAdapter adapter = getAdapter();
-        viewContact(adapter.getContactUri(position));
+    public void onStart(){
+        super.onStart();
+        getLoaderManager().restartLoader(LOADER_STREQUENT, null, mStrequentLoaderListener);
     }
 
-    @Override
-    protected ContactListAdapter createListAdapter() {
-        StrequentContactListAdapter adapter =
-                new StrequentContactListAdapter(getActivity(), CALL_BUTTON_ID);
-        adapter.setSectionHeaderDisplayEnabled(false);
-        adapter.setDisplayPhotos(true);
-        adapter.setQuickContactEnabled(true);
-        adapter.setCallButtonListener(this);
+    /**
+     * The listener for the strequent meta data loader.
+     */
+    private final LoaderManager.LoaderCallbacks<Cursor> mStrequentLoaderListener =
+            new LoaderCallbacks<Cursor>() {
 
-        return adapter;
-    }
-
-    @Override
-    protected void configureAdapter() {
-        super.configureAdapter();
-
-        StrequentContactListAdapter adapter = (StrequentContactListAdapter)getAdapter();
-        if (adapter != null) {
-            adapter.setStarredContactsIncluded(mStarredContactsIncluded);
-            adapter.setFrequentlyContactedContactsIncluded(mFrequentlyContactedContactsIncluded);
+        @Override
+        public CursorLoader onCreateLoader(int id, Bundle args) {
+            return new StrequentMetaDataLoader(mContext);
         }
-    }
 
-    @Override
-    protected View inflateView(LayoutInflater inflater, ViewGroup container) {
-        return inflater.inflate(R.layout.contacts_list_content, null);
-    }
+        @Override
+        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+            mAdapter.setCursor(data);
+            mListView.setAdapter(mAdapter);
+        }
 
-    @Override
-    protected void prepareEmptyView() {
-        setEmptyText(R.string.noFavoritesHelpText);
-    }
+        @Override
+        public void onLoaderReset(Loader<Cursor> loader) {
+            mAdapter.setCursor(null);
+        }
+    };
 
-    @Override
-    public void onClick(View v) {
-        int id = v.getId();
-        switch (id) {
-            case CALL_BUTTON_ID: {
-                final int position = (Integer)v.getTag();
-                ContactListAdapter adapter = getAdapter();
-                callContact(adapter.getContactUri(position));
-                break;
+    private StrequentAdapter.Listener mAdapterListener =
+            new StrequentAdapter.Listener() {
+        @Override
+        public void onContactSelected(Uri contactUri) {
+            if (mListener != null) {
+                mListener.onContactSelected(contactUri);
             }
         }
-    }
+    };
 }