• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.contacts.calllog;
18 
19 import com.android.contacts.PhoneCallDetails;
20 import com.android.contacts.R;
21 
22 import android.content.Context;
23 import android.provider.CallLog.Calls;
24 import android.text.format.DateUtils;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.BaseAdapter;
29 import android.widget.TextView;
30 
31 /**
32  * Adapter for a ListView containing history items from the details of a call.
33  */
34 public class CallDetailHistoryAdapter extends BaseAdapter {
35     /** The top element is a blank header, which is hidden under the rest of the UI. */
36     private static final int VIEW_TYPE_HEADER = 0;
37     /** Each history item shows the detail of a call. */
38     private static final int VIEW_TYPE_HISTORY_ITEM = 1;
39 
40     private final Context mContext;
41     private final LayoutInflater mLayoutInflater;
42     private final CallTypeHelper mCallTypeHelper;
43     private final PhoneCallDetails[] mPhoneCallDetails;
44     /** Whether the voicemail controls are shown. */
45     private final boolean mShowVoicemail;
46     /** Whether the call and SMS controls are shown. */
47     private final boolean mShowCallAndSms;
48     /** The controls that are shown on top of the history list. */
49     private final View mControls;
50     /** The listener to changes of focus of the header. */
51     private View.OnFocusChangeListener mHeaderFocusChangeListener =
52             new View.OnFocusChangeListener() {
53         @Override
54         public void onFocusChange(View v, boolean hasFocus) {
55             // When the header is focused, focus the controls above it instead.
56             if (hasFocus) {
57                 mControls.requestFocus();
58             }
59         }
60     };
61 
CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater, CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails, boolean showVoicemail, boolean showCallAndSms, View controls)62     public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
63             CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails,
64             boolean showVoicemail, boolean showCallAndSms, View controls) {
65         mContext = context;
66         mLayoutInflater = layoutInflater;
67         mCallTypeHelper = callTypeHelper;
68         mPhoneCallDetails = phoneCallDetails;
69         mShowVoicemail = showVoicemail;
70         mShowCallAndSms = showCallAndSms;
71         mControls = controls;
72     }
73 
74     @Override
isEnabled(int position)75     public boolean isEnabled(int position) {
76         // None of history will be clickable.
77         return false;
78     }
79 
80     @Override
getCount()81     public int getCount() {
82         return mPhoneCallDetails.length + 1;
83     }
84 
85     @Override
getItem(int position)86     public Object getItem(int position) {
87         if (position == 0) {
88             return null;
89         }
90         return mPhoneCallDetails[position - 1];
91     }
92 
93     @Override
getItemId(int position)94     public long getItemId(int position) {
95         if (position == 0) {
96             return -1;
97         }
98         return position - 1;
99     }
100 
101     @Override
getViewTypeCount()102     public int getViewTypeCount() {
103         return 2;
104     }
105 
106     @Override
getItemViewType(int position)107     public int getItemViewType(int position) {
108         if (position == 0) {
109             return VIEW_TYPE_HEADER;
110         }
111         return VIEW_TYPE_HISTORY_ITEM;
112     }
113 
114     @Override
getView(int position, View convertView, ViewGroup parent)115     public View getView(int position, View convertView, ViewGroup parent) {
116         if (position == 0) {
117             final View header = convertView == null
118                     ? mLayoutInflater.inflate(R.layout.call_detail_history_header, parent, false)
119                     : convertView;
120             // Voicemail controls are only shown in the main UI if there is a voicemail.
121             View voicemailContainer = header.findViewById(R.id.header_voicemail_container);
122             voicemailContainer.setVisibility(mShowVoicemail ? View.VISIBLE : View.GONE);
123             // Call and SMS controls are only shown in the main UI if there is a known number.
124             View callAndSmsContainer = header.findViewById(R.id.header_call_and_sms_container);
125             callAndSmsContainer.setVisibility(mShowCallAndSms ? View.VISIBLE : View.GONE);
126             header.setFocusable(true);
127             header.setOnFocusChangeListener(mHeaderFocusChangeListener);
128             return header;
129         }
130 
131         // Make sure we have a valid convertView to start with
132         final View result  = convertView == null
133                 ? mLayoutInflater.inflate(R.layout.call_detail_history_item, parent, false)
134                 : convertView;
135 
136         PhoneCallDetails details = mPhoneCallDetails[position - 1];
137         CallTypeIconsView callTypeIconView =
138                 (CallTypeIconsView) result.findViewById(R.id.call_type_icon);
139         TextView callTypeTextView = (TextView) result.findViewById(R.id.call_type_text);
140         TextView dateView = (TextView) result.findViewById(R.id.date);
141         TextView durationView = (TextView) result.findViewById(R.id.duration);
142 
143         int callType = details.callTypes[0];
144         callTypeIconView.clear();
145         callTypeIconView.add(callType);
146         callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType));
147         // Set the date.
148         CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
149                 DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
150                 DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
151         dateView.setText(dateValue);
152         // Set the duration
153         if (callType == Calls.MISSED_TYPE || callType == Calls.VOICEMAIL_TYPE) {
154             durationView.setVisibility(View.GONE);
155         } else {
156             durationView.setVisibility(View.VISIBLE);
157             durationView.setText(formatDuration(details.duration));
158         }
159 
160         return result;
161     }
162 
formatDuration(long elapsedSeconds)163     private String formatDuration(long elapsedSeconds) {
164         long minutes = 0;
165         long seconds = 0;
166 
167         if (elapsedSeconds >= 60) {
168             minutes = elapsedSeconds / 60;
169             elapsedSeconds -= minutes * 60;
170         }
171         seconds = elapsedSeconds;
172 
173         return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
174     }
175 }
176