1/*
2 * Copyright (C) 2011 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.contacts.common.list;
17
18import android.content.Context;
19import android.graphics.Rect;
20import android.net.Uri;
21import android.util.AttributeSet;
22import android.view.View;
23import android.widget.FrameLayout;
24import android.widget.ImageView;
25import android.widget.TextView;
26import com.android.contacts.common.ContactPhotoManager;
27import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
28import com.android.contacts.common.MoreContactUtils;
29import com.android.contacts.common.R;
30import com.android.dialer.callintent.CallInitiationType;
31import com.android.dialer.callintent.CallSpecificAppData;
32import com.android.dialer.common.LogUtil;
33
34/** A ContactTile displays a contact's picture and name */
35public abstract class ContactTileView extends FrameLayout {
36
37  private static final String TAG = ContactTileView.class.getSimpleName();
38  protected Listener mListener;
39  private Uri mLookupUri;
40  private ImageView mPhoto;
41  private TextView mName;
42  private ContactPhotoManager mPhotoManager = null;
43
44  public ContactTileView(Context context, AttributeSet attrs) {
45    super(context, attrs);
46  }
47
48  @Override
49  protected void onFinishInflate() {
50    super.onFinishInflate();
51    mName = (TextView) findViewById(R.id.contact_tile_name);
52    mPhoto = (ImageView) findViewById(R.id.contact_tile_image);
53
54    OnClickListener listener = createClickListener();
55    setOnClickListener(listener);
56  }
57
58  protected OnClickListener createClickListener() {
59    return new OnClickListener() {
60      @Override
61      public void onClick(View v) {
62        if (mListener == null) {
63          return;
64        }
65        CallSpecificAppData callSpecificAppData =
66            CallSpecificAppData.newBuilder()
67                .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
68                .build();
69        mListener.onContactSelected(
70            getLookupUri(),
71            MoreContactUtils.getTargetRectFromView(ContactTileView.this),
72            callSpecificAppData);
73      }
74    };
75  }
76
77  public void setPhotoManager(ContactPhotoManager photoManager) {
78    mPhotoManager = photoManager;
79  }
80
81  /**
82   * Populates the data members to be displayed from the fields in {@link
83   * com.android.contacts.common.list.ContactEntry}
84   */
85  public void loadFromContact(ContactEntry entry) {
86
87    if (entry != null) {
88      mName.setText(getNameForView(entry));
89      mLookupUri = entry.lookupUri;
90
91      setVisibility(View.VISIBLE);
92
93      if (mPhotoManager != null) {
94        DefaultImageRequest request = getDefaultImageRequest(entry.namePrimary, entry.lookupKey);
95        configureViewForImage(entry.photoUri == null);
96        if (mPhoto != null) {
97          mPhotoManager.loadPhoto(
98              mPhoto,
99              entry.photoUri,
100              getApproximateImageSize(),
101              isDarkTheme(),
102              isContactPhotoCircular(),
103              request);
104
105
106        }
107      } else {
108        LogUtil.w(TAG, "contactPhotoManager not set");
109      }
110    } else {
111      setVisibility(View.INVISIBLE);
112    }
113  }
114
115  public void setListener(Listener listener) {
116    mListener = listener;
117  }
118
119  public Uri getLookupUri() {
120    return mLookupUri;
121  }
122
123  /**
124   * Returns the string that should actually be displayed as the contact's name. Subclasses can
125   * override this to return formatted versions of the name - i.e. first name only.
126   */
127  protected String getNameForView(ContactEntry contactEntry) {
128    return contactEntry.namePrimary;
129  }
130
131  /**
132   * Implemented by subclasses to estimate the size of the picture. This can return -1 if only a
133   * thumbnail is shown anyway
134   */
135  protected abstract int getApproximateImageSize();
136
137  protected abstract boolean isDarkTheme();
138
139  /**
140   * Implemented by subclasses to reconfigure the view's layout and subviews, based on whether or
141   * not the contact has a user-defined photo.
142   *
143   * @param isDefaultImage True if the contact does not have a user-defined contact photo (which
144   *     means a default contact image will be applied by the {@link ContactPhotoManager}
145   */
146  protected void configureViewForImage(boolean isDefaultImage) {
147    // No-op by default.
148  }
149
150  /**
151   * Implemented by subclasses to allow them to return a {@link DefaultImageRequest} with the
152   * various image parameters defined to match their own layouts.
153   *
154   * @param displayName The display name of the contact
155   * @param lookupKey The lookup key of the contact
156   * @return A {@link DefaultImageRequest} object with each field configured by the subclass as
157   *     desired, or {@code null}.
158   */
159  protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
160    return new DefaultImageRequest(displayName, lookupKey, isContactPhotoCircular());
161  }
162
163  /**
164   * Whether contact photo should be displayed as a circular image. Implemented by subclasses so
165   * they can change which drawables to fetch.
166   */
167  protected boolean isContactPhotoCircular() {
168    return true;
169  }
170
171  public interface Listener {
172
173    /** Notification that the contact was selected; no specific action is dictated. */
174    void onContactSelected(
175        Uri contactLookupUri, Rect viewRect, CallSpecificAppData callSpecificAppData);
176
177    /** Notification that the specified number is to be called. */
178    void onCallNumberDirectly(String phoneNumber, CallSpecificAppData callSpecificAppData);
179  }
180}
181