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

Commit f748d59e authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Launch viewStreamItemPhotoActivity when photo is tapped...

on stream item list, if the account type supports it.

If the account type doesn't support it, tap of photos launches
viewStreamItemActivity as before.

Bug 5185880

Change-Id: I0b43da3e966ee7737937b2dde7a97e4c440d00dc
parent 06dfcefa
Loading
Loading
Loading
Loading
+46 −14
Original line number Diff line number Diff line
@@ -20,13 +20,13 @@ import com.android.contacts.ContactLoader;
import com.android.contacts.ContactLoader.Result;
import com.android.contacts.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.format.FormatUtils;
import com.android.contacts.preference.ContactsPreferences;
import com.android.contacts.util.ContactBadgeUtil;
import com.android.contacts.util.StreamItemEntry;
import com.android.contacts.util.StreamItemPhotoEntry;
import com.google.common.annotations.VisibleForTesting;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
@@ -37,16 +37,15 @@ import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.DisplayNameSources;
import android.provider.ContactsContract.StreamItems;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
@@ -71,6 +70,27 @@ public class ContactDetailDisplayUtils {

    private static final int PHOTO_FADE_IN_ANIMATION_DURATION_MILLIS = 100;

    /**
     * Tag object used for stream item photos.
     */
    public static class StreamPhotoTag {
        public final StreamItemEntry streamItem;
        public final StreamItemPhotoEntry streamItemPhoto;

        public StreamPhotoTag(StreamItemEntry streamItem, StreamItemPhotoEntry streamItemPhoto) {
            this.streamItem = streamItem;
            this.streamItemPhoto = streamItemPhoto;
        }

        public Uri getStreamItemPhotoUri() {
            final Uri.Builder builder = StreamItems.CONTENT_URI.buildUpon();
            ContentUris.appendId(builder, streamItem.getId());
            builder.appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
            ContentUris.appendId(builder, streamItemPhoto.getId());
            return builder.build();
        }
    }

    private ContactDetailDisplayUtils() {
        // Disallow explicit creation of this class.
    }
@@ -244,7 +264,8 @@ public class ContactDetailDisplayUtils {

    /** Creates the view that represents a stream item. */
    public static View createStreamItemView(LayoutInflater inflater, Context context,
            StreamItemEntry streamItem, LinearLayout parent) {
            StreamItemEntry streamItem, LinearLayout parent,
            View.OnClickListener photoClickListener) {
        View container = inflater.inflate(R.layout.stream_item_container, parent, false);
        ViewGroup contentTable = (ViewGroup) container.findViewById(R.id.stream_item_content);

@@ -261,17 +282,17 @@ public class ContactDetailDisplayUtils {

                View photoContainer = inflater.inflate(R.layout.stream_item_row_two_images,
                        contentTable, false);
                loadPhoto(contactPhotoManager, firstPhoto, photoContainer,
                        R.id.stream_item_first_image);
                loadPhoto(contactPhotoManager, secondPhoto, photoContainer,
                        R.id.stream_item_second_image);
                loadPhoto(contactPhotoManager, streamItem, firstPhoto, photoContainer,
                        R.id.stream_item_first_image, photoClickListener);
                loadPhoto(contactPhotoManager, streamItem, secondPhoto, photoContainer,
                        R.id.stream_item_second_image, photoClickListener);
                contentTable.addView(photoContainer);
            } else {
                // Put in a single photo with text on the side.
                View photoContainer = inflater.inflate(
                        R.layout.stream_item_row_image_and_text, contentTable, false);
                loadPhoto(contactPhotoManager, firstPhoto, photoContainer,
                        R.id.stream_item_first_image);
                loadPhoto(contactPhotoManager, streamItem, firstPhoto, photoContainer,
                        R.id.stream_item_first_image, photoClickListener);
                addStreamItemText(context, streamItem,
                        photoContainer.findViewById(R.id.stream_item_second_text));
                contentTable.addView(photoContainer);
@@ -294,11 +315,22 @@ public class ContactDetailDisplayUtils {
        return container;
    }

    /** Loads a photo into an image view. The image view is identifiedc by the given id. */
    /** Loads a photo into an image view. The image view is identified by the given id. */
    private static void loadPhoto(ContactPhotoManager contactPhotoManager,
            final StreamItemPhotoEntry firstPhoto, View photoContainer, int imageViewId) {
        ImageView firstImageView = (ImageView) photoContainer.findViewById(imageViewId);
        contactPhotoManager.loadPhoto(firstImageView, Uri.parse(firstPhoto.getPhotoUri()));
            final StreamItemEntry streamItem, final StreamItemPhotoEntry streamItemPhoto,
            View photoContainer, int imageViewId, View.OnClickListener photoClickListener) {
        ImageView imageView = (ImageView) photoContainer.findViewById(imageViewId);
        if (photoClickListener != null) {
            imageView.setOnClickListener(photoClickListener);
            imageView.setTag(new StreamPhotoTag(streamItem, streamItemPhoto));
            imageView.setFocusable(true);
        } else {
            imageView.setOnClickListener(null);
            imageView.setTag(null);
            imageView.setFocusable(false);
            imageView.setClickable(false); // setOnClickListener makes it clickable, so overwrite it
        }
        contactPhotoManager.loadPhoto(imageView, Uri.parse(streamItemPhoto.getPhotoUri()));
    }

    @VisibleForTesting
+28 −5
Original line number Diff line number Diff line
@@ -19,9 +19,11 @@ package com.android.contacts.detail;
import com.android.contacts.ContactLoader;
import com.android.contacts.R;
import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.util.StreamItemEntry;
import com.android.contacts.util.StreamItemPhotoEntry;

import android.app.ListFragment;
import android.content.ContentUris;
@@ -67,7 +69,7 @@ public class ContactDetailUpdatesFragment extends ListFragment
     * <p>
     * It assumes the view has a tag of type {@link StreamItemEntry} associated with it.
     */
    private View.OnClickListener mStreamItemClickListener = new View.OnClickListener() {
    private final View.OnClickListener mStreamItemClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            StreamItemEntry streamItemEntry = (StreamItemEntry) view.getTag();
@@ -75,9 +77,7 @@ public class ContactDetailUpdatesFragment extends ListFragment
                // Ignore if this item does not have a stream item associated with it.
                return;
            }
            final AccountTypeManager manager = AccountTypeManager.getInstance(getActivity());
            final AccountType accountType = manager.getAccountType(
                    streamItemEntry.getAccountType(), streamItemEntry.getDataSet());
            final AccountType accountType = getAccountTypeForStreamItemEntry(streamItemEntry);

            final Uri uri = ContentUris.withAppendedId(StreamItems.CONTENT_URI,
                    streamItemEntry.getId());
@@ -88,6 +88,28 @@ public class ContactDetailUpdatesFragment extends ListFragment
        }
    };

    private final View.OnClickListener mStreamItemPhotoItemClickListener
            = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            StreamPhotoTag tag = (StreamPhotoTag) view.getTag();
            if (tag == null) {
                return;
            }
            final AccountType accountType = getAccountTypeForStreamItemEntry(tag.streamItem);

            final Intent intent = new Intent(Intent.ACTION_VIEW, tag.getStreamItemPhotoUri());
            intent.setClassName(accountType.resPackageName,
                    accountType.getViewStreamItemPhotoActivity());
            startActivity(intent);
        }
    };

    private AccountType getAccountTypeForStreamItemEntry(StreamItemEntry streamItemEntry) {
        return AccountTypeManager.getInstance(getActivity()).getAccountType(
                streamItemEntry.getAccountType(), streamItemEntry.getDataSet());
    }

    public ContactDetailUpdatesFragment() {
        // Explicit constructor for inflation
    }
