Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ac89196 authored by Steve Kondik's avatar Steve Kondik
Browse files

Merge branch 'master' of git://github.com/Wysie/Contacts_Eclair_Mod into eclair

parents 0106be54 281c8b69
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.contacts"
    android:sharedUserId="android.uid.shared"
>
    android:sharedUserId="android.uid.shared">

    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
+25 −4
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:paddingLeft="7dip"
    android:paddingLeft="4dip"
>

    <com.android.contacts.ui.widget.DontPressWithParentImageView android:id="@+id/call_icon"
@@ -38,7 +38,7 @@
        android:layout_marginTop="5dip"
        android:layout_marginBottom="5dip"
        android:layout_toLeftOf="@id/call_icon"
        android:layout_marginLeft="11dip"
        android:layout_marginLeft="2dip"
        android:background="@drawable/divider_vertical_dark"
    />

@@ -47,6 +47,9 @@
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@id/divider"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginRight="9dip"
        android:layout_marginLeft="3dip"
    />

    <TextView android:id="@+id/date"
@@ -55,6 +58,8 @@
        android:layout_toLeftOf="@id/divider"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="8dip"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginRight="5dip"

        android:textAppearance="?android:attr/textAppearanceSmall"
        android:singleLine="true"
@@ -63,10 +68,12 @@
    <TextView android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toRightOf="@id/photo"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="8dip"
        android:layout_marginTop="-10dip"
        android:layout_marginLeft="8dip"
        android:layout_alignWithParentIfMissing="true"

        android:singleLine="true"
        android:ellipsize="marquee"
@@ -88,13 +95,27 @@
        android:textAppearance="?android:attr/textAppearanceSmall"
    />
    
    <android.widget.QuickContactBadge android:id="@+id/photo"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        style="@*android:style/Widget.QuickContactBadge.WindowLarge" />
    />
    
    <ImageView android:id="@+id/noQuickContactPhoto"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"            
        style="@*android:style/Widget.QuickContactBadge.WindowMedium"
        android:background="@null" />
    />

    <TextView android:id="@+id/line1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@id/photo"
        android:layout_toLeftOf="@+id/call_type_icon"
        android:layout_above="@id/label"
        android:layout_marginLeft="8dip"
        android:layout_alignWithParentIfMissing="true"

        android:textAppearance="?android:attr/textAppearanceLarge"
+1 −1
Original line number Diff line number Diff line
@@ -1303,7 +1303,7 @@
    <string name="title_about_name">Mod Name</string>
    <string name="summary_about_name">WyContacts Eclair</string>
    <string name="title_about_version">Version</string>
    <string name="summary_about_version">0.9</string>
    <string name="summary_about_version">1.0</string>
    <string name="title_about_credits">Credits</string>
    <string name="summary_about_credits">ChainsDD, geesun, niuchl, rac2030 and the rest of XDA! :)</string>
    
+4 −6
Original line number Diff line number Diff line
@@ -56,21 +56,21 @@
                    android:dialogTitle="@string/title_choose_color"
                    android:entries="@array/digits_colors"
                    android:entryValues="@array/digits_colors_values"
                    android:defaultValue="-1" />
                    android:defaultValue="-16777216" />
                <ListPreference
                    android:key="focused_digit_color"
                    android:title="@string/title_digits_color_focused"
                    android:dialogTitle="@string/title_choose_color"
                    android:entries="@array/digits_colors"
                    android:entryValues="@array/digits_colors_values"
                    android:defaultValue="-16777216" />
                    android:defaultValue="-1" />
                <ListPreference
                    android:key="unselected_digit_color"
                    android:title="@string/title_digits_color_unselected"
                    android:dialogTitle="@string/title_choose_color"
                    android:entries="@array/digits_colors"
                    android:entryValues="@array/digits_colors_values"
                    android:defaultValue="-16777216" />
                    android:defaultValue="-1" />
                <CheckBoxPreference
                    android:key="dial_digit_use_custom_color"
                    android:title="@string/title_use_custom_color"
