summaryrefslogtreecommitdiff
path: root/InCallUI/src/com/android/incallui
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2015-10-21 21:15:30 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-10-21 21:15:30 +0000
commit3867a0ac286d0c9cc457b81e9db5d36019e786e4 (patch)
tree8a97e9fea8fbcb2e5d136272b629969b487ee077 /InCallUI/src/com/android/incallui
parent826a1350722e9da5867430c217b974aae225adb8 (diff)
parent687390732d6253903141d89d734113373d0e3c13 (diff)
Merge "New layout for business call context." into ub-contactsdialer-a-dev
Diffstat (limited to 'InCallUI/src/com/android/incallui')
-rw-r--r--InCallUI/src/com/android/incallui/CallCardFragment.java121
-rw-r--r--InCallUI/src/com/android/incallui/CallCardPresenter.java32
-rw-r--r--InCallUI/src/com/android/incallui/InCallContactInteractions.java35
3 files changed, 144 insertions, 44 deletions
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index b276a9569..fa4e8b4f1 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -21,13 +21,18 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Trace;
import android.os.Handler;
import android.os.Looper;
+import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
+import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.telecom.DisconnectCause;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
@@ -46,6 +51,7 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
@@ -133,6 +139,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
// Container view that houses the primary call information
private ViewGroup mPrimaryCallInfo;
private View mCallButtonsContainer;
+ private ImageView mPhotoSmall;
// Secondary caller info
private View mSecondaryCallInfo;
@@ -145,10 +152,11 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
// Call card content
private View mCallCardContent;
- private ImageView mPhoto;
+ private ImageView mPhotoLarge;
private View mContactContext;
private TextView mContactContextTitle;
private ListView mContactContextListView;
+ private LinearLayout mContactContextListHeaders;
private View mManageConferenceCallButton;
@@ -246,16 +254,21 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mSecondaryCallInfo = view.findViewById(R.id.secondary_call_info);
mSecondaryCallProviderInfo = view.findViewById(R.id.secondary_call_provider_info);
mCallCardContent = view.findViewById(R.id.call_card_content);
- mPhoto = (ImageView) view.findViewById(R.id.photo);
- mPhoto.setOnClickListener(new View.OnClickListener() {
+ mPhotoLarge = (ImageView) view.findViewById(R.id.photoLarge);
+ mPhotoLarge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getPresenter().onContactPhotoClick();
}
});
+
mContactContext = view.findViewById(R.id.contact_context);
mContactContextTitle = (TextView) view.findViewById(R.id.contactContextTitle);
mContactContextListView = (ListView) view.findViewById(R.id.contactContextInfo);
+ // This layout stores all the list header layouts so they can be easily removed.
+ mContactContextListHeaders = new LinearLayout(getView().getContext());
+ mContactContextListView.addHeaderView(mContactContextListHeaders);
+
mCallStateIcon = (ImageView) view.findViewById(R.id.callStateIcon);
mCallStateVideoCallIcon = (ImageView) view.findViewById(R.id.videoCallIcon);
mCallStateLabel = (TextView) view.findViewById(R.id.callStateLabel);
@@ -267,6 +280,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
mPrimaryCallCardContainer = view.findViewById(R.id.primary_call_info_container);
mPrimaryCallInfo = (ViewGroup) view.findViewById(R.id.primary_call_banner);
mCallButtonsContainer = view.findViewById(R.id.callButtonFragment);
+ mPhotoSmall = (ImageView) view.findViewById(R.id.photoSmall);
+ mPhotoSmall.setVisibility(View.GONE);
mInCallMessageLabel = (TextView) view.findViewById(R.id.connectionServiceMessage);
mProgressSpinner = view.findViewById(R.id.progressSpinner);
@@ -334,17 +349,23 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
@Override
- public void setContactContext(String title, ListAdapter listAdapter) {
- mContactContextTitle.setText(title);
+ public void setContactContextTitle(View headerView) {
+ mContactContextListHeaders.removeAllViews();
+ mContactContextListHeaders.addView(headerView);
+ }
+
+ @Override
+ public void setContactContextContent(ListAdapter listAdapter) {
mContactContextListView.setAdapter(listAdapter);
}
@Override
public void showContactContext(boolean show) {
- mPhoto.setVisibility(show ? View.GONE : View.VISIBLE);
- mPrimaryCallCardContainer.setElevation(
- show ? 0 : getResources().getDimension(R.dimen.primary_call_elevation));
- mContactContext.setVisibility(show ? View.VISIBLE : View.GONE);
+ showImageView(mPhotoLarge, !show);
+ showImageView(mPhotoSmall, show);
+ mPrimaryCallCardContainer.setElevation(
+ show ? 0 : getResources().getDimension(R.dimen.primary_call_elevation));
+ mContactContext.setVisibility(show ? View.VISIBLE : View.GONE);
}
/**
@@ -498,7 +519,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
@Override
public void setPrimaryImage(Drawable image, boolean isVisible) {
if (image != null) {
- setDrawableToImageView(mPhoto, image, isVisible);
+ setDrawableToImageViews(image);
+ showImageView(mPhotoLarge, isVisible);
}
}
@@ -560,7 +582,8 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
showInternetCallLabel(isSipCall);
- setDrawableToImageView(mPhoto, photo, isContactPhotoShown);
+ setDrawableToImageViews(photo);
+ showImageView(mPhotoLarge, isContactPhotoShown);
}
@Override
@@ -620,7 +643,7 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
// photo is hidden when the incoming video surface is shown.
// The contact photo visibility can also change in setPrimary().
boolean showContactPhoto = !VideoCallPresenter.showIncomingVideo(videoState, state);
- mPhoto.setVisibility(showContactPhoto ? View.VISIBLE : View.GONE);
+ mPhotoLarge.setVisibility(showContactPhoto ? View.VISIBLE : View.GONE);
// Check if the call subject is showing -- if it is, we want to bypass showing the call
// state.
@@ -807,33 +830,87 @@ public class CallCardFragment extends BaseFragment<CallCardPresenter, CallCardPr
}
}
- private void setDrawableToImageView(ImageView view, Drawable photo, boolean isVisible) {
+ /**
+ * Set all the ImageViews to the same photo. Currently there are 2 photo views: the large one
+ * (which fills about the bottom half of the screen) and the small one, which displays as a
+ * circle next to the primary contact info. This method does not handle whether the ImageView
+ * is shown or not.
+ *
+ * @param photo The photo to set for the image views.
+ */
+ private void setDrawableToImageViews(Drawable photo) {
if (photo == null) {
- photo = ContactInfoCache.getInstance(
- view.getContext()).getDefaultContactPhotoDrawable();
+ photo = ContactInfoCache.getInstance(getView().getContext())
+ .getDefaultContactPhotoDrawable();
}
- if (mPrimaryPhotoDrawable == photo) {
+ if (mPrimaryPhotoDrawable == photo){
return;
}
mPrimaryPhotoDrawable = photo;
- final Drawable current = view.getDrawable();
- if (current == null) {
- view.setImageDrawable(photo);
+ mPhotoLarge.setImageDrawable(photo);
+
+ // Modify the drawable to be round for the smaller ImageView.
+ Bitmap bitmap = drawableToBitmap(photo);
+ if (bitmap != null) {
+ final RoundedBitmapDrawable drawable =
+ RoundedBitmapDrawableFactory.create(getResources(), bitmap);
+ drawable.setAntiAlias(true);
+ drawable.setCornerRadius(bitmap.getHeight() / 2);
+ photo = drawable;
+ }
+ mPhotoSmall.setImageDrawable(photo);
+ }
+
+ /**
+ * Helper method for image view to handle animations.
+ *
+ * @param view The image view to show or hide.
+ * @param isVisible {@code true} if we want to show the image, {@code false} to hide it.
+ */
+ private void showImageView(ImageView view, boolean isVisible) {
+ if (view.getDrawable() == null) {
if (isVisible) {
AnimUtils.fadeIn(mElapsedTime, AnimUtils.DEFAULT_DURATION);
}
} else {
- // Cross fading is buggy and not noticable due to the multiple calls to this method
- // that switch drawables in the middle of the cross-fade animations. Just set the
+ // Cross fading is buggy and not noticeable due to the multiple calls to this method
+ // that switch drawables in the middle of the cross-fade animations. Just show the
// photo directly instead.
- view.setImageDrawable(photo);
view.setVisibility(isVisible ? View.VISIBLE : View.GONE);
}
}
/**
+ * Converts a drawable into a bitmap.
+ *
+ * @param drawable the drawable to be converted.
+ */
+ public static Bitmap drawableToBitmap(Drawable drawable) {
+ Bitmap bitmap;
+ if (drawable instanceof BitmapDrawable) {
+ bitmap = ((BitmapDrawable) drawable).getBitmap();
+ } else {
+ if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
+ // Needed for drawables that are just a colour.
+ bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ } else {
+ bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
+ drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ }
+
+ Log.i(TAG, "Created bitmap with width " + bitmap.getWidth() + ", height "
+ + bitmap.getHeight());
+
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ }
+ return bitmap;
+ }
+
+ /**
* Gets the call state label based on the state of the call or cause of disconnect.
*
* Additional labels are applied as follows:
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 9c47a93d7..aa022f448 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.location.Address;
import android.net.Uri;
import android.os.Bundle;
import android.telecom.Call.Details;
@@ -35,6 +36,7 @@ import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
+import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.ListAdapter;
@@ -227,7 +229,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
secondary = getCallToDisplay(callList, primary, true);
}
- if (mInCallContactInteractions != null) {
+ if (mInCallContactInteractions != null &&
+ (oldState == InCallState.INCOMING || newState == InCallState.INCOMING)) {
ui.showContactContext(newState != InCallState.INCOMING);
}
@@ -593,14 +596,18 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
private void updateContactInteractions() {
if (mPrimary != null && mPrimaryContactInfo != null
&& mPrimaryContactInfo.locationAddress != null) {
- setInCallContactInteractionsType(true);
+
+ // TODO: This is hardcoded to "isBusiness" because functionality to differentiate
+ // between business and personal has not yet been added.
+ if (setInCallContactInteractionsType(true /* isBusiness */)) {
+ getUi().setContactContextTitle(
+ mInCallContactInteractions.getBusinessListHeaderView());
+ }
mInCallContactInteractions.setBusinessInfo(
mPrimaryContactInfo.locationAddress,
mDistanceHelper.calculateDistance(mPrimaryContactInfo.locationAddress));
- getUi().setContactContext(
- null,
- mInCallContactInteractions.getListAdapter());
+ getUi().setContactContextContent(mInCallContactInteractions.getListAdapter());
getUi().showContactContext(mPrimary.getState() != State.INCOMING);
}
}
@@ -610,14 +617,18 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
*
* @param isBusiness {@code true} if the interaction is a business interaction, {@code false} if
* it is a personal contact.
+ *
+ * @return {@code true} if this is a new type of contact interaction (business or personal).
+ * {@code false} if it hasn't changed.
*/
- private void setInCallContactInteractionsType(boolean isBusiness) {
+ private boolean setInCallContactInteractionsType(boolean isBusiness) {
if (mInCallContactInteractions == null) {
mInCallContactInteractions =
new InCallContactInteractions(mContext, isBusiness);
- } else {
- mInCallContactInteractions.setIsBusiness(isBusiness);
+ return true;
}
+
+ return mInCallContactInteractions.switchContactType(isBusiness);
}
private void updateContactEntry(ContactCacheEntry entry, boolean isPrimary) {
@@ -741,6 +752,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
mPrimaryContactInfo.photo,
mPrimaryContactInfo.isSipCall,
showContactPhoto);
+
+ updateContactInteractions();
} else {
// Clear the primary display info.
ui.setPrimary(null, null, false, null, null, false, false);
@@ -1031,7 +1044,8 @@ public class CallCardPresenter extends Presenter<CallCardPresenter.CallCardUi>
public interface CallCardUi extends Ui {
void setVisible(boolean on);
- void setContactContext(String title, ListAdapter listAdapter);
+ void setContactContextTitle(View listHeaderView);
+ void setContactContextContent(ListAdapter listAdapter);
void showContactContext(boolean show);
void setCallCardVisible(boolean visible);
void setPrimary(String number, String name, boolean nameIsNumber, String label,
diff --git a/InCallUI/src/com/android/incallui/InCallContactInteractions.java b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
index 6f30720c2..04caecc13 100644
--- a/InCallUI/src/com/android/incallui/InCallContactInteractions.java
+++ b/InCallUI/src/com/android/incallui/InCallContactInteractions.java
@@ -44,10 +44,14 @@ public class InCallContactInteractions {
private Context mContext;
private InCallContactInteractionsListAdapter mListAdapter;
private boolean mIsBusiness;
+ private View mBusinessHeaderView;
+ private LayoutInflater mInflater;
public InCallContactInteractions(Context context, boolean isBusiness) {
mContext = context;
- setIsBusiness(isBusiness);
+ mInflater = (LayoutInflater)
+ context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ switchContactType(isBusiness);
}
public InCallContactInteractionsListAdapter getListAdapter() {
@@ -55,17 +59,22 @@ public class InCallContactInteractions {
}
/**
- * Resets the "isBusiness" value, also recreates the list adapter with the resource
- * corresponding to the new isBusiness value.
+ * Switches the "isBusiness" value, if applicable. Recreates the list adapter with the resource
+ * corresponding to the new isBusiness value if the "isBusiness" value is switched.
+ *
* @param isBusiness Whether or not the contact is a business.
+ *
+ * @return {@code true} if a new list adapter was created, {@code} otherwise.
*/
- public void setIsBusiness(boolean isBusiness) {
+ public boolean switchContactType(boolean isBusiness) {
if (mIsBusiness != isBusiness || mListAdapter == null) {
mIsBusiness = isBusiness;
mListAdapter = new InCallContactInteractionsListAdapter(mContext,
mIsBusiness ? R.layout.business_context_info_list_item
: R.layout.person_context_info_list_item);
+ return true;
}
+ return false;
}
public void setBusinessInfo(Address address, float distance) {
@@ -73,14 +82,17 @@ public class InCallContactInteractions {
mListAdapter.addAll(constructBusinessContextInfo(address, distance));
}
+ public View getBusinessListHeaderView() {
+ if (mBusinessHeaderView == null) {
+ mBusinessHeaderView = mInflater.inflate(
+ R.layout.business_contact_context_list_header, null);
+ }
+ return mBusinessHeaderView;
+ }
+
private List<ContactContextInfo> constructBusinessContextInfo(Address address, float distance) {
List<ContactContextInfo> info = new ArrayList<ContactContextInfo>();
- BusinessContextInfo headerInfo = new BusinessContextInfo();
- headerInfo.iconId = R.drawable.ic_business_white_24dp;
- headerInfo.heading = getContactContextTitle();
- info.add(headerInfo);
-
//TODO: hours of operation information
// Location information
@@ -192,10 +204,7 @@ public class InCallContactInteractions {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- LayoutInflater inflater = (LayoutInflater)
- getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- View listItem = inflater.inflate(mResId, null);
+ View listItem = mInflater.inflate(mResId, null);
ContactContextInfo item = getItem(position);
if (item == null) {