auto import from //depot/cupcake/@135843
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
new file mode 100644
index 0000000..012a33e
--- /dev/null
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2009 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.contacts;
+
+import android.app.ListActivity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.CallLog;
+import android.provider.Contacts;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Intents.Insert;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Displays the details of a specific call log entry.
+ */
+public class CallDetailActivity extends ListActivity implements
+ AdapterView.OnItemClickListener {
+ private static final String TAG = "CallDetail";
+
+ private TextView mCallType;
+ private ImageView mCallTypeIcon;
+ private TextView mCallTime;
+ private TextView mCallDuration;
+
+ private String mNumber = null;
+
+ /* package */ LayoutInflater mInflater;
+ /* package */ Resources mResources;
+
+ static final String[] CALL_LOG_PROJECTION = new String[] {
+ CallLog.Calls.DATE,
+ CallLog.Calls.DURATION,
+ CallLog.Calls.NUMBER,
+ CallLog.Calls.TYPE,
+ };
+
+ static final int DATE_COLUMN_INDEX = 0;
+ static final int DURATION_COLUMN_INDEX = 1;
+ static final int NUMBER_COLUMN_INDEX = 2;
+ static final int CALL_TYPE_COLUMN_INDEX = 3;
+
+ static final String[] PHONES_PROJECTION = new String[] {
+ Phones.PERSON_ID,
+ Phones.DISPLAY_NAME,
+ Phones.TYPE,
+ Phones.LABEL,
+ Phones.NUMBER,
+ };
+ static final int COLUMN_INDEX_ID = 0;
+ static final int COLUMN_INDEX_NAME = 1;
+ static final int COLUMN_INDEX_TYPE = 2;
+ static final int COLUMN_INDEX_LABEL = 3;
+ static final int COLUMN_INDEX_NUMBER = 4;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.call_detail);
+
+ mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
+ mResources = getResources();
+
+ mCallType = (TextView) findViewById(R.id.type);
+ mCallTypeIcon = (ImageView) findViewById(R.id.icon);
+ mCallTime = (TextView) findViewById(R.id.time);
+ mCallDuration = (TextView) findViewById(R.id.duration);
+
+ getListView().setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateData(getIntent().getData());
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_CALL: {
+ // Make sure phone isn't already busy before starting direct call
+ TelephonyManager tm = (TelephonyManager)
+ getSystemService(Context.TELEPHONY_SERVICE);
+ if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
+ Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+ Uri.fromParts("tel", mNumber, null));
+ startActivity(callIntent);
+ return true;
+ }
+ }
+ }
+
+ return super.onKeyDown(keyCode, event);
+ }
+
+ /**
+ * Update user interface with details of given call.
+ *
+ * @param callUri Uri into {@link CallLog.Calls}
+ */
+ private void updateData(Uri callUri) {
+ ContentResolver resolver = getContentResolver();
+ Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null);
+ try {
+ if (callCursor != null && callCursor.moveToFirst()) {
+ // Read call log specifics
+ mNumber = callCursor.getString(NUMBER_COLUMN_INDEX);
+ long date = callCursor.getLong(DATE_COLUMN_INDEX);
+ long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
+ int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
+
+ // Pull out string in format [relative], [date]
+ CharSequence dateClause = DateUtils.formatDateRange(this, date, date,
+ DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
+ DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
+ mCallTime.setText(dateClause);
+
+ // Set the duration
+ if (callType == Calls.MISSED_TYPE) {
+ mCallDuration.setVisibility(View.GONE);
+ } else {
+ mCallDuration.setVisibility(View.VISIBLE);
+ mCallDuration.setText(formatDuration(duration));
+ }
+
+ // Set the call type icon and caption
+ String callText = null;
+ switch (callType) {
+ case Calls.INCOMING_TYPE:
+ mCallTypeIcon.setImageResource(android.R.drawable.sym_call_incoming);
+ mCallType.setText(R.string.type_incoming);
+ callText = getString(R.string.callBack);
+ break;
+
+ case Calls.OUTGOING_TYPE:
+ mCallTypeIcon.setImageResource(android.R.drawable.sym_call_outgoing);
+ mCallType.setText(R.string.type_outgoing);
+ callText = getString(R.string.callAgain);
+ break;
+
+ case Calls.MISSED_TYPE:
+ mCallTypeIcon.setImageResource(android.R.drawable.sym_call_missed);
+ mCallType.setText(R.string.type_missed);
+ callText = getString(R.string.returnCall);
+ break;
+ }
+
+ // Perform a reverse-phonebook lookup to find the PERSON_ID
+ String callLabel = null;
+ Uri personUri = null;
+ Uri phoneUri = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, Uri.encode(mNumber));
+ Cursor phonesCursor = resolver.query(phoneUri, PHONES_PROJECTION, null, null, null);
+ try {
+ if (phonesCursor != null && phonesCursor.moveToFirst()) {
+ long personId = phonesCursor.getLong(COLUMN_INDEX_ID);
+ personUri = ContentUris.withAppendedId(
+ Contacts.People.CONTENT_URI, personId);
+ callText = getString(R.string.recentCalls_callNumber,
+ phonesCursor.getString(COLUMN_INDEX_NAME));
+ mNumber = phonesCursor.getString(COLUMN_INDEX_NUMBER);
+ callLabel = Phones.getDisplayLabel(this,
+ phonesCursor.getInt(COLUMN_INDEX_TYPE),
+ phonesCursor.getString(COLUMN_INDEX_LABEL)).toString();
+ } else {
+ mNumber = PhoneNumberUtils.formatNumber(mNumber);
+ }
+ } finally {
+ if (phonesCursor != null) phonesCursor.close();
+ }
+
+ // Build list of various available actions
+ List<ViewEntry> actions = new ArrayList<ViewEntry>();
+
+ Intent callIntent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
+ Uri.fromParts("tel", mNumber, null));
+ ViewEntry entry = new ViewEntry(android.R.drawable.sym_action_call, callText,
+ callIntent);
+ entry.number = mNumber;
+ entry.label = callLabel;
+ actions.add(entry);
+
+ Intent smsIntent = new Intent(Intent.ACTION_SENDTO,
+ Uri.fromParts("sms", mNumber, null));
+ actions.add(new ViewEntry(R.drawable.sym_action_sms,
+ getString(R.string.menu_sendTextMessage), smsIntent));
+
+ // Let user view contact details if they exist, otherwise add option
+ // to create new contact from this number.
+ if (personUri != null) {
+ Intent viewIntent = new Intent(Intent.ACTION_VIEW, personUri);
+ actions.add(new ViewEntry(R.drawable.sym_action_view_contact,
+ getString(R.string.menu_viewContact), viewIntent));
+ } else {
+ Intent createIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+ createIntent.setType(People.CONTENT_ITEM_TYPE);
+ createIntent.putExtra(Insert.PHONE, mNumber);
+ actions.add(new ViewEntry(R.drawable.sym_action_add,
+ getString(R.string.recentCalls_addToContact), createIntent));
+ }
+
+ ViewAdapter adapter = new ViewAdapter(this, actions);
+ setListAdapter(adapter);
+ } else {
+ // Something went wrong reading in our primary data, so we're going to
+ // bail out and show error to users.
+ Toast.makeText(this, R.string.toast_call_detail_error,
+ Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ } finally {
+ if (callCursor != null) {
+ callCursor.close();
+ }
+ }
+ }
+
+ private String formatDuration(long elapsedSeconds) {
+ long minutes = 0;
+ long seconds = 0;
+
+ if (elapsedSeconds >= 60) {
+ minutes = elapsedSeconds / 60;
+ elapsedSeconds -= minutes * 60;
+ }
+ seconds = elapsedSeconds;
+
+ return getString(R.string.callDetailsDurationFormat, minutes, seconds);
+ }
+
+ static final class ViewEntry {
+ public int icon = -1;
+ public String text = null;
+ public Intent intent = null;
+ public String label = null;
+ public String number = null;
+
+ public ViewEntry(int icon, String text, Intent intent) {
+ this.icon = icon;
+ this.text = text;
+ this.intent = intent;
+ }
+ }
+
+ static final class ViewAdapter extends BaseAdapter {
+
+ private final List<ViewEntry> mActions;
+
+ private final LayoutInflater mInflater;
+
+ public ViewAdapter(Context context, List<ViewEntry> actions) {
+ mActions = actions;
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ }
+
+ public int getCount() {
+ return mActions.size();
+ }
+
+ public Object getItem(int position) {
+ return mActions.get(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // Make sure we have a valid convertView to start with
+ if (convertView == null) {
+ convertView = mInflater.inflate(R.layout.call_detail_list_item, parent, false);
+ }
+
+ // Fill action with icon and text.
+ ViewEntry entry = mActions.get(position);
+ convertView.setTag(entry);
+
+ ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
+ TextView text = (TextView) convertView.findViewById(android.R.id.text1);
+
+ icon.setImageResource(entry.icon);
+ text.setText(entry.text);
+
+ View line2 = convertView.findViewById(R.id.line2);
+ boolean numberEmpty = TextUtils.isEmpty(entry.number);
+ boolean labelEmpty = TextUtils.isEmpty(entry.label) || numberEmpty;
+ if (labelEmpty && numberEmpty) {
+ line2.setVisibility(View.GONE);
+ } else {
+ line2.setVisibility(View.VISIBLE);
+
+ TextView label = (TextView) convertView.findViewById(R.id.label);
+ if (labelEmpty) {
+ label.setVisibility(View.GONE);
+ } else {
+ label.setText(entry.label);
+ label.setVisibility(View.VISIBLE);
+ }
+
+ TextView number = (TextView) convertView.findViewById(R.id.number);
+ number.setText(entry.number);
+ }
+
+ return convertView;
+ }
+ }
+
+ public void onItemClick(AdapterView parent, View view, int position, long id) {
+ // Handle passing action off to correct handler.
+ if (view.getTag() instanceof ViewEntry) {
+ ViewEntry entry = (ViewEntry) view.getTag();
+ if (entry.intent != null) {
+ startActivity(entry.intent);
+ }
+ }
+ }
+}