@@ -92,17 +92,15 @@
        </PreferenceScreen>
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/recentCallsIconLabel">
        <!--
        <CheckBoxPreference
            android:key="cl_show_dial_button"
            android:title="@string/title_contacts_show_dial_button"
            android:summary="@string/summary_contacts_show_dial_button"
            android:defaultValue="true" />
            android:defaultValue="false" />
        <CheckBoxPreference
            android:key="cl_show_pic"
            android:title="@string/title_contacts_show_pic"
            android:defaultValue="true" />
        -->
        <CheckBoxPreference
            android:key="cl_exact_time"
            android:title="@string/title_cl_exact_time"
+366 −23
Original line number Diff line number Diff line
@@ -79,6 +79,19 @@ import android.database.sqlite.SQLiteException;
import android.preference.PreferenceManager;
import android.text.format.DateFormat;

//Wysie: Contact pictures
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.provider.ContactsContract.QuickContact;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.QuickContactBadge;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.lang.ref.SoftReference;
import java.util.HashSet;


/**
 * Displays a list of call log entries.
 */
@@ -113,7 +126,10 @@ public class RecentCallsListActivity extends ListActivity
            PhoneLookup.DISPLAY_NAME,
            PhoneLookup.TYPE,
            PhoneLookup.LABEL,
            PhoneLookup.NUMBER
            PhoneLookup.NUMBER,
            //Wysie: Contact pictures
            PhoneLookup.PHOTO_ID,
            PhoneLookup.LOOKUP_KEY
    };

    static final int PERSON_ID_COLUMN_INDEX = 0;
@@ -121,6 +137,9 @@ public class RecentCallsListActivity extends ListActivity
    static final int PHONE_TYPE_COLUMN_INDEX = 2;
    static final int LABEL_COLUMN_INDEX = 3;
    static final int MATCHED_NUMBER_COLUMN_INDEX = 4;    
    //Wysie: Contact pictures
    static final int PHOTO_ID_COLUMN_INDEX = 5;
    static final int LOOKUP_KEY_COLUMN_INDEX = 6;

    private static final int MENU_ITEM_DELETE = 1;
    private static final int MENU_ITEM_DELETE_ALL = 2;
