blob: 7f33f462e303c57b739c80616d268ac51019ecb7 [file] [log] [blame]
/*
* Copyright (C) 2017 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.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModelProviders;
import com.android.car.apps.common.LetterTileDrawable;
import com.android.car.arch.common.FutureData;
import com.android.car.dialer.R;
import com.android.car.dialer.ui.common.DialerListBaseFragment;
import com.android.car.telephony.common.Contact;
import com.android.car.telephony.common.PhoneNumber;
import com.android.car.telephony.common.TelecomUtils;
import com.android.car.ui.toolbar.Toolbar;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
/**
* A fragment that shows the name of the contact, the photo and all listed phone numbers. It is
* primarily used to respond to the results of search queries but supplyig it with the content://
* uri of a contact should work too.
*/
public class ContactDetailsFragment extends DialerListBaseFragment implements
ContactDetailsAdapter.PhoneNumberPresenter {
private static final String TAG = "CD.ContactDetailsFragment";
public static final String FRAGMENT_TAG = "CONTACT_DETAIL_FRAGMENT_TAG";
// Key to load and save the contact entity instance.
private static final String KEY_CONTACT_ENTITY = "ContactEntity";
private Contact mContact;
private LiveData<FutureData<Contact>> mContactDetailsLiveData;
private ContactDetailsViewModel mContactDetailsViewModel;
private boolean mShowActionBarView;
private boolean mShowActionBarAvatar;
/**
* Creates a new ContactDetailsFragment using a {@link Contact}.
*/
public static ContactDetailsFragment newInstance(Contact contact) {
ContactDetailsFragment fragment = new ContactDetailsFragment();
Bundle args = new Bundle();
args.putParcelable(KEY_CONTACT_ENTITY, contact);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContact = getArguments().getParcelable(KEY_CONTACT_ENTITY);
if (mContact == null && savedInstanceState != null) {
mContact = savedInstanceState.getParcelable(KEY_CONTACT_ENTITY);
}
mContactDetailsViewModel = ViewModelProviders.of(this).get(
ContactDetailsViewModel.class);
mContactDetailsLiveData = mContactDetailsViewModel.getContactDetails(mContact);
mShowActionBarView = getResources().getBoolean(
R.bool.config_show_contact_details_action_bar_view);
mShowActionBarAvatar = getResources().getBoolean(
R.bool.config_show_contact_details_action_bar_avatar);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ContactDetailsAdapter contactDetailsAdapter = new ContactDetailsAdapter(getContext(),
mContact, this);
getRecyclerView().setAdapter(contactDetailsAdapter);
mContactDetailsLiveData.observe(this, contact -> {
if (contact.isLoading()) {
showLoading();
} else {
onContactChanged(contact.getData());
contactDetailsAdapter.setContact(contact.getData());
showContent();
}
});
}
private void onContactChanged(Contact contact) {
getArguments().clear();
Toolbar toolbar = getActivity().findViewById(R.id.car_ui_toolbar);
// Null check to have unit tests to pass.
if (toolbar == null) {
return;
}
toolbar.setTitle(null);
toolbar.setLogo(null);
if (mShowActionBarView) {
toolbar.setTitle(contact == null ? getString(R.string.error_contact_deleted)
: contact.getDisplayName());
if (mShowActionBarAvatar) {
int avatarSize = getResources().getDimensionPixelSize(
R.dimen.contact_details_action_bar_avatar_size);
LetterTileDrawable letterTile = TelecomUtils.createLetterTile(getContext(),
contact == null ? null : contact.getInitials(),
contact == null ? null : contact.getDisplayName());
Uri avatarUri = contact == null ? null : contact.getAvatarUri();
Glide.with(this)
.asBitmap()
.load(avatarUri)
.apply(new RequestOptions().override(avatarSize).error(letterTile))
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap bitmap,
Transition<? super Bitmap> transition) {
RoundedBitmapDrawable roundedBitmapDrawable = createFromBitmap(
bitmap, avatarSize);
toolbar.setLogo(roundedBitmapDrawable);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
RoundedBitmapDrawable roundedBitmapDrawable = createFromLetterTile(
letterTile, avatarSize);
toolbar.setLogo(roundedBitmapDrawable);
}
});
}
}
}
@Override
protected void setupToolbar(@NonNull Toolbar toolbar) {
toolbar.setState(getToolbarState());
toolbar.setMenuItems(null);
// Remove the tool bar background if we don't show the action bar view.
if (!mShowActionBarView) {
setShowToolbarBackground(false);
}
setToolbarHeight(toolbar);
}
@Override
public void onToolbarHeightChange(int toolbarHeight) {
if (mShowActionBarView) {
super.onToolbarHeightChange(toolbarHeight);
} else {
getRecyclerView().setScrollBarPadding(toolbarHeight, 0);
}
}
@Override
protected Toolbar.State getToolbarState() {
return Toolbar.State.SUBPAGE;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_CONTACT_ENTITY, mContact);
}
@Override
public void onClick(Contact contact, PhoneNumber phoneNumber) {
boolean isFavorite = phoneNumber.isFavorite();
if (isFavorite) {
mContactDetailsViewModel.removeFromFavorite(contact, phoneNumber);
} else {
mContactDetailsViewModel.addToFavorite(contact, phoneNumber);
}
}
private RoundedBitmapDrawable createFromLetterTile(LetterTileDrawable letterTileDrawable,
int avatarSize) {
return createFromBitmap(letterTileDrawable.toBitmap(avatarSize), avatarSize);
}
private RoundedBitmapDrawable createFromBitmap(Bitmap bitmap, int avatarSize) {
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(
getResources(), bitmap);
float radiusPercent = getResources()
.getFloat(R.dimen.contact_avatar_corner_radius_percent);
float radius = avatarSize * radiusPercent;
roundedBitmapDrawable.setCornerRadius(radius);
return roundedBitmapDrawable;
}
}