1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.calldetails; 18 19 import android.content.Context; 20 import android.support.annotation.CallSuper; 21 import android.support.annotation.MainThread; 22 import android.support.v7.widget.RecyclerView; 23 import android.support.v7.widget.RecyclerView.ViewHolder; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; 28 import com.android.dialer.calldetails.CallDetailsEntryViewHolder.CallDetailsEntryListener; 29 import com.android.dialer.calldetails.CallDetailsFooterViewHolder.DeleteCallDetailsListener; 30 import com.android.dialer.calldetails.CallDetailsFooterViewHolder.ReportCallIdListener; 31 import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallDetailsHeaderListener; 32 import com.android.dialer.calllogutils.CallTypeHelper; 33 import com.android.dialer.calllogutils.CallbackActionHelper; 34 import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; 35 import com.android.dialer.common.Assert; 36 import com.android.dialer.duo.DuoComponent; 37 import com.android.dialer.glidephotomanager.PhotoInfo; 38 39 /** 40 * Contains common logic shared between {@link OldCallDetailsAdapter} and {@link 41 * CallDetailsAdapter}. 42 */ 43 abstract class CallDetailsAdapterCommon extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 44 45 private static final int HEADER_VIEW_TYPE = 1; 46 private static final int CALL_ENTRY_VIEW_TYPE = 2; 47 private static final int FOOTER_VIEW_TYPE = 3; 48 49 private final CallDetailsEntryListener callDetailsEntryListener; 50 private final CallDetailsHeaderListener callDetailsHeaderListener; 51 private final ReportCallIdListener reportCallIdListener; 52 private final DeleteCallDetailsListener deleteCallDetailsListener; 53 private final CallTypeHelper callTypeHelper; 54 55 private CallDetailsEntries callDetailsEntries; 56 bindCallDetailsHeaderViewHolder( CallDetailsHeaderViewHolder viewHolder, int position)57 protected abstract void bindCallDetailsHeaderViewHolder( 58 CallDetailsHeaderViewHolder viewHolder, int position); 59 createCallDetailsHeaderViewHolder( View container, CallDetailsHeaderListener callDetailsHeaderListener)60 protected abstract CallDetailsHeaderViewHolder createCallDetailsHeaderViewHolder( 61 View container, CallDetailsHeaderListener callDetailsHeaderListener); 62 63 /** Returns the phone number of the call details. */ getNumber()64 protected abstract String getNumber(); 65 66 /** Returns the primary text shown on call details toolbar, usually contact name or number. */ getPrimaryText()67 protected abstract String getPrimaryText(); 68 69 /** Returns {@link PhotoInfo} of the contact. */ getPhotoInfo()70 protected abstract PhotoInfo getPhotoInfo(); 71 CallDetailsAdapterCommon( Context context, CallDetailsEntries callDetailsEntries, CallDetailsEntryListener callDetailsEntryListener, CallDetailsHeaderListener callDetailsHeaderListener, ReportCallIdListener reportCallIdListener, DeleteCallDetailsListener deleteCallDetailsListener)72 CallDetailsAdapterCommon( 73 Context context, 74 CallDetailsEntries callDetailsEntries, 75 CallDetailsEntryListener callDetailsEntryListener, 76 CallDetailsHeaderListener callDetailsHeaderListener, 77 ReportCallIdListener reportCallIdListener, 78 DeleteCallDetailsListener deleteCallDetailsListener) { 79 this.callDetailsEntries = callDetailsEntries; 80 this.callDetailsEntryListener = callDetailsEntryListener; 81 this.callDetailsHeaderListener = callDetailsHeaderListener; 82 this.reportCallIdListener = reportCallIdListener; 83 this.deleteCallDetailsListener = deleteCallDetailsListener; 84 this.callTypeHelper = 85 new CallTypeHelper(context.getResources(), DuoComponent.get(context).getDuo()); 86 } 87 88 @Override 89 @CallSuper onCreateViewHolder(ViewGroup parent, int viewType)90 public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 91 LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 92 switch (viewType) { 93 case HEADER_VIEW_TYPE: 94 return createCallDetailsHeaderViewHolder( 95 inflater.inflate(R.layout.contact_container, parent, false), callDetailsHeaderListener); 96 case CALL_ENTRY_VIEW_TYPE: 97 return new CallDetailsEntryViewHolder( 98 inflater.inflate(R.layout.call_details_entry, parent, false), callDetailsEntryListener); 99 case FOOTER_VIEW_TYPE: 100 return new CallDetailsFooterViewHolder( 101 inflater.inflate(R.layout.call_details_footer, parent, false), 102 reportCallIdListener, 103 deleteCallDetailsListener); 104 default: 105 throw Assert.createIllegalStateFailException( 106 "No ViewHolder available for viewType: " + viewType); 107 } 108 } 109 110 @Override 111 @CallSuper onBindViewHolder(ViewHolder holder, int position)112 public void onBindViewHolder(ViewHolder holder, int position) { 113 if (position == 0) { // Header 114 bindCallDetailsHeaderViewHolder((CallDetailsHeaderViewHolder) holder, position); 115 } else if (position == getItemCount() - 1) { 116 ((CallDetailsFooterViewHolder) holder).setPhoneNumber(getNumber()); 117 } else { 118 CallDetailsEntryViewHolder viewHolder = (CallDetailsEntryViewHolder) holder; 119 CallDetailsEntry entry = callDetailsEntries.getEntries(position - 1); 120 viewHolder.setCallDetails( 121 getNumber(), 122 getPrimaryText(), 123 getPhotoInfo(), 124 entry, 125 callTypeHelper, 126 !entry.getHistoryResultsList().isEmpty() && position != getItemCount() - 2); 127 } 128 } 129 130 @Override 131 @CallSuper getItemViewType(int position)132 public int getItemViewType(int position) { 133 if (position == 0) { // Header 134 return HEADER_VIEW_TYPE; 135 } else if (position == getItemCount() - 1) { 136 return FOOTER_VIEW_TYPE; 137 } else { 138 return CALL_ENTRY_VIEW_TYPE; 139 } 140 } 141 142 @Override 143 @CallSuper getItemCount()144 public int getItemCount() { 145 return callDetailsEntries.getEntriesCount() == 0 146 ? 0 147 : callDetailsEntries.getEntriesCount() + 2; // plus header and footer 148 } 149 getCallDetailsEntries()150 final CallDetailsEntries getCallDetailsEntries() { 151 return callDetailsEntries; 152 } 153 154 @MainThread updateCallDetailsEntries(CallDetailsEntries entries)155 final void updateCallDetailsEntries(CallDetailsEntries entries) { 156 Assert.isMainThread(); 157 callDetailsEntries = entries; 158 notifyDataSetChanged(); 159 } 160 getCallbackAction()161 final @CallbackAction int getCallbackAction() { 162 Assert.checkState(!callDetailsEntries.getEntriesList().isEmpty()); 163 164 CallDetailsEntry entry = callDetailsEntries.getEntries(0); 165 return CallbackActionHelper.getCallbackAction( 166 getNumber(), entry.getFeatures(), entry.getIsDuoCall()); 167 } 168 } 169