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

Commit 48fc9121 authored by Paul Soulos's avatar Paul Soulos
Browse files

Adds VOLTE icon and capabilities to QuickContact

bug: 16015752
Change-Id: I9970d5901f80fc56d7528d61da6b4e8b8c66e0c1
parent a9cdf984
Loading
Loading
Loading
Loading
+23 −11
Original line number Diff line number Diff line
@@ -86,12 +86,24 @@
         android:id="@+id/icon_alternate"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
         android:layout_alignParentTop="true"
         android:layout_toStartOf="@+id/third_icon"
         android:layout_alignWithParentIfMissing="true"
         android:visibility="gone"
         android:background="?android:attr/selectableItemBackgroundBorderless"
         android:paddingTop="@dimen/expanding_entry_card_item_icon_margin_top"
         android:paddingBottom="@dimen/expanding_entry_card_item_alternate_icon_margin_bottom"
         android:layout_marginStart="@dimen/expanding_entry_card_item_alternate_icon_start_margin" />

     <ImageView
         android:id="@+id/third_icon"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentEnd="true"
         android:layout_alignParentTop="true"
         android:visibility="gone"
         android:background="?android:attr/selectableItemBackgroundBorderless"
         android:paddingTop="@dimen/expanding_entry_card_item_icon_margin_top"
         android:paddingBottom="@dimen/expanding_entry_card_item_alternate_icon_margin_bottom"
         android:layout_marginStart="@dimen/expanding_entry_card_item_alternate_icon_start_margin" />
