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
17package com.android.dialer.calllog;
18
19import android.content.Context;
20import android.provider.CallLog.Calls;
21import android.text.format.DateUtils;
22import android.text.format.Formatter;
23import android.view.LayoutInflater;
24import android.view.View;
25import android.view.ViewGroup;
26import android.widget.BaseAdapter;
27import android.widget.TextView;
28
29import com.android.contacts.common.CallUtil;
30import com.android.dialer.PhoneCallDetails;
31import com.android.dialer.R;
32import com.android.dialer.util.DialerUtils;
33import com.google.common.collect.Lists;
34
35import java.util.ArrayList;
36
37/**
38 * Adapter for a ListView containing history items from the details of a call.
39 */
40public 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
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
65    public boolean isEnabled(int position) {
66        // None of history will be clickable.
67        return false;
68    }
69
70    @Override
71    public int getCount() {
72        return mPhoneCallDetails.length + 1;
73    }
74
75    @Override
76    public Object getItem(int position) {
77        if (position == 0) {
78            return null;
79        }
80        return mPhoneCallDetails[position - 1];
81    }
82
83    @Override
84    public long getItemId(int position) {
85        if (position == 0) {
86            return -1;
87        }
88        return position - 1;
89    }
90
91    @Override
92    public int getViewTypeCount() {
93        return 2;
94    }
95
96    @Override
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
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
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            seconds = elapsedSeconds;
157            return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
158        } else {
159            seconds = elapsedSeconds;
160            return mContext.getString(R.string.callDetailsShortDurationFormat, seconds);
161        }
162    }
163
164    /**
165     * Formats a string containing the call duration and the data usage (if specified).
166     *
167     * @param elapsedSeconds Total elapsed seconds.
168     * @param dataUsage Data usage in bytes, or null if not specified.
169     * @return String containing call duration and data usage.
170     */
171    private CharSequence formatDurationAndDataUsage(long elapsedSeconds, Long dataUsage) {
172        CharSequence duration = formatDuration(elapsedSeconds);
173
174        if (dataUsage != null) {
175            mDurationItems.clear();
176            mDurationItems.add(duration);
177            mDurationItems.add(Formatter.formatShortFileSize(mContext, dataUsage));
178
179            return DialerUtils.join(mContext.getResources(), mDurationItems);
180        } else {
181            return duration;
182        }
183    }
184}
185