239 lines
9.2 KiB
Java
239 lines
9.2 KiB
Java
/*
|
|
* 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.speeddial;
|
|
|
|
import android.app.Dialog;
|
|
import android.content.Context;
|
|
import android.os.Bundle;
|
|
import android.support.annotation.VisibleForTesting;
|
|
import android.support.annotation.WorkerThread;
|
|
import android.support.v4.app.DialogFragment;
|
|
import android.support.v4.app.FragmentManager;
|
|
import android.support.v7.app.AlertDialog;
|
|
import android.text.TextUtils;
|
|
import android.util.ArraySet;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.widget.CheckBox;
|
|
import android.widget.ImageView;
|
|
import android.widget.LinearLayout;
|
|
import android.widget.LinearLayout.LayoutParams;
|
|
import android.widget.TextView;
|
|
import com.android.dialer.callintent.CallInitiationType;
|
|
import com.android.dialer.callintent.CallIntentBuilder;
|
|
import com.android.dialer.common.Assert;
|
|
import com.android.dialer.common.LogUtil;
|
|
import com.android.dialer.common.concurrent.DefaultFutureCallback;
|
|
import com.android.dialer.common.concurrent.DialerExecutorComponent;
|
|
import com.android.dialer.logging.DialerImpression;
|
|
import com.android.dialer.logging.Logger;
|
|
import com.android.dialer.precall.PreCall;
|
|
import com.android.dialer.speeddial.database.SpeedDialEntry;
|
|
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
|
|
import com.android.dialer.speeddial.database.SpeedDialEntryDatabaseHelper;
|
|
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.util.concurrent.Futures;
|
|
import com.google.common.util.concurrent.ListenableFuture;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
/** Disambiguation dialog for favorite contacts in {@link SpeedDialFragment}. */
|
|
public class DisambigDialog extends DialogFragment {
|
|
|
|
@VisibleForTesting public static final String FRAGMENT_TAG = "disambig_dialog";
|
|
private final Set<String> phoneNumbers = new ArraySet<>();
|
|
|
|
private SpeedDialUiItem speedDialUiItem;
|
|
@VisibleForTesting public List<Channel> channels;
|
|
@VisibleForTesting public LinearLayout container;
|
|
@VisibleForTesting public CheckBox rememberThisChoice;
|
|
|
|
/** Show a disambiguation dialog for a starred contact without a favorite communication avenue. */
|
|
public static DisambigDialog show(SpeedDialUiItem speedDialUiItem, FragmentManager manager) {
|
|
DisambigDialog dialog = new DisambigDialog();
|
|
dialog.speedDialUiItem = speedDialUiItem;
|
|
dialog.channels = speedDialUiItem.channels();
|
|
dialog.show(manager, FRAGMENT_TAG);
|
|
return dialog;
|
|
}
|
|
|
|
@Override
|
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
|
LayoutInflater inflater = getActivity().getLayoutInflater();
|
|
// TODO(calderwoodra): set max height of the scrollview. Might need to override onMeasure.
|
|
View view = inflater.inflate(R.layout.disambig_dialog_layout, null, false);
|
|
container = view.findViewById(R.id.communication_avenue_container);
|
|
rememberThisChoice = view.findViewById(R.id.remember_this_choice_checkbox);
|
|
insertOptions(container.findViewById(R.id.communication_avenue_container), channels);
|
|
return new AlertDialog.Builder(getActivity()).setView(view).create();
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
getDialog()
|
|
.getWindow()
|
|
.setLayout(
|
|
getContext().getResources().getDimensionPixelSize(R.dimen.disambig_dialog_width),
|
|
LayoutParams.WRAP_CONTENT);
|
|
}
|
|
|
|
@Override
|
|
public void onPause() {
|
|
super.onPause();
|
|
// TODO(calderwoodra): for simplicity, just dismiss the dialog on configuration change and
|
|
// consider changing this later.
|
|
dismiss();
|
|
}
|
|
|
|
/**
|
|
* Inflates and inserts the following in the dialog:
|
|
*
|
|
* <ul>
|
|
* <li>Header for each unique phone number
|
|
* <li>Clickable video option if the phone number is video reachable (ViLTE, Duo)
|
|
* <li>Clickable voice option
|
|
* </ul>
|
|
*/
|
|
private void insertOptions(LinearLayout container, List<Channel> channels) {
|
|
for (Channel channel : channels) {
|
|
// TODO(calderwoodra): use fuzzy number matcher
|
|
if (phoneNumbers.add(channel.number())) {
|
|
if (phoneNumbers.size() != 1) {
|
|
insertDivider(container);
|
|
}
|
|
insertHeader(container, channel.number(), channel.label());
|
|
}
|
|
insertOption(container, channel);
|
|
}
|
|
}
|
|
|
|
private void insertDivider(LinearLayout container) {
|
|
View view =
|
|
getActivity()
|
|
.getLayoutInflater()
|
|
.inflate(R.layout.disambig_dialog_divider, container, false);
|
|
container.addView(view);
|
|
}
|
|
|
|
private void insertHeader(LinearLayout container, String number, String label) {
|
|
View view =
|
|
getActivity()
|
|
.getLayoutInflater()
|
|
.inflate(R.layout.disambig_option_header_layout, container, false);
|
|
String secondaryInfo =
|
|
TextUtils.isEmpty(label)
|
|
? number
|
|
: getContext().getString(R.string.call_subject_type_and_number, label, number);
|
|
((TextView) view.findViewById(R.id.disambig_header_phone_label)).setText(secondaryInfo);
|
|
container.addView(view);
|
|
}
|
|
|
|
/** Inserts a group of options for a specific phone number. */
|
|
private void insertOption(LinearLayout container, Channel channel) {
|
|
View view =
|
|
getActivity()
|
|
.getLayoutInflater()
|
|
.inflate(R.layout.disambig_option_layout, container, false);
|
|
if (channel.isVideoTechnology()) {
|
|
View videoOption = view.findViewById(R.id.option_container);
|
|
videoOption.setOnClickListener(v -> onVideoOptionClicked(channel));
|
|
videoOption.setContentDescription(
|
|
getActivity().getString(R.string.disambig_option_video_call));
|
|
((ImageView) view.findViewById(R.id.disambig_option_image))
|
|
.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
|
|
((TextView) view.findViewById(R.id.disambig_option_text))
|
|
.setText(R.string.disambig_option_video_call);
|
|
} else {
|
|
View voiceOption = view.findViewById(R.id.option_container);
|
|
voiceOption.setOnClickListener(v -> onVoiceOptionClicked(channel));
|
|
voiceOption.setContentDescription(
|
|
getActivity().getString(R.string.disambig_option_voice_call));
|
|
((ImageView) view.findViewById(R.id.disambig_option_image))
|
|
.setImageResource(R.drawable.quantum_ic_phone_vd_theme_24);
|
|
((TextView) view.findViewById(R.id.disambig_option_text))
|
|
.setText(R.string.disambig_option_voice_call);
|
|
}
|
|
container.addView(view);
|
|
}
|
|
|
|
private void onVideoOptionClicked(Channel channel) {
|
|
if (rememberThisChoice.isChecked()) {
|
|
Logger.get(getContext()).logImpression(DialerImpression.Type.FAVORITE_SET_VIDEO_DEFAULT);
|
|
setDefaultChannel(getContext().getApplicationContext(), speedDialUiItem, channel);
|
|
}
|
|
|
|
if (channel.technology() == Channel.DUO) {
|
|
Logger.get(getContext())
|
|
.logImpression(
|
|
DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT_DISAMBIG);
|
|
}
|
|
|
|
PreCall.start(
|
|
getContext(),
|
|
new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL_DISAMBIG_DIALOG)
|
|
.setAllowAssistedDial(true)
|
|
.setIsVideoCall(true)
|
|
.setIsDuoCall(channel.technology() == Channel.DUO));
|
|
dismiss();
|
|
}
|
|
|
|
private void onVoiceOptionClicked(Channel channel) {
|
|
if (rememberThisChoice.isChecked()) {
|
|
Logger.get(getContext()).logImpression(DialerImpression.Type.FAVORITE_SET_VOICE_DEFAULT);
|
|
setDefaultChannel(getContext().getApplicationContext(), speedDialUiItem, channel);
|
|
}
|
|
|
|
PreCall.start(
|
|
getContext(),
|
|
new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL_DISAMBIG_DIALOG)
|
|
.setAllowAssistedDial(true));
|
|
dismiss();
|
|
}
|
|
|
|
private static void setDefaultChannel(Context appContext, SpeedDialUiItem item, Channel channel) {
|
|
LogUtil.enterBlock("DisambigDialog.setDefaultChannel");
|
|
ListenableFuture<Void> future =
|
|
DialerExecutorComponent.get(appContext)
|
|
.backgroundExecutor()
|
|
.submit(
|
|
() -> {
|
|
updateDatabaseEntry(appContext, item, channel);
|
|
return null;
|
|
});
|
|
Futures.addCallback(
|
|
future,
|
|
new DefaultFutureCallback<>(),
|
|
DialerExecutorComponent.get(appContext).backgroundExecutor());
|
|
}
|
|
|
|
@WorkerThread
|
|
private static void updateDatabaseEntry(
|
|
Context appContext, SpeedDialUiItem item, Channel channel) {
|
|
Assert.isWorkerThread();
|
|
SpeedDialEntry entry =
|
|
SpeedDialEntry.builder()
|
|
.setId(item.speedDialEntryId())
|
|
.setContactId(item.contactId())
|
|
.setLookupKey(item.lookupKey())
|
|
.setDefaultChannel(channel)
|
|
.build();
|
|
new SpeedDialEntryDatabaseHelper(appContext).update(ImmutableList.of(entry));
|
|
}
|
|
}
|