blob: dbfce631da94fce32ad92006705454caffc9c19b [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
* Copyright (C) 2023 The LineageOS 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.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.TextView;
import androidx.annotation.WorkerThread;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import com.android.dialer.R;
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.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 {
private static final String FRAGMENT_TAG = "disambig_dialog";
private final Set<String> phoneNumbers = new ArraySet<>();
private SpeedDialUiItem speedDialUiItem;
private List<Channel> channels;
private LinearLayout container;
private 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().setBackgroundDrawable(
ResourcesCompat.getDrawable(requireActivity().getResources(),
R.drawable.dialog_background, requireActivity().getTheme()));
}
@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) {
insertOption(container, channel);
}
}
private void insertOption(LinearLayout container, Channel channel) {
View view = getActivity()
.getLayoutInflater()
.inflate(R.layout.disambig_option_layout, container, false);
View option = view.findViewById(R.id.option_container);
if (channel.isVideoTechnology()) {
option.setOnClickListener(v -> onVideoOptionClicked(channel));
option.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);
} else {
option.setOnClickListener(v -> onVoiceOptionClicked(channel));
option.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) option.findViewById(R.id.speed_dial_label)).setText(channel.label());
((TextView) option.findViewById(R.id.speed_dial_number)).setText(channel.number());
container.addView(view);
}
private void onVideoOptionClicked(Channel channel) {
if (rememberThisChoice.isChecked()) {
setDefaultChannel(getContext().getApplicationContext(), speedDialUiItem, channel);
}
PreCall.start(
getContext(),
new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL_DISAMBIG_DIALOG)
.setAllowAssistedDial(true)
.setIsVideoCall(true));
dismiss();
}
private void onVoiceOptionClicked(Channel channel) {
if (rememberThisChoice.isChecked()) {
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));
}
}