</view>
+149 −34
Original line number Diff line number Diff line
@@ -35,8 +35,9 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.TouchDelegate;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -81,21 +82,26 @@ public class ExpandingEntryCardView extends CardView {
        private final boolean mShouldApplyColor;
        private final boolean mIsEditable;
        private final EntryContextMenuInfo mEntryContextMenuInfo;
        private final Drawable mThirdIcon;
        private final Intent mThirdIntent;
        private final String mThirdContentDescription;

        public Entry(int id, Drawable icon, String header, String subHeader, String text,
                Intent intent, Drawable alternateIcon, Intent alternateIntent,
                String alternateContentDescription, boolean shouldApplyColor,
                boolean isEditable, EntryContextMenuInfo entryContextMenuInfo) {
                boolean isEditable, EntryContextMenuInfo entryContextMenuInfo,
                Drawable thirdIcon, Intent thirdIntent, String thirdContentDescription) {
            this(id, icon, header, subHeader, null, text, null, intent, alternateIcon,
                    alternateIntent, alternateContentDescription, shouldApplyColor, isEditable,
                    entryContextMenuInfo);
                    entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
        }

        public Entry(int id, Drawable mainIcon, String header, String subHeader,
                Drawable subHeaderIcon, String text, Drawable textIcon, Intent intent,
                Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription,
                boolean shouldApplyColor, boolean isEditable,
                EntryContextMenuInfo entryContextMenuInfo) {
                EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent,
                String thirdContentDescription) {
            mId = id;
            mIcon = mainIcon;
            mHeader = header;
@@ -110,6 +116,9 @@ public class ExpandingEntryCardView extends CardView {
            mShouldApplyColor = shouldApplyColor;
            mIsEditable = isEditable;
            mEntryContextMenuInfo = entryContextMenuInfo;
            mThirdIcon = thirdIcon;
            mThirdIntent = thirdIntent;
            mThirdContentDescription = thirdContentDescription;
        }

        Drawable getIcon() {
@@ -167,6 +176,18 @@ public class ExpandingEntryCardView extends CardView {
        EntryContextMenuInfo getEntryContextMenuInfo() {
            return mEntryContextMenuInfo;
        }

        Drawable getThirdIcon() {
            return mThirdIcon;
        }

        Intent getThirdIntent() {
            return mThirdIntent;
        }

        String getThirdContentDescription() {
            return mThirdContentDescription;
        }
    }

    public interface ExpandingEntryCardViewListener {
@@ -541,6 +562,10 @@ public class ExpandingEntryCardView extends CardView {
                        if (alternateIcon != null) {
                            alternateIcon.setColorFilter(mThemeColorFilter);
                        }
                        Drawable thirdIcon = entry.getThirdIcon();
                        if (thirdIcon != null) {
                            thirdIcon.setColorFilter(mThemeColorFilter);
                        }
                    }
                }
            }
@@ -621,36 +646,6 @@ public class ExpandingEntryCardView extends CardView {
            header.setLayoutParams(headerLayoutParams);
        }

        final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate);
        if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) {
            alternateIcon.setImageDrawable(entry.getAlternateIcon());
            alternateIcon.setOnClickListener(mOnClickListener);
            alternateIcon.setTag(new EntryTag(entry.getId(), entry.getAlternateIntent()));
            alternateIcon.setVisibility(View.VISIBLE);
            alternateIcon.setContentDescription(entry.getAlternateContentDescription());

            // Expand the clickable area for alternate icon to be top to bottom and to end edge
            // of the entry view
            view.post(new Runnable() {
                @Override
                public void run() {
                    final Rect alternateIconRect = new Rect();
                    alternateIcon.getHitRect(alternateIconRect);

                    alternateIconRect.bottom = view.getHeight();
                    alternateIconRect.top = 0;
                    if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
                        alternateIconRect.left = 0;
                    } else {
                        alternateIconRect.right = view.getWidth();
                    }
                    final TouchDelegate touchDelegate =
                            new TouchDelegate(alternateIconRect, alternateIcon);
                    view.setTouchDelegate(touchDelegate);
                }
            });
        }

        // Adjust the top padding size for entries with an invisible icon. The padding depends on
        // if there is a sub header or text section
        if (iconVisibility == View.INVISIBLE &&
@@ -666,6 +661,27 @@ public class ExpandingEntryCardView extends CardView {
                    view.getPaddingBottom());
        }

        final ImageView alternateIcon = (ImageView) view.findViewById(R.id.icon_alternate);
        final ImageView thirdIcon = (ImageView) view.findViewById(R.id.third_icon);

        if (entry.getAlternateIcon() != null && entry.getAlternateIntent() != null) {
            alternateIcon.setImageDrawable(entry.getAlternateIcon());
            alternateIcon.setOnClickListener(mOnClickListener);
            alternateIcon.setTag(new EntryTag(entry.getId(), entry.getAlternateIntent()));
            alternateIcon.setVisibility(View.VISIBLE);
            alternateIcon.setContentDescription(entry.getAlternateContentDescription());
        }

        if (entry.getThirdIcon() != null && entry.getThirdIntent() != null) {
            thirdIcon.setImageDrawable(entry.getThirdIcon());
            thirdIcon.setOnClickListener(mOnClickListener);
            thirdIcon.setTag(new EntryTag(entry.getId(), entry.getThirdIntent()));
            thirdIcon.setVisibility(View.VISIBLE);
            thirdIcon.setContentDescription(entry.getThirdContentDescription());
        }

        // Set a custom touch listener for expanding the extra icon touch areas
        view.setOnTouchListener(new EntryTouchListener(view, alternateIcon, thirdIcon));
        view.setOnCreateContextMenuListener(mOnCreateContextMenuListener);

        return view;
