diff options
author | Eric Erfanian <erfanian@google.com> | 2017-03-15 14:41:07 -0700 |
---|---|---|
committer | Eric Erfanian <erfanian@google.com> | 2017-03-15 16:24:23 -0700 |
commit | d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9 (patch) | |
tree | b54abbb51fb7d66e7755a1fbb5db023ff601090b /java/com/android/dialer/calldetails | |
parent | 30436e7e6d3f2c8755a91b2b6222b74d465a9e87 (diff) |
Update Dialer source from latest green build.
* Refactor voicemail component
* Add new enriched calling components
Test: treehugger, manual aosp testing
Change-Id: I521a0f86327d4b42e14d93927c7d613044ed5942
Diffstat (limited to 'java/com/android/dialer/calldetails')
17 files changed, 1513 insertions, 0 deletions
diff --git a/java/com/android/dialer/calldetails/AndroidManifest.xml b/java/com/android/dialer/calldetails/AndroidManifest.xml new file mode 100644 index 000000000..b71207ba2 --- /dev/null +++ b/java/com/android/dialer/calldetails/AndroidManifest.xml @@ -0,0 +1,31 @@ +<!-- + ~ Copyright (C) 2017 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 + --> +<manifest + xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.dialer.calldetails"> + <application> + <activity + android:label="@string/call_details" + android:name="com.android.dialer.calldetails.CallDetailsActivity" + android:theme="@style/Theme.AppCompat.NoActionBar"> + <intent-filter> + <action android:name="android.intent.action.VIEW"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="vnd.android.cursor.item/calls"/> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java new file mode 100644 index 000000000..6070640a0 --- /dev/null +++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2017 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.dialer.calldetails; + +import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; +import android.os.Bundle; +import android.provider.CallLog; +import android.provider.CallLog.Calls; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MenuItem; +import android.widget.Toolbar; +import com.android.dialer.callcomposer.nano.CallComposerContact; +import com.android.dialer.calldetails.nano.CallDetailsEntries; +import com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry; +import com.android.dialer.common.Assert; +import com.android.dialer.common.AsyncTaskExecutors; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.nano.DialerImpression; +import com.android.dialer.protos.ProtoParsers; + +/** Displays the details of a specific call log entry. */ +public class CallDetailsActivity extends AppCompatActivity { + + private static final String EXTRA_CALL_DETAILS_ENTRIES = "call_details_entries"; + private static final String EXTRA_CONTACT = "contact"; + private static final String TASK_DELETE = "task_delete"; + + private CallDetailsEntry[] entries; + + public static Intent newInstance( + Context context, @NonNull CallDetailsEntries details, @NonNull CallComposerContact contact) { + Assert.isNotNull(details); + Assert.isNotNull(contact); + + Intent intent = new Intent(context, CallDetailsActivity.class); + ProtoParsers.put(intent, EXTRA_CONTACT, contact); + ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, details); + return intent; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.call_details_activity); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setActionBar(toolbar); + toolbar.inflateMenu(R.menu.call_details_menu); + toolbar.setNavigationOnClickListener(v -> finish()); + onHandleIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + onHandleIntent(intent); + } + + private void onHandleIntent(Intent intent) { + Bundle arguments = intent.getExtras(); + CallComposerContact contact = + ProtoParsers.getFromInstanceState(arguments, EXTRA_CONTACT, new CallComposerContact()); + entries = + ProtoParsers.getFromInstanceState( + arguments, EXTRA_CALL_DETAILS_ENTRIES, new CallDetailsEntries()) + .entries; + RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(new CallDetailsAdapter(this, contact, entries)); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.call_detail_delete_menu_item) { + Logger.get(this).logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM); + AsyncTaskExecutors.createAsyncTaskExecutor().submit(TASK_DELETE, new DeleteCallsTask()); + item.setEnabled(false); + return true; + } + return super.onOptionsItemSelected(item); + } + + /** Delete specified calls from the call log. */ + private class DeleteCallsTask extends AsyncTask<Void, Void, Void> { + + private final String callIds; + + DeleteCallsTask() { + StringBuilder callIds = new StringBuilder(); + for (CallDetailsEntry entry : entries) { + if (callIds.length() != 0) { + callIds.append(","); + } + callIds.append(entry.callId); + } + this.callIds = callIds.toString(); + } + + @Override + protected Void doInBackground(Void... params) { + getContentResolver() + .delete(Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIds + ")", null); + return null; + } + + @Override + public void onPostExecute(Void result) { + finish(); + } + } +} diff --git a/java/com/android/dialer/calldetails/CallDetailsAdapter.java b/java/com/android/dialer/calldetails/CallDetailsAdapter.java new file mode 100644 index 000000000..954583077 --- /dev/null +++ b/java/com/android/dialer/calldetails/CallDetailsAdapter.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 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.dialer.calldetails; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.LayoutInflater; +import android.view.ViewGroup; +import com.android.dialer.callcomposer.nano.CallComposerContact; +import com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry; +import com.android.dialer.calllogutils.CallTypeHelper; +import com.android.dialer.common.Assert; + +/** Adapter for RecyclerView in {@link CallDetailsActivity}. */ +public class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + + private static final int HEADER_VIEW_TYPE = 1; + private static final int CALL_ENTRY_VIEW_TYPE = 2; + private static final int FOOTER_VIEW_TYPE = 3; + + private final CallComposerContact contact; + private final CallDetailsEntry[] callDetailsEntries; + private final CallTypeHelper callTypeHelper; + + public CallDetailsAdapter( + Context context, CallComposerContact contact, CallDetailsEntry[] callDetailsEntries) { + this.contact = Assert.isNotNull(contact); + this.callDetailsEntries = Assert.isNotNull(callDetailsEntries); + callTypeHelper = new CallTypeHelper(context.getResources()); + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LayoutInflater inflater = LayoutInflater.from(parent.getContext()); + switch (viewType) { + case HEADER_VIEW_TYPE: + return new CallDetailsHeaderViewHolder( + inflater.inflate(R.layout.contact_container, parent, false)); + case CALL_ENTRY_VIEW_TYPE: + return new CallDetailsEntryViewHolder( + inflater.inflate(R.layout.call_details_entry, parent, false)); + case FOOTER_VIEW_TYPE: + return new CallDetailsFooterViewHolder( + inflater.inflate(R.layout.call_details_footer, parent, false)); + default: + Assert.fail("No ViewHolder available for viewType: " + viewType); + return null; + } + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + if (position == 0) { // Header + ((CallDetailsHeaderViewHolder) holder).updateContactInfo(contact); + } else if (position == getItemCount() - 1) { + ((CallDetailsFooterViewHolder) holder).setPhoneNumber(contact.number); + } else { + CallDetailsEntryViewHolder viewHolder = (CallDetailsEntryViewHolder) holder; + viewHolder.setCallDetails( + contact.number, + callDetailsEntries[position - 1], + callTypeHelper, + position != getItemCount() - 2); + } + } + + @Override + public int getItemViewType(int position) { + if (position == 0) { // Header + return HEADER_VIEW_TYPE; + } else if (position == getItemCount() - 1) { + return FOOTER_VIEW_TYPE; + } else { + return CALL_ENTRY_VIEW_TYPE; + } + } + + @Override + public int getItemCount() { + return callDetailsEntries.length + 2; // Header + footer + } +} diff --git a/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java b/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java new file mode 100644 index 000000000..b1a70af0c --- /dev/null +++ b/java/com/android/dialer/calldetails/CallDetailsEntryViewHolder.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2017 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.dialer.calldetails; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.provider.CallLog.Calls; +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.text.TextUtils; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; +import com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry; +import com.android.dialer.calllogutils.CallEntryFormatter; +import com.android.dialer.calllogutils.CallTypeHelper; +import com.android.dialer.common.LogUtil; +import com.android.dialer.compat.AppCompatConstants; +import com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult; +import com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult.Type; +import com.android.dialer.util.CallUtil; +import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.IntentUtil; + +/** ViewHolder for call entries in {@link CallDetailsActivity}. */ +public class CallDetailsEntryViewHolder extends ViewHolder { + + private final ImageView callTypeIcon; + private final TextView callTypeText; + private final TextView callTime; + private final TextView callDuration; + + private final View multimediaImageContainer; + private final View multimediaDetailsContainer; + private final View multimediaDivider; + + private final TextView multimediaDetails; + + private final ImageView multimediaImage; + + // TODO: Display this when location is stored - b/36160042 + @SuppressWarnings("unused") + private final TextView multimediaAttachmentsNumber; + + private final Context context; + + public CallDetailsEntryViewHolder(View container) { + super(container); + context = container.getContext(); + + callTypeIcon = (ImageView) container.findViewById(R.id.call_direction); + callTypeText = (TextView) container.findViewById(R.id.call_type); + callTime = (TextView) container.findViewById(R.id.call_time); + callDuration = (TextView) container.findViewById(R.id.call_duration); + + multimediaImageContainer = container.findViewById(R.id.multimedia_image_container); + multimediaDetailsContainer = container.findViewById(R.id.ec_container); + multimediaDivider = container.findViewById(R.id.divider); + multimediaDetails = (TextView) container.findViewById(R.id.multimedia_details); + multimediaImage = (ImageView) container.findViewById(R.id.multimedia_image); + multimediaAttachmentsNumber = + (TextView) container.findViewById(R.id.multimedia_attachments_number); + } + + void setCallDetails( + String number, + CallDetailsEntry entry, + CallTypeHelper callTypeHelper, + boolean showMultimediaDivider) { + int callType = entry.callType; + boolean isVideoCall = + (entry.features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO + && CallUtil.isVideoEnabled(context); + boolean isPulledCall = + (entry.features & Calls.FEATURES_PULLED_EXTERNALLY) == Calls.FEATURES_PULLED_EXTERNALLY; + + Drawable callIcon = getIconForCallType(context.getResources(), callType); + int color = getColorForCallType(context, callType); + callIcon.setColorFilter(color, PorterDuff.Mode.MULTIPLY); + callTime.setTextColor(color); + callTypeIcon.setImageDrawable(callIcon); + + callTypeText.setText(callTypeHelper.getCallTypeText(callType, isVideoCall, isPulledCall)); + callTime.setText(CallEntryFormatter.formatDate(context, entry.date)); + if (CallTypeHelper.isMissedCallType(callType)) { + callDuration.setVisibility(View.GONE); + } else { + callDuration.setVisibility(View.VISIBLE); + callDuration.setText( + CallEntryFormatter.formatDurationAndDataUsage(context, entry.duration, entry.dataUsage)); + } + setMultimediaDetails(number, entry, showMultimediaDivider); + } + + private void setMultimediaDetails(String number, CallDetailsEntry entry, boolean showDivider) { + multimediaDivider.setVisibility(showDivider ? View.VISIBLE : View.GONE); + if (entry.historyResults == null || entry.historyResults.length <= 0) { + LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no data, hiding UI"); + multimediaDetailsContainer.setVisibility(View.GONE); + } else { + + // TODO: b/36158891 Add room for 2 pieces of enriched call data. It's possible + // to have both call composer data and post call data for a single call. + HistoryResult historyResult = entry.historyResults[0]; + multimediaDetailsContainer.setVisibility(View.VISIBLE); + multimediaDetailsContainer.setOnClickListener( + (v) -> { + DialerUtils.startActivityWithErrorToast(context, IntentUtil.getSendSmsIntent(number)); + }); + multimediaImageContainer.setClipToOutline(true); + + if (!TextUtils.isEmpty(historyResult.imageUri)) { + LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "setting image"); + multimediaImageContainer.setVisibility(View.VISIBLE); + multimediaImage.setImageURI(Uri.parse(historyResult.imageUri)); + multimediaDetails.setText( + isIncoming(historyResult) ? R.string.received_a_photo : R.string.sent_a_photo); + } else { + LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no image"); + } + + // Set text after image to overwrite the received/sent a photo text + if (!TextUtils.isEmpty(historyResult.text)) { + LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "showing text"); + multimediaDetails.setText( + context.getString(R.string.message_in_quotes, historyResult.text)); + } else { + LogUtil.i("CallDetailsEntryViewHolder.setMultimediaDetails", "no text"); + } + } + } + + private static boolean isIncoming(@NonNull HistoryResult historyResult) { + return historyResult.type == Type.INCOMING_POST_CALL + || historyResult.type == Type.INCOMING_CALL_COMPOSER; + } + + private static Drawable getIconForCallType(Resources resources, int callType) { + switch (callType) { + case AppCompatConstants.CALLS_OUTGOING_TYPE: + return resources.getDrawable(R.drawable.quantum_ic_call_made_white_24); + case AppCompatConstants.CALLS_BLOCKED_TYPE: + return resources.getDrawable(R.drawable.quantum_ic_block_white_24); + case AppCompatConstants.CALLS_INCOMING_TYPE: + case AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE: + case AppCompatConstants.CALLS_REJECTED_TYPE: + return resources.getDrawable(R.drawable.quantum_ic_call_received_white_24); + case AppCompatConstants.CALLS_MISSED_TYPE: + default: + // It is possible for users to end up with calls with unknown call types in their + // call history, possibly due to 3rd party call log implementations (e.g. to + // distinguish between rejected and missed calls). Instead of crashing, just + // assume that all unknown call types are missed calls. + return resources.getDrawable(R.drawable.quantum_ic_call_missed_white_24); + } + } + + private static @ColorInt int getColorForCallType(Context context, int callType) { + switch (callType) { + case AppCompatConstants.CALLS_OUTGOING_TYPE: + case AppCompatConstants.CALLS_VOICEMAIL_TYPE: + case AppCompatConstants.CALLS_BLOCKED_TYPE: + case AppCompatConstants.CALLS_INCOMING_TYPE: + case AppCompatConstants.CALLS_ANSWERED_EXTERNALLY_TYPE: + case AppCompatConstants.CALLS_REJECTED_TYPE: + return ContextCompat.getColor(context, R.color.dialer_secondary_text_color); + case AppCompatConstants.CALLS_MISSED_TYPE: + default: + // It is possible for users to end up with calls with unknown call types in their + // call history, possibly due to 3rd party call log implementations (e.g. to + // distinguish between rejected and missed calls). Instead of crashing, just + // assume that all unknown call types are missed calls. + return ContextCompat.getColor(context, R.color.missed_call); + } + } +} diff --git a/java/com/android/dialer/calldetails/CallDetailsFooterViewHolder.java b/java/com/android/dialer/calldetails/CallDetailsFooterViewHolder.java new file mode 100644 index 000000000..36662bab9 --- /dev/null +++ b/java/com/android/dialer/calldetails/CallDetailsFooterViewHolder.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 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.dialer.calldetails; + +import android.content.Context; +import android.content.Intent; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.View.OnClickListener; +import com.android.contacts.common.ClipboardUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.nano.DialerImpression; +import com.android.dialer.util.CallUtil; +import com.android.dialer.util.DialerUtils; + +/** ViewHolder container for {@link CallDetailsActivity} footer. */ +public class CallDetailsFooterViewHolder extends RecyclerView.ViewHolder + implements OnClickListener { + + private final View copy; + private final View edit; + + private String number; + + public CallDetailsFooterViewHolder(View view) { + super(view); + copy = view.findViewById(R.id.call_detail_action_copy); + edit = view.findViewById(R.id.call_detail_action_edit_before_call); + + copy.setOnClickListener(this); + edit.setOnClickListener(this); + } + + public void setPhoneNumber(String number) { + this.number = number; + } + + @Override + public void onClick(View view) { + Context context = view.getContext(); + if (view == copy) { + Logger.get(context).logImpression(DialerImpression.Type.CALL_DETAILS_COPY_NUMBER); + ClipboardUtils.copyText(context, null, number, true); + } else if (view == edit) { + Logger.get(context).logImpression(DialerImpression.Type.CALL_DETAILS_EDIT_BEFORE_CALL); + Intent dialIntent = new Intent(Intent.ACTION_DIAL, CallUtil.getCallUri(number)); + DialerUtils.startActivityWithErrorToast(context, dialIntent); + } else { + Assert.fail("View on click not implemented: " + view); + } + } +} diff --git a/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java b/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java new file mode 100644 index 000000000..1679c2baf --- /dev/null +++ b/java/com/android/dialer/calldetails/CallDetailsHeaderViewHolder.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 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.dialer.calldetails; + +import android.content.Context; +import android.net.Uri; +import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.QuickContactBadge; +import android.widget.TextView; +import com.android.contacts.common.ContactPhotoManager; +import com.android.contacts.common.util.UriUtils; +import com.android.dialer.callcomposer.nano.CallComposerContact; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.callintent.nano.CallInitiationType; +import com.android.dialer.common.Assert; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.nano.DialerImpression; +import com.android.dialer.util.DialerUtils; + +/** ViewHolder for Header/Contact in {@link CallDetailsActivity}. */ +public class CallDetailsHeaderViewHolder extends RecyclerView.ViewHolder + implements OnClickListener { + + private final View callBackButton; + private final TextView nameView; + private final TextView numberView; + private final QuickContactBadge contactPhoto; + private final Context context; + + private CallComposerContact contact; + + CallDetailsHeaderViewHolder(View container) { + super(container); + context = container.getContext(); + callBackButton = container.findViewById(R.id.call_back_button); + nameView = (TextView) container.findViewById(R.id.contact_name); + numberView = (TextView) container.findViewById(R.id.phone_number); + contactPhoto = (QuickContactBadge) container.findViewById(R.id.quick_contact_photo); + callBackButton.setOnClickListener(this); + } + + /** + * Populates the contact info fields based on the current contact information. Copied from {@link + * com.android.contacts.common.dialog.CallSubjectDialog}. + */ + public void updateContactInfo(CallComposerContact contact) { + this.contact = contact; + setPhoto( + contact.photoId, + Uri.parse(contact.photoUri), + Uri.parse(contact.contactUri), + contact.nameOrNumber, + contact.isBusiness); + + nameView.setText(contact.nameOrNumber); + if (!TextUtils.isEmpty(contact.numberLabel) && !TextUtils.isEmpty(contact.displayNumber)) { + numberView.setVisibility(View.VISIBLE); + String secondaryInfo = + context.getString( + com.android.contacts.common.R.string.call_subject_type_and_number, + contact.numberLabel, + contact.displayNumber); + numberView.setText(secondaryInfo); + } else { + numberView.setVisibility(View.GONE); + numberView.setText(null); + } + } + + /** + * Sets the photo on the quick contact galleryIcon. Copied from {@link + * com.android.contacts.common.dialog.CallSubjectDialog}. + */ + private void setPhoto( + long photoId, Uri photoUri, Uri contactUri, String displayName, boolean isBusiness) { + contactPhoto.assignContactUri(contactUri); + contactPhoto.setOverlay(null); + + int contactType = + isBusiness ? ContactPhotoManager.TYPE_BUSINESS : ContactPhotoManager.TYPE_DEFAULT; + String lookupKey = contactUri == null ? null : UriUtils.getLookupKeyFromUri(contactUri); + + ContactPhotoManager.DefaultImageRequest request = + new ContactPhotoManager.DefaultImageRequest( + displayName, lookupKey, contactType, true /* isCircular */); + + if (photoId == 0 && photoUri != null) { + contactPhoto.setImageDrawable( + context.getDrawable(R.drawable.product_logo_avatar_anonymous_color_120)); + } else { + ContactPhotoManager.getInstance(context) + .loadThumbnail( + contactPhoto, photoId, false /* darkTheme */, true /* isCircular */, request); + } + } + + @Override + public void onClick(View view) { + if (view == callBackButton) { + Logger.get(view.getContext()).logImpression(DialerImpression.Type.CALL_DETAILS_CALL_BACK); + DialerUtils.startActivityWithErrorToast( + view.getContext(), + new CallIntentBuilder(contact.number, CallInitiationType.Type.CALL_DETAILS).build()); + } else { + Assert.fail("View OnClickListener not implemented: " + view); + } + } +} diff --git a/java/com/android/dialer/calldetails/nano/CallDetailsEntries.java b/java/com/android/dialer/calldetails/nano/CallDetailsEntries.java new file mode 100644 index 000000000..aee8f3652 --- /dev/null +++ b/java/com/android/dialer/calldetails/nano/CallDetailsEntries.java @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2017 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! + +package com.android.dialer.calldetails.nano; + +/** This file is autogenerated, but javadoc required. */ +@SuppressWarnings("hiding") +public final class CallDetailsEntries + extends com.google.protobuf.nano.ExtendableMessageNano<CallDetailsEntries> { + + /** This file is autogenerated, but javadoc required. */ + public static final class CallDetailsEntry + extends com.google.protobuf.nano.ExtendableMessageNano<CallDetailsEntry> { + + private static volatile CallDetailsEntry[] _emptyArray; + public static CallDetailsEntry[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized (com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new CallDetailsEntry[0]; + } + } + } + return _emptyArray; + } + + // optional int64 call_id = 1; + public long callId; + + // optional int32 call_type = 2; + public int callType; + + // optional int32 features = 3; + public int features; + + // optional int64 date = 4; + public long date; + + // optional int64 duration = 5; + public long duration; + + // optional int64 data_usage = 6; + public long dataUsage; + + // repeated .com.android.dialer.enrichedcall.historyquery.proto. + // HistoryResult history_results = 7; + public com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult[] historyResults; + + // @@protoc_insertion_point(class_scope:com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry) + + public CallDetailsEntry() { + clear(); + } + + public CallDetailsEntry clear() { + callId = 0L; + callType = 0; + features = 0; + date = 0L; + duration = 0L; + dataUsage = 0L; + historyResults = + com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult.emptyArray(); + unknownFieldData = null; + cachedSize = -1; + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof CallDetailsEntry)) { + return false; + } + CallDetailsEntry other = (CallDetailsEntry) o; + if (this.callId != other.callId) { + return false; + } + if (this.callType != other.callType) { + return false; + } + if (this.features != other.features) { + return false; + } + if (this.date != other.date) { + return false; + } + if (this.duration != other.duration) { + return false; + } + if (this.dataUsage != other.dataUsage) { + return false; + } + if (!com.google.protobuf.nano.InternalNano.equals( + this.historyResults, other.historyResults)) { + return false; + } + if (unknownFieldData == null || unknownFieldData.isEmpty()) { + return other.unknownFieldData == null || other.unknownFieldData.isEmpty(); + } else { + return unknownFieldData.equals(other.unknownFieldData); + } + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + getClass().getName().hashCode(); + result = 31 * result + (int) (this.callId ^ (this.callId >>> 32)); + result = 31 * result + this.callType; + result = 31 * result + this.features; + result = 31 * result + (int) (this.date ^ (this.date >>> 32)); + result = 31 * result + (int) (this.duration ^ (this.duration >>> 32)); + result = 31 * result + (int) (this.dataUsage ^ (this.dataUsage >>> 32)); + result = 31 * result + com.google.protobuf.nano.InternalNano.hashCode(this.historyResults); + result = + 31 * result + + (unknownFieldData == null || unknownFieldData.isEmpty() + ? 0 + : unknownFieldData.hashCode()); + return result; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.callId != 0L) { + output.writeInt64(1, this.callId); + } + if (this.callType != 0) { + output.writeInt32(2, this.callType); + } + if (this.features != 0) { + output.writeInt32(3, this.features); + } + if (this.date != 0L) { + output.writeInt64(4, this.date); + } + if (this.duration != 0L) { + output.writeInt64(5, this.duration); + } + if (this.dataUsage != 0L) { + output.writeInt64(6, this.dataUsage); + } + if (this.historyResults != null && this.historyResults.length > 0) { + for (int i = 0; i < this.historyResults.length; i++) { + com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult element = + this.historyResults[i]; + if (element != null) { + output.writeMessage(7, element); + } + } + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.callId != 0L) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt64Size(1, this.callId); + } + if (this.callType != 0) { + size += + com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt32Size(2, this.callType); + } + if (this.features != 0) { + size += + com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt32Size(3, this.features); + } + if (this.date != 0L) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt64Size(4, this.date); + } + if (this.duration != 0L) { + size += + com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt64Size(5, this.duration); + } + if (this.dataUsage != 0L) { + size += + com.google.protobuf.nano.CodedOutputByteBufferNano.computeInt64Size(6, this.dataUsage); + } + if (this.historyResults != null && this.historyResults.length > 0) { + for (int i = 0; i < this.historyResults.length; i++) { + com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult element = + this.historyResults[i]; + if (element != null) { + size += + com.google.protobuf.nano.CodedOutputByteBufferNano.computeMessageSize(7, element); + } + } + } + return size; + } + + @Override + public CallDetailsEntry mergeFrom(com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: + { + if (!super.storeUnknownField(input, tag)) { + return this; + } + break; + } + case 8: + { + this.callId = input.readInt64(); + break; + } + case 16: + { + this.callType = input.readInt32(); + break; + } + case 24: + { + this.features = input.readInt32(); + break; + } + case 32: + { + this.date = input.readInt64(); + break; + } + case 40: + { + this.duration = input.readInt64(); + break; + } + case 48: + { + this.dataUsage = input.readInt64(); + break; + } + case 58: + { + int arrayLength = + com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, 58); + int i = this.historyResults == null ? 0 : this.historyResults.length; + com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult[] newArray = + new com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult + [i + arrayLength]; + if (i != 0) { + java.lang.System.arraycopy(this.historyResults, 0, newArray, 0, i); + } + for (; i < newArray.length - 1; i++) { + newArray[i] = + new com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult(); + input.readMessage(newArray[i]); + input.readTag(); + } + // Last one without readTag. + newArray[i] = + new com.android.dialer.enrichedcall.historyquery.proto.nano.HistoryResult(); + input.readMessage(newArray[i]); + this.historyResults = newArray; + break; + } + } + } + } + + public static CallDetailsEntry parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new CallDetailsEntry(), data); + } + + public static CallDetailsEntry parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) throws java.io.IOException { + return new CallDetailsEntry().mergeFrom(input); + } + } + + private static volatile CallDetailsEntries[] _emptyArray; + public static CallDetailsEntries[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized (com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new CallDetailsEntries[0]; + } + } + } + return _emptyArray; + } + + // repeated .com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry entries = 1; + public com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry[] entries; + + // @@protoc_insertion_point(class_scope:com.android.dialer.calldetails.CallDetailsEntries) + + public CallDetailsEntries() { + clear(); + } + + public CallDetailsEntries clear() { + entries = com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry.emptyArray(); + unknownFieldData = null; + cachedSize = -1; + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof CallDetailsEntries)) { + return false; + } + CallDetailsEntries other = (CallDetailsEntries) o; + if (!com.google.protobuf.nano.InternalNano.equals(this.entries, other.entries)) { + return false; + } + if (unknownFieldData == null || unknownFieldData.isEmpty()) { + return other.unknownFieldData == null || other.unknownFieldData.isEmpty(); + } else { + return unknownFieldData.equals(other.unknownFieldData); + } + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + getClass().getName().hashCode(); + result = 31 * result + com.google.protobuf.nano.InternalNano.hashCode(this.entries); + result = + 31 * result + + (unknownFieldData == null || unknownFieldData.isEmpty() + ? 0 + : unknownFieldData.hashCode()); + return result; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.entries != null && this.entries.length > 0) { + for (int i = 0; i < this.entries.length; i++) { + com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry element = + this.entries[i]; + if (element != null) { + output.writeMessage(1, element); + } + } + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.entries != null && this.entries.length > 0) { + for (int i = 0; i < this.entries.length; i++) { + com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry element = + this.entries[i]; + if (element != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano.computeMessageSize(1, element); + } + } + } + return size; + } + + @Override + public CallDetailsEntries mergeFrom(com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: + { + if (!super.storeUnknownField(input, tag)) { + return this; + } + break; + } + case 10: + { + int arrayLength = + com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, 10); + int i = this.entries == null ? 0 : this.entries.length; + com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry[] newArray = + new com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry + [i + arrayLength]; + if (i != 0) { + java.lang.System.arraycopy(this.entries, 0, newArray, 0, i); + } + for (; i < newArray.length - 1; i++) { + newArray[i] = + new com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry(); + input.readMessage(newArray[i]); + input.readTag(); + } + // Last one without readTag. + newArray[i] = + new com.android.dialer.calldetails.nano.CallDetailsEntries.CallDetailsEntry(); + input.readMessage(newArray[i]); + this.entries = newArray; + break; + } + } + } + } + + public static CallDetailsEntries parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new CallDetailsEntries(), data); + } + + public static CallDetailsEntries parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) throws java.io.IOException { + return new CallDetailsEntries().mergeFrom(input); + } +} diff --git a/java/com/android/dialer/calldetails/res/drawable/multimedia_image_background.xml b/java/com/android/dialer/calldetails/res/drawable/multimedia_image_background.xml new file mode 100644 index 000000000..421bdbfee --- /dev/null +++ b/java/com/android/dialer/calldetails/res/drawable/multimedia_image_background.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="2dp"/> +</shape> diff --git a/java/com/android/dialer/calldetails/res/layout/call_details_activity.xml b/java/com/android/dialer/calldetails/res/layout/call_details_activity.xml new file mode 100644 index 000000000..038a8745e --- /dev/null +++ b/java/com/android/dialer/calldetails/res/layout/call_details_activity.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="@color/dialer_theme_color" + android:elevation="4dp" + android:titleTextAppearance="@style/toolbar_title_text" + android:title="@string/call_details" + android:navigationIcon="@drawable/quantum_ic_arrow_back_white_24"/> + + <android.support.v7.widget.RecyclerView + android:id="@+id/recycler_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/background_dialer_white"/> +</LinearLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/layout/call_details_entry.xml b/java/com/android/dialer/calldetails/res/layout/call_details_entry.xml new file mode 100644 index 000000000..7f8bb8087 --- /dev/null +++ b/java/com/android/dialer/calldetails/res/layout/call_details_entry.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="@dimen/call_entry_padding"> + + <ImageView + android:id="@+id/call_direction" + android:layout_width="@dimen/call_entry_icon_size" + android:layout_height="@dimen/call_entry_icon_size" + android:layout_marginStart="@dimen/call_entry_padding" + android:layout_marginEnd="@dimen/call_entry_left_margin"/> + + <TextView + android:id="@+id/call_type" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@+id/call_direction" + style="@style/PrimaryText"/> + + <TextView + android:id="@+id/call_time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toEndOf="@id/call_direction" + android:layout_below="@+id/call_type" + android:layout_marginBottom="@dimen/call_entry_bottom_padding" + style="@style/SecondaryText"/> + + <TextView + android:id="@+id/call_duration" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/call_entry_padding" + style="@style/PrimaryText"/> + + <include + layout="@layout/ec_data_container" + android:id="@+id/ec_container" + android:layout_height="@dimen/ec_container_height" + android:layout_width="match_parent" + android:layout_marginStart="@dimen/ec_text_left_margin" + android:layout_below="@+id/call_time" + android:visibility="gone"/> + + <View + android:id="@+id/divider" + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_below="@id/ec_container" + android:layout_marginTop="@dimen/ec_divider_top_bottom_margin" + android:layout_marginBottom="@dimen/ec_divider_top_bottom_margin" + android:layout_marginStart="@dimen/ec_text_left_margin" + android:background="#12000000" + android:visibility="gone"/> +</RelativeLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/layout/call_details_footer.xml b/java/com/android/dialer/calldetails/res/layout/call_details_footer.xml new file mode 100644 index 000000000..885cb0989 --- /dev/null +++ b/java/com/android/dialer/calldetails/res/layout/call_details_footer.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginTop="@dimen/ec_divider_top_bottom_margin" + android:layout_marginBottom="@dimen/ec_divider_top_bottom_margin" + android:background="#12000000"/> + + <TextView + android:id="@+id/call_detail_action_copy" + style="@style/CallDetailsActionItemStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableStart="@drawable/quantum_ic_content_copy_grey600_24" + android:text="@string/call_details_copy_number"/> + + <TextView + android:id="@+id/call_detail_action_edit_before_call" + style="@style/CallDetailsActionItemStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:drawableStart="@drawable/quantum_ic_edit_grey600_24" + android:text="@string/call_details_edit_number"/> +</LinearLayout> diff --git a/java/com/android/dialer/calldetails/res/layout/contact_container.xml b/java/com/android/dialer/calldetails/res/layout/contact_container.xml new file mode 100644 index 000000000..95fe189b2 --- /dev/null +++ b/java/com/android/dialer/calldetails/res/layout/contact_container.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:padding="@dimen/contact_container_padding"> + + <QuickContactBadge + android:id="@+id/quick_contact_photo" + android:layout_width="@dimen/call_details_contact_photo_size" + android:layout_height="@dimen/call_details_contact_photo_size" + android:focusable="true"/> + + <TextView + android:id="@+id/contact_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/text_bottom_margin" + android:layout_marginStart="@dimen/photo_text_margin" + android:layout_toEndOf="@+id/quick_contact_photo" + android:layout_toStartOf="@+id/call_back_button" + style="@style/PrimaryText"/> + + <TextView + android:id="@+id/phone_number" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/photo_text_margin" + android:layout_toEndOf="@+id/quick_contact_photo" + android:layout_toStartOf="@+id/call_back_button" + android:layout_below="@+id/contact_name" + style="@style/SecondaryText"/> + + <ImageView + android:id="@+id/call_back_button" + android:layout_width="@dimen/call_back_button_size" + android:layout_height="@dimen/call_back_button_size" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@string/description_call_log_call_action" + android:src="@drawable/quantum_ic_call_white_24" + android:tint="@color/secondary_text_color"/> +</RelativeLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/layout/ec_data_container.xml b/java/com/android/dialer/calldetails/res/layout/ec_data_container.xml new file mode 100644 index 000000000..5ad7912fa --- /dev/null +++ b/java/com/android/dialer/calldetails/res/layout/ec_data_container.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/ec_container_height"> + + <TextView + android:id="@+id/multimedia_details" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:maxLines="2" + style="@style/SecondaryText"/> + + <FrameLayout + android:id="@+id/multimedia_image_container" + android:layout_width="@dimen/ec_photo_size" + android:layout_height="@dimen/ec_photo_size" + android:layout_alignParentEnd="true" + android:layout_marginEnd="@dimen/call_entry_padding" + android:layout_centerVertical="true" + android:background="@drawable/multimedia_image_background" + android:outlineProvider="background" + android:visibility="gone"> + + <ImageView + android:id="@+id/multimedia_image" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="centerCrop"/> + + <com.android.incallui.autoresizetext.AutoResizeTextView + android:id="@+id/multimedia_attachments_number" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="4dp" + android:gravity="center" + android:textColor="@color/background_dialer_white" + android:textSize="100sp" + android:background="#80000000" + android:visibility="gone"/> + </FrameLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/menu/call_details_menu.xml b/java/com/android/dialer/calldetails/res/menu/call_details_menu.xml new file mode 100644 index 000000000..c2d1032da --- /dev/null +++ b/java/com/android/dialer/calldetails/res/menu/call_details_menu.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/call_detail_delete_menu_item" + android:icon="@drawable/quantum_ic_delete_white_24" + android:title="@string/delete" + android:showAsAction="ifRoom"/> +</menu>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/values/dimens.xml b/java/com/android/dialer/calldetails/res/values/dimens.xml new file mode 100644 index 000000000..b1a8f1c8e --- /dev/null +++ b/java/com/android/dialer/calldetails/res/values/dimens.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<resources> + <dimen name="text_bottom_margin">2dp</dimen> + <dimen name="call_details_primary_text_size">16sp</dimen> + <dimen name="call_details_secondary_text_size">14sp</dimen> + + <!-- contact container --> + <dimen name="contact_container_padding">16dp</dimen> + <dimen name="call_details_contact_photo_size">40dp</dimen> + <dimen name="photo_text_margin">16dp</dimen> + <dimen name="call_back_button_size">24dp</dimen> + + <!-- call entry container --> + <dimen name="call_entry_icon_size">24dp</dimen> + <dimen name="call_entry_padding">16dp</dimen> + <dimen name="call_entry_bottom_padding">14dp</dimen> + <dimen name="call_entry_left_margin">32dp</dimen> + + <!-- EC container --> + <dimen name="call_details_ec_text_size">12sp</dimen> + <dimen name="ec_container_height">48dp</dimen> + <dimen name="ec_text_left_margin">72dp</dimen> + <dimen name="ec_photo_size">40dp</dimen> + <dimen name="ec_divider_top_bottom_margin">8dp</dimen> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/calldetails/res/values/strings.xml b/java/com/android/dialer/calldetails/res/values/strings.xml new file mode 100644 index 000000000..8a7cc4cfc --- /dev/null +++ b/java/com/android/dialer/calldetails/res/values/strings.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Title bar for call detail screen --> + <string name="call_details">Call details</string> + + <!-- Menu item in call details used to remove a call or voicemail from the call log. --> + <string name="delete">Delete</string> + + <!-- Option displayed in context menu to copy long pressed phone number. [CHAR LIMIT=48] --> + <string name="call_details_copy_number">Copy number</string> + + <!-- Label for action to edit a number before calling it. [CHAR LIMIT=48] --> + <string name="call_details_edit_number">Edit number before call</string> + + <!-- String describing the phone icon on a call log list item. When tapped, it will place a + call to the number represented by that call log entry. [CHAR LIMIT=NONE]--> + <string name="description_call_log_call_action">Call</string> + + <!-- String shown when the call details show a image that was sent --> + <string name="sent_a_photo">Sent a photo</string> + + <!-- String shown when the call details show a image that was received --> + <string name="received_a_photo">Received a photo</string> + + <!-- Messages shown to the user are wrapped in quotes, e.g. the user would see "Some text" --> + <string name="message_in_quotes">\"<xliff:g id="message">%1$s</xliff:g>\"</string> +</resources> diff --git a/java/com/android/dialer/calldetails/res/values/styles.xml b/java/com/android/dialer/calldetails/res/values/styles.xml new file mode 100644 index 000000000..4fffe1afb --- /dev/null +++ b/java/com/android/dialer/calldetails/res/values/styles.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2017 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 + --> +<resources> + <style name="PrimaryText"> + <item name="android:textColor">#DE000000</item> + <item name="android:textSize">@dimen/call_details_primary_text_size</item> + <item name="android:maxLines">1</item> + </style> + + <style name="SecondaryText"> + <item name="android:textColor">#8A000000</item> + <item name="android:textSize">@dimen/call_details_secondary_text_size</item> + <item name="android:maxLines">1</item> + </style> + + <style name="ECText"> + <item name="android:textColor">#8A000000</item> + <item name="android:textSize">@dimen/call_details_ec_text_size</item> + <item name="android:maxLines">1</item> + </style> + + <style name="CallDetailsActionItemStyle"> + <item name="android:foreground">?android:attr/selectableItemBackground</item> + <item name="android:clickable">true</item> + <item name="android:drawablePadding">28dp</item> + <item name="android:gravity">center_vertical</item> + <item name="android:paddingStart">28dp</item> + <item name="android:paddingEnd">28dp</item> + <item name="android:paddingTop">16dp</item> + <item name="android:paddingBottom">16dp</item> + <item name="android:textColor">#8A000000</item> + <item name="android:textSize">14sp</item> + </style> +</resources>
\ No newline at end of file |