@@ -108,7 +130,8 @@ public class ContactDetailUpdatesFragment extends ListFragment
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mStreamItemAdapter = new StreamItemAdapter(getActivity(), mStreamItemClickListener);
        mStreamItemAdapter = new StreamItemAdapter(getActivity(), mStreamItemClickListener,
                mStreamItemPhotoItemClickListener);
        setListAdapter(mStreamItemAdapter);
        getListView().setOnScrollListener(mVerticalScrollListener);

+13 −7
Original line number Diff line number Diff line
@@ -42,14 +42,17 @@ public class StreamItemAdapter extends BaseAdapter {
    private static final int ITEM_VIEW_TYPE_STREAM_ITEM = 2;

    private final Context mContext;
    private final View.OnClickListener mListener;
    private final View.OnClickListener mItemClickListener;
    private final View.OnClickListener mPhotoClickListener;
    private final LayoutInflater mInflater;

    private List<StreamItemEntry> mStreamItems;

    public StreamItemAdapter(Context context, View.OnClickListener listener) {
    public StreamItemAdapter(Context context, View.OnClickListener itemClickListener,
            View.OnClickListener photoClickListener) {
        mContext = context;
        mListener = listener;
        mItemClickListener = itemClickListener;
        mPhotoClickListener = photoClickListener;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mStreamItems = Lists.newArrayList();
    }
@@ -83,20 +86,23 @@ public class StreamItemAdapter extends BaseAdapter {
        if (position == 1) {
            return mInflater.inflate(R.layout.updates_title, null);
        }
        StreamItemEntry streamItem = (StreamItemEntry) getItem(position);
        View view = ContactDetailDisplayUtils.createStreamItemView(
                mInflater, mContext, streamItem, null);
        final StreamItemEntry streamItem = (StreamItemEntry) getItem(position);
        final AccountTypeManager manager = AccountTypeManager.getInstance(mContext);
        final AccountType accountType =
                manager.getAccountType(streamItem.getAccountType(), streamItem.getDataSet());
        final View view = ContactDetailDisplayUtils.createStreamItemView(
                mInflater, mContext, streamItem, null,
                (accountType.getViewStreamItemPhotoActivity() == null) ? null : mPhotoClickListener
                );
        if (accountType.getViewStreamItemActivity() != null) {
            view.setTag(streamItem);
            view.setFocusable(true);
            view.setOnClickListener(mListener);
            view.setOnClickListener(mItemClickListener);
        } else {
            view.setTag(null);
            view.setFocusable(false);
            view.setOnClickListener(null);
            view.setClickable(false); // setOnClickListener makes it clickable, so overwrite it
        }
        return view;
    }
+4 −1
Original line number Diff line number Diff line
@@ -28,19 +28,22 @@ import java.util.ArrayList;
// TODO: We should have tests for action, but that requires a mock sync-adapter that specifies
// an action or doesn't

// TODO Add test for photo click

/**
 * Unit tests for {@link StreamItemAdapter}.
 */
public class StreamItemAdapterTest extends AndroidTestCase {
    private StreamItemAdapter mAdapter;
    private FakeOnClickListener mListener;
    private FakeOnClickListener mPhotoListener;
    private View mView;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mListener = new FakeOnClickListener();
        mAdapter = new StreamItemAdapter(getContext(), mListener);
        mAdapter = new StreamItemAdapter(getContext(), mListener, mPhotoListener);
    }

    @Override