@@ -920,4 +936,103 @@ public class ExpandingEntryCardView extends CardView {
            return mIntent;
        }
    }

    /**
     * This custom touch listener increases the touch area for the second and third icons, if
     * they are present. This is necessary to maintain other properties on an entry view, like
     * using a top padding on entry. Based off of {@link android.view.TouchDelegate}
     */
    private static final class EntryTouchListener implements View.OnTouchListener {
        private final View mEntry;
        private final ImageView mAlternateIcon;
        private final ImageView mThirdIcon;
        /** mTouchedView locks in a view on touch down */
        private View mTouchedView;
        /** mSlop adds some space to account for touches that are just outside the hit area */
        private int mSlop;

        public EntryTouchListener(View entry, ImageView alternateIcon, ImageView thirdIcon) {
            mEntry = entry;
            mAlternateIcon = alternateIcon;
            mThirdIcon = thirdIcon;
            mSlop = ViewConfiguration.get(entry.getContext()).getScaledTouchSlop();
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            View touchedView = mTouchedView;
            boolean sendToTouched = false;
            boolean hit = true;
            boolean handled = false;

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (hitThirdIcon(event)) {
                        mTouchedView = mThirdIcon;
                        sendToTouched = true;
                    } else if (hitAlternateIcon(event)) {
                        mTouchedView = mAlternateIcon;
                        sendToTouched = true;
                    } else {
                        mTouchedView = mEntry;
                        sendToTouched = false;
                    }
                    touchedView = mTouchedView;
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_MOVE:
                    sendToTouched = mTouchedView != null && mTouchedView != mEntry;
                    if (sendToTouched) {
                        final Rect slopBounds = new Rect();
                        touchedView.getHitRect(slopBounds);
                        slopBounds.inset(-mSlop, -mSlop);
                        if (!slopBounds.contains((int) event.getX(), (int) event.getY())) {
                            hit = false;
                        }
                    }
                    break;
                case MotionEvent.ACTION_CANCEL:
                    sendToTouched = mTouchedView != null && mTouchedView != mEntry;
                    mTouchedView = null;
                    break;
            }
            if (sendToTouched) {
                if (hit) {
                    event.setLocation(touchedView.getWidth() / 2, touchedView.getHeight() / 2);
                } else {
                    // Offset event coordinates to be outside the target view (in case it does
                    // something like tracking pressed state)
                    event.setLocation(-(mSlop * 2), -(mSlop * 2));
                }
                handled = touchedView.dispatchTouchEvent(event);
            }
            return handled;
        }

        private boolean hitThirdIcon(MotionEvent event) {
            if (mEntry.isLayoutRtl()) {
                return mThirdIcon.getVisibility() == View.VISIBLE &&
                        event.getX() < mThirdIcon.getRight();
            } else {
                return mThirdIcon.getVisibility() == View.VISIBLE &&
                        event.getX() > mThirdIcon.getLeft();
            }
        }

        /**
         * Should be used after checking if third icon was hit
         */
        private boolean hitAlternateIcon(MotionEvent event) {
            // LayoutParams used to add the start margin to the touch area
            final RelativeLayout.LayoutParams alternateIconParams =
                    (RelativeLayout.LayoutParams) mAlternateIcon.getLayoutParams();
            if (mEntry.isLayoutRtl()) {
                return mAlternateIcon.getVisibility() == View.VISIBLE &&
                        event.getX() < mAlternateIcon.getRight() + alternateIconParams.rightMargin;
            } else {
                return mAlternateIcon.getVisibility() == View.VISIBLE &&
                        event.getX() > mAlternateIcon.getLeft() - alternateIconParams.leftMargin;
            }
        }
    }
}
+29 −6
Original line number Diff line number Diff line
@@ -135,7 +135,6 @@ import com.android.contacts.util.SchedulingUtils;
import com.android.contacts.util.StructuredPostalUtils;
import com.android.contacts.widget.MultiShrinkScroller;
import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

@@ -185,6 +184,8 @@ public class QuickContactActivity extends ContactsActivity {
    private static final String MIMETYPE_HANGOUTS =
            "vnd.android.cursor.item/vnd.googleplus.profile.comm";
    private static final String INTENT_DATA_HANGOUTS_VIDEO = "Start video call";
    private static final String CALL_ORIGIN_QUICK_CONTACTS_ACTIVITY =
            "com.android.contacts.quickcontact.QuickContactActivity";

    /**
     * The URI used to load the the Contact. Once the contact is loaded, use Contact#getLookupUri()
@@ -937,7 +938,10 @@ public class QuickContactActivity extends ContactsActivity {
                    /* shouldApplyColor = */ false,
                    /* isEditable = */ false,
                    /* EntryContextMenuInfo = */ new EntryContextMenuInfo(phoneticName,
                            getResources().getString(R.string.name_phonetic)));
                            getResources().getString(R.string.name_phonetic)),
                    /* thirdIcon = */ null,
                    /* thirdIntent = */ null,
                    /* thirdContentDescription = */ null);
            List<Entry> phoneticList = new ArrayList<>();
            phoneticList.add(phoneticEntry);
            // Phonetic name comes after nickname. Check to see if the first entry type is nickname
