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  */
16 package com.android.messaging.ui;
17 
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.content.res.TypedArray;
21 import android.net.Uri;
22 import android.text.TextUtils;
23 import android.util.AttributeSet;
24 import android.view.MotionEvent;
25 import android.view.View;
26 
27 import com.android.messaging.R;
28 import com.android.messaging.datamodel.data.ParticipantData;
29 import com.android.messaging.datamodel.media.AvatarGroupRequestDescriptor;
30 import com.android.messaging.datamodel.media.AvatarRequestDescriptor;
31 import com.android.messaging.util.Assert;
32 import com.android.messaging.util.AvatarUriUtil;
33 import 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  */
40 public 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 
ContactIconView(final Context context, final AttributeSet attrs)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
onTouchEvent(MotionEvent event)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      */
setImageClickHandlerDisabled(final boolean isHandlerDisabled)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      */
setImageResourceUri(final Uri uri)107     public void setImageResourceUri(final Uri uri) {
108         setImageResourceUri(uri, 0, null, null);
109     }
110 
setImageResourceUri(final Uri uri, final long contactId, final String contactLookupKey, final String normalizedDestination)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 
maybeInitializeOnClickListener()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