1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2011 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.contacts.common.list;
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.Context;
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Rect;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.net.Uri;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.util.AttributeSet;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.view.View;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.FrameLayout;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.ImageView;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.widget.TextView;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactPhotoManager;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.MoreContactUtils;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.R;
302f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.callintent.CallInitiationType;
312f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.callintent.CallSpecificAppData;
322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport com.android.dialer.common.LogUtil;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/** A ContactTile displays a contact's picture and name */
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic abstract class ContactTileView extends FrameLayout {
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String TAG = ContactTileView.class.getSimpleName();
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected Listener mListener;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Uri mLookupUri;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ImageView mPhoto;
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private TextView mName;
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private ContactPhotoManager mPhotoManager = null;
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public ContactTileView(Context context, AttributeSet attrs) {
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super(context, attrs);
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected void onFinishInflate() {
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    super.onFinishInflate();
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mName = (TextView) findViewById(R.id.contact_tile_name);
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPhoto = (ImageView) findViewById(R.id.contact_tile_image);
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    OnClickListener listener = createClickListener();
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    setOnClickListener(listener);
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected OnClickListener createClickListener() {
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return new OnClickListener() {
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Override
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      public void onClick(View v) {
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (mListener == null) {
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          return;
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
652f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        CallSpecificAppData callSpecificAppData =
662f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            CallSpecificAppData.newBuilder()
672f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                .setCallInitiationType(CallInitiationType.Type.SPEED_DIAL)
682f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian                .build();
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mListener.onContactSelected(
702f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            getLookupUri(),
712f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            MoreContactUtils.getTargetRectFromView(ContactTileView.this),
722f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            callSpecificAppData);
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    };
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setPhotoManager(ContactPhotoManager photoManager) {
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPhotoManager = photoManager;
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Populates the data members to be displayed from the fields in {@link
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * com.android.contacts.common.list.ContactEntry}
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void loadFromContact(ContactEntry entry) {
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (entry != null) {
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mName.setText(getNameForView(entry));
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mLookupUri = entry.lookupUri;
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      setVisibility(View.VISIBLE);
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mPhotoManager != null) {
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        DefaultImageRequest request = getDefaultImageRequest(entry.namePrimary, entry.lookupKey);
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        configureViewForImage(entry.photoUri == null);
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        if (mPhoto != null) {
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          mPhotoManager.loadPhoto(
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              mPhoto,
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              entry.photoUri,
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              getApproximateImageSize(),
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              isDarkTheme(),
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              isContactPhotoCircular(),
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian              request);
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        }
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
1082f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        LogUtil.w(TAG, "contactPhotoManager not set");
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      setVisibility(View.INVISIBLE);
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setListener(Listener listener) {
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mListener = listener;
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Uri getLookupUri() {
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mLookupUri;
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Returns the string that should actually be displayed as the contact's name. Subclasses can
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * override this to return formatted versions of the name - i.e. first name only.
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected String getNameForView(ContactEntry contactEntry) {
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return contactEntry.namePrimary;
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Implemented by subclasses to estimate the size of the picture. This can return -1 if only a
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * thumbnail is shown anyway
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected abstract int getApproximateImageSize();
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected abstract boolean isDarkTheme();
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Implemented by subclasses to reconfigure the view's layout and subviews, based on whether or
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * not the contact has a user-defined photo.
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param isDefaultImage True if the contact does not have a user-defined contact photo (which
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     means a default contact image will be applied by the {@link ContactPhotoManager}
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected void configureViewForImage(boolean isDefaultImage) {
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // No-op by default.
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Implemented by subclasses to allow them to return a {@link DefaultImageRequest} with the
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * various image parameters defined to match their own layouts.
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param displayName The display name of the contact
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param lookupKey The lookup key of the contact
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return A {@link DefaultImageRequest} object with each field configured by the subclass as
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     desired, or {@code null}.
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return new DefaultImageRequest(displayName, lookupKey, isContactPhotoCircular());
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Whether contact photo should be displayed as a circular image. Implemented by subclasses so
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * they can change which drawables to fetch.
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  protected boolean isContactPhotoCircular() {
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return true;
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public interface Listener {
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    /** Notification that the contact was selected; no specific action is dictated. */
1742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    void onContactSelected(
1752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        Uri contactLookupUri, Rect viewRect, CallSpecificAppData callSpecificAppData);
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    /** Notification that the specified number is to be called. */
1782f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    void onCallNumberDirectly(String phoneNumber, CallSpecificAppData callSpecificAppData);
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
181