@@ -987,7 +991,9 @@ public class QuickContactActivity extends ContactsActivity {
                /* subHeader = */ null, /* text = */ null, getEditContactIntent(),
                /* alternateIcon = */ null, /* alternateIntent = */ null,
                /* alternateContentDescription = */ null, /* shouldApplyColor = */ true,
                /* isEditable = */ false, /* EntryContextMenuInfo = */ null);
                /* isEditable = */ false, /* EntryContextMenuInfo = */ null,
                /* thirdIcon = */ null, /* thirdIntent = */ null,
                /* thirdContentDescription = */ null);

        final Drawable emailIcon = getResources().getDrawable(
                R.drawable.ic_email_24dp).mutate();
@@ -996,7 +1002,8 @@ public class QuickContactActivity extends ContactsActivity {
                /* text = */ null, getEditContactIntent(), /* alternateIcon = */ null,
                /* alternateIntent = */ null, /* alternateContentDescription = */ null,
                /* shouldApplyColor = */ true, /* isEditable = */ false,
                /* EntryContextMenuInfo = */ null);
                /* EntryContextMenuInfo = */ null, /* thirdIcon = */ null,
                /* thirdIntent = */ null, /* thirdContentDescription = */ null);

        final List<List<Entry>> promptEntries = new ArrayList<>();
        promptEntries.add(new ArrayList<Entry>(1));
@@ -1157,6 +1164,9 @@ public class QuickContactActivity extends ContactsActivity {
        String alternateContentDescription = null;
        final boolean isEditable = false;
        EntryContextMenuInfo entryContextMenuInfo = null;
        Drawable thirdIcon = null;
        Intent thirdIntent = null;
        String thirdContentDescription = null;

        context = context.getApplicationContext();
        DataKind kind = dataItem.getDataKind();
@@ -1273,8 +1283,18 @@ public class QuickContactActivity extends ContactsActivity {
                }
                alternateIntent = new Intent(Intent.ACTION_SENDTO,
                        Uri.fromParts(CallUtil.SCHEME_SMSTO, phone.getNumber(), null));

                alternateIcon = context.getResources().getDrawable(R.drawable.ic_message_24dp);
                alternateContentDescription = context.getResources().getString(R.string.sms_other);

                // Add video call button if supported
                if (CallUtil.isVideoEnabled()) {
                    thirdIcon = context.getResources().getDrawable(R.drawable.ic_videocam);
                    thirdIntent = CallUtil.getVideoCallIntent(phone.getNumber(),
                            CALL_ORIGIN_QUICK_CONTACTS_ACTIVITY);
                    thirdContentDescription =
                            context.getResources().getString(R.string.description_video_call);
                }
            }
        } else if (dataItem instanceof EmailDataItem) {
            final EmailDataItem email = (EmailDataItem) dataItem;
@@ -1406,7 +1426,7 @@ public class QuickContactActivity extends ContactsActivity {

        return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon, intent,
                alternateIcon, alternateIntent, alternateContentDescription, shouldApplyColor,
                isEditable, entryContextMenuInfo);
                isEditable, entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
    }

    private List<Entry> dataItemsToEntries(List<DataItem> dataItems,
@@ -1574,7 +1594,10 @@ public class QuickContactActivity extends ContactsActivity {
                    /* alternateContentDescription = */ null,
                    /* shouldApplyColor = */ true,
                    /* isEditable = */ false,
                    /* EntryContextMenuInfo = */ null));
                    /* EntryContextMenuInfo = */ null,
                    /* thirdIcon = */ null,
                    /* thirdIntent = */ null,
                    /* thirdContentDescription = */ null));
        }
        return entries;
    }