blob: afc504008eb8dae2cf13092e968fabfe0afcb06e [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.dialer.ui.contact;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.android.car.apps.common.BackgroundImageView;
import com.android.car.apps.common.LetterTileDrawable;
import com.android.car.apps.common.util.ViewUtils;
import com.android.car.dialer.R;
import com.android.car.dialer.log.L;
import com.android.car.dialer.telecom.UiCallManager;
import com.android.car.dialer.ui.view.ContactAvatarOutputlineProvider;
import com.android.car.telephony.common.Contact;
import com.android.car.telephony.common.PhoneNumber;
import com.android.car.telephony.common.PostalAddress;
import com.android.car.telephony.common.TelecomUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import java.util.List;
/**
* ViewHolder for {@link ContactDetailsFragment}.
*/
class ContactDetailsViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "CD.ContactDetailsVH";
// Applies to all
@NonNull
private final TextView mTitle;
// Applies to header
@Nullable
private final ImageView mAvatarView;
@Nullable
private final BackgroundImageView mBackgroundImageView;
// Applies to phone number items and address items
@Nullable
private final TextView mText;
// Applies to phone number items
@Nullable
private final View mCallActionView;
@Nullable
private final ImageView mFavoriteActionView;
// Applies to address items
@Nullable
private final View mAddressView;
@Nullable
private final View mNavigationButton;
@NonNull
private final ContactDetailsAdapter.PhoneNumberPresenter mPhoneNumberPresenter;
ContactDetailsViewHolder(
View v,
@NonNull ContactDetailsAdapter.PhoneNumberPresenter phoneNumberPresenter) {
super(v);
mCallActionView = v.findViewById(R.id.call_action_id);
mFavoriteActionView = v.findViewById(R.id.contact_details_favorite_button);
mAddressView = v.findViewById(R.id.address_button);
mNavigationButton = v.findViewById(R.id.navigation_button);
mTitle = v.findViewById(R.id.title);
mText = v.findViewById(R.id.text);
mAvatarView = v.findViewById(R.id.avatar);
if (mAvatarView != null) {
mAvatarView.setOutlineProvider(ContactAvatarOutputlineProvider.get());
}
mBackgroundImageView = v.findViewById(R.id.background_image);
mPhoneNumberPresenter = phoneNumberPresenter;
}
public void bind(Context context, Contact contact) {
if (contact == null) {
ViewUtils.setText(mTitle, R.string.error_contact_deleted);
LetterTileDrawable letterTile = TelecomUtils.createLetterTile(context, null, null);
if (mAvatarView != null) {
mAvatarView.setImageDrawable(letterTile);
}
if (mBackgroundImageView != null) {
mBackgroundImageView.setAlpha(context.getResources().getFloat(
R.dimen.config_background_image_error_alpha));
mBackgroundImageView.setBackgroundColor(letterTile.getColor());
}
return;
}
ViewUtils.setText(mTitle, contact.getDisplayName());
if (mAvatarView == null && mBackgroundImageView == null) {
return;
}
LetterTileDrawable letterTile = TelecomUtils.createLetterTile(context,
contact.getInitials(), contact.getDisplayName());
Glide.with(context)
.load(contact.getAvatarUri())
.apply(new RequestOptions().centerCrop().error(letterTile))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model,
Target<Drawable> target, boolean isFirstResource) {
if (mBackgroundImageView != null) {
mBackgroundImageView.setAlpha(context.getResources().getFloat(
R.dimen.config_background_image_error_alpha));
mBackgroundImageView.setBackgroundColor(letterTile.getColor());
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model,
Target<Drawable> target, DataSource dataSource,
boolean isFirstResource) {
if (mBackgroundImageView != null) {
mBackgroundImageView.setAlpha(context.getResources().getFloat(
R.dimen.config_background_image_alpha));
mBackgroundImageView.setBackgroundDrawable(resource, false);
}
return false;
}
}).into(mAvatarView);
}
public void bind(Context context, Contact contact, PhoneNumber phoneNumber) {
mTitle.setText(phoneNumber.getRawNumber());
// Present the phone number type and local favorite state.
CharSequence readableLabel = phoneNumber.getReadableLabel(context.getResources());
CharSequence favoriteLabel = phoneNumber.isFavorite() ? context.getString(
R.string.local_favorite_number_description, readableLabel) : readableLabel;
if (phoneNumber.isPrimary()) {
mText.setText(context.getString(R.string.primary_number_description, favoriteLabel));
mText.setTextAppearance(R.style.TextAppearance_DefaultNumberLabel);
} else {
mText.setText(favoriteLabel);
mText.setTextAppearance(R.style.TextAppearance_ContactDetailsListSubtitle);
}
mCallActionView.setOnClickListener(
v -> UiCallManager.get().placeCall(phoneNumber.getRawNumber()));
if (phoneNumber.isFavorite() || !contact.isStarred()) {
// If the phone number is marked as favorite locally, enable the action button to
// allow users to remove from local favorites.
// If the phone number is not a local favorite or a favorite from phone, allow users
// to mark it as favorite locally.
ViewUtils.setActivated(mFavoriteActionView, phoneNumber.isFavorite());
ViewUtils.setEnabled(mFavoriteActionView, true);
ViewUtils.setOnClickListener(mFavoriteActionView, v -> {
mPhoneNumberPresenter.onClick(contact, phoneNumber);
mFavoriteActionView.setActivated(!mFavoriteActionView.isActivated());
});
} else {
// The contact is favorite contact downloaded from phone. Disable the favorite action
// button so the phone numbers can not be marked as favorite locally as it is not
// necessary.
ViewUtils.setActivated(mFavoriteActionView, false);
ViewUtils.setEnabled(mFavoriteActionView, false);
ViewUtils.setOnClickListener(mFavoriteActionView, null);
}
}
public void bind(Context context, @NonNull PostalAddress postalAddress) {
String address = postalAddress.getFormattedAddress();
Resources resources = context.getResources();
mTitle.setText(address);
ViewUtils.setText(mText, postalAddress.getReadableLabel(resources));
mAddressView.setOnClickListener(
v -> openMapWithMapIntent(context, postalAddress.getAddressIntent(resources)));
Intent intent = postalAddress.getNavigationIntent(resources);
List<ResolveInfo> infos = context.getPackageManager().queryIntentActivities(intent, 0);
if (infos.size() > 0) {
mNavigationButton.setVisibility(View.VISIBLE);
mNavigationButton.setOnClickListener(v -> openMapWithMapIntent(context, intent));
} else {
mNavigationButton.setVisibility(View.GONE);
}
}
private void openMapWithMapIntent(Context context, Intent mapIntent) {
try {
context.startActivity(mapIntent);
} catch (ActivityNotFoundException e) {
L.w(TAG, "Map is not available.");
}
}
}