1 /*
2  * Copyright (C) 2011 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.calllog;
18 
19 import android.content.Context;
20 import android.provider.CallLog.Calls;
21 import android.text.format.DateUtils;
22 import android.text.format.Formatter;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 import android.widget.BaseAdapter;
27 import android.widget.TextView;
28 
29 import com.android.contacts.common.CallUtil;
30 import com.android.dialer.PhoneCallDetails;
31 import com.android.dialer.R;
32 import com.android.dialer.util.DialerUtils;
33 import com.google.common.collect.Lists;
34 
35 import java.util.ArrayList;
36 
37 /**
38  * Adapter for a ListView containing history items from the details of a call.
39  */
40 public class CallDetailHistoryAdapter extends BaseAdapter {
41     /** The top element is a blank header, which is hidden under the rest of the UI. */
42     private static final int VIEW_TYPE_HEADER = 0;
43     /** Each history item shows the detail of a call. */
44     private static final int VIEW_TYPE_HISTORY_ITEM = 1;
45 
46     private final Context mContext;
47     private final LayoutInflater mLayoutInflater;
48     private final CallTypeHelper mCallTypeHelper;
49     private final PhoneCallDetails[] mPhoneCallDetails;
50 
51     /**
52      * List of items to be concatenated together for duration strings.
53      */
54     private ArrayList<CharSequence> mDurationItems = Lists.newArrayList();
55 
CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater, CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails)56     public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
57             CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails) {
58         mContext = context;
59         mLayoutInflater = layoutInflater;
60         mCallTypeHelper = callTypeHelper;
61         mPhoneCallDetails = phoneCallDetails;
62     }
63 
64     @Override
isEnabled(int position)65     public boolean isEnabled(int position) {
66         // None of history will be clickable.
67         return false;
68     }
69 
70     @Override
getCount()71     public int getCount() {
72         return mPhoneCallDetails.length + 1;
73     }
74 
75     @Override
getItem(int position)76     public Object getItem(int position) {
77         if (position == 0) {
78             return null;
79         }
80         return mPhoneCallDetails[position - 1];
81     }
82 
83     @Override
getItemId(int position)84     public long getItemId(int position) {
85         if (position == 0) {
86             return -1;
87         }
88         return position - 1;
89     }
90 
91     @Override
getViewTypeCount()92     public int getViewTypeCount() {
93         return 2;
94     }
95 
96     @Override
getItemViewType(int position)97     public int getItemViewType(int position) {
98         if (position == 0) {
99             return VIEW_TYPE_HEADER;
100         }
101         return VIEW_TYPE_HISTORY_ITEM;
102     }
103 
104     @Override
getView(int position, View convertView, ViewGroup parent)105     public View getView(int position, View convertView, ViewGroup parent) {
106         if (position == 0) {
107             final View header = convertView == null
108                     ? mLayoutInflater.inflate(R.layout.call_detail_history_header, parent, false)
109                     : convertView;
110             return header;
111         }
112 
113         // Make sure we have a valid convertView to start with
114         final View result  = convertView == null
115                 ? mLayoutInflater.inflate(R.layout.call_detail_history_item, parent, false)
116                 : convertView;
117 
118         PhoneCallDetails details = mPhoneCallDetails[position - 1];
119         CallTypeIconsView callTypeIconView =
120                 (CallTypeIconsView) result.findViewById(R.id.call_type_icon);
121         TextView callTypeTextView = (TextView) result.findViewById(R.id.call_type_text);
122         TextView dateView = (TextView) result.findViewById(R.id.date);
123         TextView durationView = (TextView) result.findViewById(R.id.duration);
124 
125         int callType = details.callTypes[0];
126         boolean isVideoCall = (details.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO
127                 && CallUtil.isVideoEnabled(mContext);
128 
129         callTypeIconView.clear();
130         callTypeIconView.add(callType);
131         callTypeIconView.setShowVideo(isVideoCall);
132         callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType, isVideoCall));
133         // Set the date.
134         CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
135                 DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
136                 DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
137         dateView.setText(dateValue);
138         // Set the duration
139         if (Calls.VOICEMAIL_TYPE == callType || CallTypeHelper.isMissedCallType(callType)) {
140             durationView.setVisibility(View.GONE);
141         } else {
142             durationView.setVisibility(View.VISIBLE);
143             durationView.setText(formatDurationAndDataUsage(details.duration, details.dataUsage));
144         }
145 
146         return result;
147     }
148 
formatDuration(long elapsedSeconds)149     private CharSequence formatDuration(long elapsedSeconds) {
150         long minutes = 0;
151         long seconds = 0;
152 
153         if (elapsedSeconds >= 60) {
154             minutes = elapsedSeconds / 60;
155             elapsedSeconds -= minutes * 60;
156         }
157         seconds = elapsedSeconds;
158 
159         return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
160     }
161 
162     /**
163      * Formats a string containing the call duration and the data usage (if specified).
164      *
165      * @param elapsedSeconds Total elapsed seconds.
166      * @param dataUsage Data usage in bytes, or null if not specified.
167      * @return String containing call duration and data usage.
168      */
formatDurationAndDataUsage(long elapsedSeconds, Long dataUsage)169     private CharSequence formatDurationAndDataUsage(long elapsedSeconds, Long dataUsage) {
170         CharSequence duration = formatDuration(elapsedSeconds);
171 
172         if (dataUsage != null) {
173             mDurationItems.clear();
174             mDurationItems.add(duration);
175             mDurationItems.add(Formatter.formatShortFileSize(mContext, dataUsage));
176 
177             return DialerUtils.join(mContext.getResources(), mDurationItems);
178         } else {
179             return duration;
180         }
181     }
182 }
183