@@ -149,6 +168,13 @@ public class RecentCallsListActivity extends ListActivity
    
    private static final int MENU_PREFERENCES = 7;
    
    //Wysie: Contact pictures
    private static ExecutorService sImageFetchThreadPool;
    private int mScrollState;
    private static boolean mDisplayPhotos;
    private static boolean isQuickContact;
    private static boolean showDialButton;

    static final class ContactInfo {
        public long personId;
        public String name;
@@ -156,17 +182,26 @@ public class RecentCallsListActivity extends ListActivity
        public String label;
        public String number;
        public String formattedNumber;        
        //Wysie: Contact pictures
        public long photoId;
        public String lookupKey;

        public static ContactInfo EMPTY = new ContactInfo();
    }

    public static final class RecentCallsListItemViews {
        //Wysie: Contact pictures
        QuickContactBadge photoView;
        ImageView nonQuickContactPhotoView;
        
        TextView line1View;
        TextView labelView;
        TextView numberView;
        TextView dateView;
        ImageView iconView;
        View callView;
        
        View dividerView;
    }

    static final class CallerInfoQuery {
@@ -194,9 +229,24 @@ public class RecentCallsListActivity extends ListActivity
     */
    private static int sFormattingType = FORMATTING_TYPE_INVALID;
    
    
    //Wysie: Contact pictures
    final static class PhotoInfo {
        public int position;
        public long photoId;
        public Uri contactUri;

        public PhotoInfo(int position, long photoId, Uri contactUri) {
            this.position = position;
            this.photoId = photoId;
            this.contactUri = contactUri;
        }
        public QuickContactBadge photoView;
    }

    /** Adapter class to fill in data for the Call Log */
    final class RecentCallsAdapter extends ResourceCursorAdapter
            implements Runnable, ViewTreeObserver.OnPreDrawListener, View.OnClickListener {
            implements Runnable, ViewTreeObserver.OnPreDrawListener, View.OnClickListener, OnScrollListener {
        HashMap<String,ContactInfo> mContactInfo;
        private final LinkedList<CallerInfoQuery> mRequests;
        private volatile boolean mDone;
@@ -213,13 +263,30 @@ public class RecentCallsListActivity extends ListActivity
        private Drawable mDrawableOutgoing;
        private Drawable mDrawableMissed;
        
        //Wysie
        private ImageFetchHandler mImageHandler;
        private ImageDbFetcher mImageFetcher;
        private static final int FETCH_IMAGE_MSG = 3;
        
        //Wysie: Contact pictures
        private HashMap<Long, SoftReference<Bitmap>> mBitmapCache = null;
        private HashSet<ImageView> mItemsMissingImages = null;
        

        public void onClick(View view) {
            if (view instanceof QuickContactBadge) {
                PhotoInfo info = (PhotoInfo)view.getTag();
                QuickContact.showQuickContact(mContext, view, info.contactUri, QuickContact.MODE_MEDIUM, null);
                isQuickContact = true;
            }
            else {
                String number = (String) view.getTag();
                if (!TextUtils.isEmpty(number)) {
                    Uri telUri = Uri.fromParts("tel", number, null);
                    startActivity(new Intent(Intent.ACTION_CALL_PRIVILEGED, telUri));
                }
            }
        }

        public boolean onPreDraw() {
            if (mFirst) {
@@ -257,6 +324,11 @@ public class RecentCallsListActivity extends ListActivity
            mDrawableMissed = getResources().getDrawable(
                    R.drawable.ic_call_log_list_missed_call);
            mLabelArray = getResources().getTextArray(com.android.internal.R.array.phoneTypes);
            
            //Wysie: Contact pictures
            mBitmapCache = new HashMap<Long, SoftReference<Bitmap>>();
            mItemsMissingImages = new HashSet<ImageView>();
            mImageHandler = new ImageFetchHandler();
        }

        /**
@@ -367,6 +439,10 @@ public class RecentCallsListActivity extends ListActivity
                        info.label = phonesCursor.getString(LABEL_COLUMN_INDEX);
                        info.number = phonesCursor.getString(MATCHED_NUMBER_COLUMN_INDEX);
                        
                        //Wysie: Contact pictures
                        info.photoId = phonesCursor.getLong(PHOTO_ID_COLUMN_INDEX);
                        info.lookupKey = phonesCursor.getString(LOOKUP_KEY_COLUMN_INDEX);

                        // New incoming phone number invalidates our formatted
                        // cache. Any cache fills happen only on the GUI thread.
                        info.formattedNumber = null;
@@ -422,9 +498,16 @@ public class RecentCallsListActivity extends ListActivity
            views.numberView = (TextView) view.findViewById(R.id.number);
            views.dateView = (TextView) view.findViewById(R.id.date);
            views.iconView = (ImageView) view.findViewById(R.id.call_type_icon);
            views.dividerView = view.findViewById(R.id.divider);
            views.callView = view.findViewById(R.id.call_icon);
            views.callView.setOnClickListener(this);
            
            //Wysie: Contact pictures
            views.photoView = (QuickContactBadge) view.findViewById(R.id.photo);
            views.photoView.setOnClickListener(this);
            
            views.nonQuickContactPhotoView = (ImageView) view.findViewById(R.id.noQuickContactPhoto);

            view.setTag(views);

            return view;
@@ -441,9 +524,23 @@ public class RecentCallsListActivity extends ListActivity
            int callerNumberType = c.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
            String callerNumberLabel = c.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
            
            //Wysie
            boolean noContactInfo = false;
            
            // Store away the number so we can call it directly if you click on the call icon
            views.callView.setTag(number);
            
            //Wysie: Use iconView to dial out if dial button is hidden            
            if (!showDialButton) {
                views.iconView.setTag(number);
                views.iconView.setOnClickListener(this);
                //views.iconView.setBackgroundResource(R.drawable.call_background);
            } else {
                views.iconView.setTag(null);
                views.iconView.setOnClickListener(null);
                //views.iconView.setBackgroundResource(0);
            }

            // Lookup contacts with this number
            ContactInfo info = mContactInfo.get(number);
            if (info == null) {
@@ -491,6 +588,7 @@ public class RecentCallsListActivity extends ListActivity
            // 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);
@@ -520,11 +618,77 @@ public class RecentCallsListActivity extends ListActivity
                    number = formatPhoneNumber(number);
                }
                
                //Wysie
                noContactInfo = true;

                views.line1View.setText(number);
                views.numberView.setVisibility(View.GONE);
                views.labelView.setVisibility(View.GONE);
            }          
            
            //Wysie: Contact pictures
            if (mDisplayPhotos) {
                long photoId = info.photoId;

                // Build soft lookup reference
                final long contactId = info.personId;
                final String lookupKey = info.lookupKey;
                Uri contactUri = Contacts.getLookupUri(contactId, lookupKey);
                ImageView viewToUse;                
                
                if (noContactInfo) {
                    viewToUse = views.nonQuickContactPhotoView;
                    views.photoView.setVisibility(View.INVISIBLE);
                    views.nonQuickContactPhotoView.setVisibility(View.VISIBLE);
                } else {
                    viewToUse = views.photoView;                    
                    //views.photoView.assignContactUri(contactUri); //Wysie: Commented out, we handle it explicityly in onClick()
                    views.photoView.setTag(contactUri);
                    views.photoView.setVisibility(View.VISIBLE);
                    views.nonQuickContactPhotoView.setVisibility(View.INVISIBLE);
                }
                
                final int position = c.getPosition();
                viewToUse.setTag(new PhotoInfo(position, photoId, contactUri));

                if (photoId == 0) {
                    viewToUse.setImageResource(R.drawable.ic_contact_list_picture);
                } else {

                    Bitmap photo = null;

                    // Look for the cached bitmap
                    SoftReference<Bitmap> ref = mBitmapCache.get(photoId);
                    if (ref != null) {
                        photo = ref.get();
                        if (photo == null) {
                            mBitmapCache.remove(photoId);
                        }
                    }

                    // Bind the photo, or use the fallback no photo resource
                    if (photo != null) {
                        viewToUse.setImageBitmap(photo);
                    } else {
                        // Cache miss
                        viewToUse.setImageResource(R.drawable.ic_contact_list_picture);

                        // Add it to a set of images that are populated asynchronously.
                        mItemsMissingImages.add(viewToUse);

                        if (mScrollState != OnScrollListener.SCROLL_STATE_FLING) {

                            // Scrolling is idle or slow, go get the image right now.
                            sendFetchImageMessage(viewToUse);
                        }
                    }
                }
            }
            else {
                views.photoView.setVisibility(View.GONE);
                views.nonQuickContactPhotoView.setVisibility(View.GONE);
            }

            int type = c.getInt(CALL_TYPE_COLUMN_INDEX);
            long date = c.getLong(DATE_COLUMN_INDEX);
            
@@ -556,6 +720,14 @@ public class RecentCallsListActivity extends ListActivity
                views.dateView.setText(DateFormat.format(format, date));                         
            }            

            if (showDialButton) {
                views.dividerView.setVisibility(View.VISIBLE);
                views.callView.setVisibility(View.VISIBLE);
            } else {
                views.dividerView.setVisibility(View.GONE);
                views.callView.setVisibility(View.GONE);
            }

            // Set the icon
            switch (type) {
                case Calls.INCOMING_TYPE:
@@ -578,6 +750,161 @@ public class RecentCallsListActivity extends ListActivity
                view.getViewTreeObserver().addOnPreDrawListener(this);
            }
        }
        
        
        //Wysie: Contact pictures
        private class ImageFetchHandler extends Handler {

            @Override
            public void handleMessage(Message message) {
                if (RecentCallsListActivity.this.isFinishing()) {
                    return;
                }
                switch(message.what) {
                    case FETCH_IMAGE_MSG: {
                        final ImageView imageView = (ImageView) message.obj;
                        if (imageView == null) {
                            break;
                        }

                        final PhotoInfo info = (PhotoInfo)imageView.getTag();
                        if (info == null) {
                            break;
                        }

                        final long photoId = info.photoId;
                        if (photoId == 0) {
                            break;
                        }

                        SoftReference<Bitmap> photoRef = mBitmapCache.get(photoId);
                        if (photoRef == null) {
                            break;
                        }
                        Bitmap photo = photoRef.get();
                        if (photo == null) {
                            mBitmapCache.remove(photoId);
                            break;
                        }

                        // Make sure the photoId on this image view has not changed
                        // while we were loading the image.
                        synchronized (imageView) {
                            final PhotoInfo updatedInfo = (PhotoInfo)imageView.getTag();
                            long currentPhotoId = updatedInfo.photoId;
                            if (currentPhotoId == photoId) {
                                imageView.setImageBitmap(photo);
                                mItemsMissingImages.remove(imageView);
                            }
                        }
                        break;
                    }
                }
            }

            public void clearImageFecthing() {
                removeMessages(FETCH_IMAGE_MSG);
            }
        }
        
        //Wysie: Contact pictures
        private class ImageDbFetcher implements Runnable {
            long mPhotoId;
            private ImageView mImageView;

            public ImageDbFetcher(long photoId, ImageView imageView) {
                this.mPhotoId = photoId;
                this.mImageView = imageView;
            }

            public void run() {
                if (RecentCallsListActivity.this.isFinishing()) {
                    return;
                }

                if (Thread.interrupted()) {
                    // shutdown has been called.
                    return;
                }
                Bitmap photo = null;
                try {
                    photo = ContactsUtils.loadContactPhoto(mContext, mPhotoId, null);
                } catch (OutOfMemoryError e) {
                    // Not enough memory for the photo, do nothing.
                }

                if (photo == null) {
                    return;
                }

                mBitmapCache.put(mPhotoId, new SoftReference<Bitmap>(photo));

                if (Thread.interrupted()) {
                    // shutdown has been called.
                    return;
                }

                // Update must happen on UI thread
                Message msg = new Message();
                msg.what = FETCH_IMAGE_MSG;
                msg.obj = mImageView;
                mImageHandler.sendMessage(msg);
            }
        }
        
        //Wysie: Contact pictures
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                int totalItemCount) {
            // no op
        }
        
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            mScrollState = scrollState;
            if (scrollState == OnScrollListener.SCROLL_STATE_FLING) {
                // If we are in a fling, stop loading images.
                clearImageFetching();
            } else if (mDisplayPhotos) {
                processMissingImageItems(view);
            }
        }

        private void processMissingImageItems(AbsListView view) {
            for (ImageView iv : mItemsMissingImages) {
                sendFetchImageMessage(iv);
            }
        }

        private void sendFetchImageMessage(ImageView view) {
            final PhotoInfo info = (PhotoInfo) view.getTag();
            if (info == null) {
                return;
            }
            final long photoId = info.photoId;
            if (photoId == 0) {
                return;
            }
            mImageFetcher = new ImageDbFetcher(photoId, view);
            synchronized (RecentCallsListActivity.this) {
                // can't sync on sImageFetchThreadPool.
                if (sImageFetchThreadPool == null) {
                    // Don't use more than 3 threads at a time to update. The thread pool will be
                    // shared by all contact items.
                    sImageFetchThreadPool = Executors.newFixedThreadPool(3);
                }
                sImageFetchThreadPool.execute(mImageFetcher);
            }
        }
        
        public void clearImageFetching() {
            synchronized (RecentCallsListActivity.this) {
                if (sImageFetchThreadPool != null) {
                    sImageFetchThreadPool.shutdownNow();
                    sImageFetchThreadPool = null;
                }
            }

            mImageHandler.clearImageFecthing();
        }
    }

    private static final class QueryHandler extends AsyncQueryHandler {
@@ -638,6 +965,7 @@ public class RecentCallsListActivity extends ListActivity

        //Wysie
        ePrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        isQuickContact = false;
        
        setContentView(R.layout.recent_calls);

@@ -658,23 +986,38 @@ public class RecentCallsListActivity extends ListActivity

    @Override
    protected void onResume() {
        if (isQuickContact) {
            isQuickContact = false;
            super.onResume();
        }
        else {
            // The adapter caches looked up numbers, clear it so they will get
            // looked up again.
            if (mAdapter != null) {
                mAdapter.clearCache();
            }
            
            // Force cache to reload so we don't show stale photos.
            if (mAdapter.mBitmapCache != null) {
                mAdapter.mBitmapCache.clear();
            }
            
            exactTime = ePrefs.getBoolean("cl_exact_time", true);
            is24hour = DateFormat.is24HourFormat(this);
            showSeconds = ePrefs.getBoolean("cl_show_seconds", true);
            mDisplayPhotos = ePrefs.getBoolean("cl_show_pic", true);
            showDialButton = ePrefs.getBoolean("cl_show_dial_button", false);
            
            super.onResume();

            startQuery();
            resetNewCallsFlag();
        
        super.onResume();
            mScrollState = OnScrollListener.SCROLL_STATE_IDLE;

            mAdapter.mPreDrawListener = null; // Let it restart the thread after next draw
        }
    }

    @Override
    protected void onPause() {
Loading