1 /*
2 
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package com.android.dialer.app.list;
18 
19 import android.content.ClipData;
20 import android.content.Context;
21 import android.text.TextUtils;
22 import android.util.AttributeSet;
23 import android.view.View;
24 import android.widget.ImageView;
25 import com.android.contacts.common.ContactPhotoManager;
26 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
27 import com.android.contacts.common.MoreContactUtils;
28 import com.android.contacts.common.list.ContactEntry;
29 import com.android.contacts.common.list.ContactTileView;
30 import com.android.dialer.app.R;
31 
32 /**
33  * A light version of the {@link com.android.contacts.common.list.ContactTileView} that is used in
34  * Dialtacts for frequently called contacts. Slightly different behavior from superclass when you
35  * tap it, you want to call the frequently-called number for the contact, even if that is not the
36  * default number for that contact. This abstract class is the super class to both the row and tile
37  * view.
38  */
39 public abstract class PhoneFavoriteTileView extends ContactTileView {
40 
41   // Constant to pass to the drag event so that the drag action only happens when a phone favorite
42   // tile is long pressed.
43   static final String DRAG_PHONE_FAVORITE_TILE = "PHONE_FAVORITE_TILE";
44   private static final String TAG = PhoneFavoriteTileView.class.getSimpleName();
45   private static final boolean DEBUG = false;
46   // These parameters instruct the photo manager to display the default image/letter at 70% of
47   // its normal size, and vertically offset upwards 12% towards the top of the letter tile, to
48   // make room for the contact name and number label at the bottom of the image.
49   private static final float DEFAULT_IMAGE_LETTER_OFFSET = -0.12f;
50   private static final float DEFAULT_IMAGE_LETTER_SCALE = 0.70f;
51   // Dummy clip data object that is attached to drag shadows so that text views
52   // don't crash with an NPE if the drag shadow is released in their bounds
53   private static final ClipData EMPTY_CLIP_DATA = ClipData.newPlainText("", "");
54   /** View that contains the transparent shadow that is overlaid on top of the contact image. */
55   private View mShadowOverlay;
56   /** Users' most frequent phone number. */
57   private String mPhoneNumberString;
58 
PhoneFavoriteTileView(Context context, AttributeSet attrs)59   public PhoneFavoriteTileView(Context context, AttributeSet attrs) {
60     super(context, attrs);
61   }
62 
63   @Override
onFinishInflate()64   protected void onFinishInflate() {
65     super.onFinishInflate();
66     mShadowOverlay = findViewById(R.id.shadow_overlay);
67 
68     setOnLongClickListener(
69         new OnLongClickListener() {
70           @Override
71           public boolean onLongClick(View v) {
72             final PhoneFavoriteTileView view = (PhoneFavoriteTileView) v;
73             // NOTE The drag shadow is handled in the ListView.
74             view.startDrag(
75                 EMPTY_CLIP_DATA, new View.DragShadowBuilder(), DRAG_PHONE_FAVORITE_TILE, 0);
76             return true;
77           }
78         });
79   }
80 
81   @Override
loadFromContact(ContactEntry entry)82   public void loadFromContact(ContactEntry entry) {
83     super.loadFromContact(entry);
84     // Set phone number to null in case we're reusing the view.
85     mPhoneNumberString = null;
86     if (entry != null) {
87       // Grab the phone-number to call directly. See {@link onClick()}.
88       mPhoneNumberString = entry.phoneNumber;
89 
90       // If this is a blank entry, don't show anything.
91       // TODO krelease: Just hide the view for now. For this to truly look like an empty row
92       // the entire ContactTileRow needs to be hidden.
93       if (entry == ContactEntry.BLANK_ENTRY) {
94         setVisibility(View.INVISIBLE);
95       } else {
96         final ImageView starIcon = (ImageView) findViewById(R.id.contact_star_icon);
97         starIcon.setVisibility(entry.isFavorite ? View.VISIBLE : View.GONE);
98         setVisibility(View.VISIBLE);
99       }
100     }
101   }
102 
103   @Override
isDarkTheme()104   protected boolean isDarkTheme() {
105     return false;
106   }
107 
108   @Override
createClickListener()109   protected OnClickListener createClickListener() {
110     return new OnClickListener() {
111       @Override
112       public void onClick(View v) {
113         if (mListener == null) {
114           return;
115         }
116         if (TextUtils.isEmpty(mPhoneNumberString)) {
117           // Copy "superclass" implementation
118           mListener.onContactSelected(
119               getLookupUri(), MoreContactUtils.getTargetRectFromView(PhoneFavoriteTileView.this));
120         } else {
121           // When you tap a frequently-called contact, you want to
122           // call them at the number that you usually talk to them
123           // at (i.e. the one displayed in the UI), regardless of
124           // whether that's their default number.
125           mListener.onCallNumberDirectly(mPhoneNumberString);
126         }
127       }
128     };
129   }
130 
131   @Override
132   protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
133     return new DefaultImageRequest(
134         displayName,
135         lookupKey,
136         ContactPhotoManager.TYPE_DEFAULT,
137         DEFAULT_IMAGE_LETTER_SCALE,
138         DEFAULT_IMAGE_LETTER_OFFSET,
139         false);
140   }
141 
142   @Override
143   protected void configureViewForImage(boolean isDefaultImage) {
144     // Hide the shadow overlay if the image is a default image (i.e. colored letter tile)
145     if (mShadowOverlay != null) {
146       mShadowOverlay.setVisibility(isDefaultImage ? View.GONE : View.VISIBLE);
147     }
148   }
149 
150   @Override
151   protected boolean isContactPhotoCircular() {
152     // Unlike Contacts' tiles, the Dialer's favorites tiles are square.
153     return false;
154   }
155 }
156