1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.messaging.ui;
17
18import android.content.Context;
19import android.content.res.Resources;
20import android.content.res.TypedArray;
21import android.net.Uri;
22import android.text.TextUtils;
23import android.util.AttributeSet;
24import android.view.MotionEvent;
25import android.view.View;
26
27import com.android.messaging.R;
28import com.android.messaging.datamodel.data.ParticipantData;
29import com.android.messaging.datamodel.media.AvatarGroupRequestDescriptor;
30import com.android.messaging.datamodel.media.AvatarRequestDescriptor;
31import com.android.messaging.util.Assert;
32import com.android.messaging.util.AvatarUriUtil;
33import com.android.messaging.util.ContactUtil;
34
35/**
36 * A view used to render contact icons. This class derives from AsyncImageView, so it loads contact
37 * icons from MediaResourceManager, and it handles more rendering logic than an AsyncImageView
38 * (draws a circular bitmap).
39 */
40public class ContactIconView extends AsyncImageView {
41    private static final int NORMAL_ICON_SIZE_ID = 0;
42    private static final int LARGE_ICON_SIZE_ID = 1;
43    private static final int SMALL_ICON_SIZE_ID = 2;
44
45    protected final int mIconSize;
46    private final int mColorPressedId;
47
48    private long mContactId;
49    private String mContactLookupKey;
50    private String mNormalizedDestination;
51    private Uri mAvatarUri;
52    private boolean mDisableClickHandler;
53
54    public ContactIconView(final Context context, final AttributeSet attrs) {
55        super(context, attrs);
56
57        final Resources resources = context.getResources();
58        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ContactIconView);
59
60        final int iconSizeId = a.getInt(R.styleable.ContactIconView_iconSize, 0);
61        switch (iconSizeId) {
62            case NORMAL_ICON_SIZE_ID:
63                mIconSize = (int) resources.getDimension(
64                        R.dimen.contact_icon_view_normal_size);
65                break;
66            case LARGE_ICON_SIZE_ID:
67                mIconSize = (int) resources.getDimension(
68                        R.dimen.contact_icon_view_large_size);
69                break;
70            case SMALL_ICON_SIZE_ID:
71                mIconSize = (int) resources.getDimension(
72                        R.dimen.contact_icon_view_small_size);
73                break;
74            default:
75                // For the compiler, something has to be set even with the assert.
76                mIconSize = 0;
77                Assert.fail("Unsupported ContactIconView icon size attribute");
78        }
79        mColorPressedId = resources.getColor(R.color.contact_avatar_pressed_color);
80
81        setImage(null);
82        a.recycle();
83    }
84
85    @Override
86    public boolean onTouchEvent(MotionEvent event) {
87        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
88            setColorFilter(mColorPressedId);
89        } else {
90            clearColorFilter();
91        }
92        return super.onTouchEvent(event);
93    }
94
95    /**
96     * Method which allows the automatic hookup of a click handler when the Uri is changed
97     */
98    public void setImageClickHandlerDisabled(final boolean isHandlerDisabled) {
99        mDisableClickHandler = isHandlerDisabled;
100        setOnClickListener(null);
101        setClickable(false);
102    }
103
104    /**
105     * A convenience method that sets the URI of the contact icon by creating a new image request.
106     */
107    public void setImageResourceUri(final Uri uri) {
108        setImageResourceUri(uri, 0, null, null);
109    }
110
111    public void setImageResourceUri(final Uri uri, final long contactId,
112            final String contactLookupKey, final String normalizedDestination) {
113        if (uri == null) {
114            setImageResourceId(null);
115        } else {
116            final String avatarType = AvatarUriUtil.getAvatarType(uri);
117            if (AvatarUriUtil.TYPE_GROUP_URI.equals(avatarType)) {
118                setImageResourceId(new AvatarGroupRequestDescriptor(uri, mIconSize, mIconSize));
119            } else {
120                setImageResourceId(new AvatarRequestDescriptor(uri, mIconSize, mIconSize));
121            }
122        }
123
124        mContactId = contactId;
125        mContactLookupKey = contactLookupKey;
126        mNormalizedDestination = normalizedDestination;
127        mAvatarUri = uri;
128
129        maybeInitializeOnClickListener();
130    }
131
132    protected void maybeInitializeOnClickListener() {
133        if ((mContactId > ParticipantData.PARTICIPANT_CONTACT_ID_NOT_RESOLVED
134                && !TextUtils.isEmpty(mContactLookupKey)) ||
135                !TextUtils.isEmpty(mNormalizedDestination)) {
136            if (!mDisableClickHandler) {
137                setOnClickListener(new View.OnClickListener() {
138                    @Override
139                    public void onClick(final View view) {
140                        ContactUtil.showOrAddContact(view, mContactId, mContactLookupKey,
141                                mAvatarUri, mNormalizedDestination);
142                    }
143                });
144            }
145        } else {
146            // This should happen when the phone number is not in the user's contacts or it is a
147            // group conversation, group conversations don't have contact phone numbers. If this
148            // is the case then absorb the click to prevent propagation.
149            setOnClickListener(null);
150        }
151    }
152}
153