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

Commit c759ffbc authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change I740cfdad into eclair

* changes:
  Use a thread pool to fetch images. Bug 2163087.
parents d40d7f06 740cfdad
Loading
Loading
Loading
Loading
+84 −13
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*TODO(emillar) I commented most of the code that deals with modes and filtering. It should be
 * brought back in as we add back that functionality.
@@ -389,6 +392,8 @@ public class ContactsListActivity extends ListActivity implements
    private static final int CONTACTS_ID = 1001;
    private static final UriMatcher sContactsIdMatcher;

    private static ExecutorService sImageFetchThreadPool;

    static {
        sContactsIdMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sContactsIdMatcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
@@ -2021,6 +2026,7 @@ public class ContactsListActivity extends ListActivity implements
        private Cursor mSuggestionsCursor;
        private int mSuggestionsCursorCount;
        private ImageFetchHandler mHandler;
        private ImageDbFetcher mImageFetcher;
        private static final int FETCH_IMAGE_MSG = 1;

        public ContactItemListAdapter(Context context) {
@@ -2095,18 +2101,11 @@ public class ContactsListActivity extends ListActivity implements
                            break;
                        }

                        Bitmap photo = null;
                        try {
                            photo = ContactsUtils.loadContactPhoto(mContext, photoId, null);
                        } catch (OutOfMemoryError e) {
                            // Not enough memory for the photo, do nothing.
                        }
                        Bitmap photo = mBitmapCache.get(photoId).get();
                        if (photo == null) {
                            break;
                        }

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

                        // Make sure the photoId on this image view has not changed
                        // while we were loading the image.
                        synchronized (imageView) {
@@ -2127,6 +2126,50 @@ public class ContactsListActivity extends ListActivity implements
            }
        }

        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 (ContactsListActivity.this.isFinishing()) {
                    return;
                }

                if (Thread.currentThread().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.currentThread().interrupted()) {
                    // shutdown has been called.
                    return;
                }

                // Update must happen on UI thread
                Message msg = new Message();
                msg.what = FETCH_IMAGE_MSG;
                msg.obj = mImageView;
                mHandler.sendMessage(msg);
            }
        }

        public void setSuggestionsCursor(Cursor cursor) {
            if (mSuggestionsCursor != null) {
                mSuggestionsCursor.close();
@@ -2775,14 +2818,42 @@ public class ContactsListActivity extends ListActivity implements
        }

        private void sendFetchImageMessage(ImageView view) {
            Message msg = new Message();
            msg.what = FETCH_IMAGE_MSG;
            msg.obj = view;
            mHandler.sendMessage(msg);
            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 (ContactsListActivity.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);
            }
        }


        /** Clear all pending messages on the {@link ImageFetchHandler} */
        /**
         * Stop the image fetching for ALL contacts, if one is in progress we'll
         * not query the database.
         *
         * TODO: move this method to ContactsListActivity, it does not apply to the current
         * contact.
         */
        public void clearImageFetching() {
            synchronized (ContactsListActivity.this) {
                if (sImageFetchThreadPool != null) {
                    sImageFetchThreadPool.shutdownNow();
                    sImageFetchThreadPool = null;
                }
            }

            mHandler.clearImageFecthing();
        }
    }