1 /* 2 * Copyright (C) 2018 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.incallui; 18 19 import android.app.AlertDialog; 20 import android.app.Dialog; 21 import android.content.Context; 22 import android.os.Bundle; 23 import android.support.annotation.NonNull; 24 import android.support.v4.app.DialogFragment; 25 import android.telephony.PhoneNumberUtils; 26 import android.text.BidiFormatter; 27 import android.text.TextDirectionHeuristics; 28 import android.text.TextUtils; 29 import android.view.View; 30 import android.widget.TextView; 31 import com.android.dialer.common.Assert; 32 import com.android.dialer.common.LogUtil; 33 import com.android.dialer.contacts.ContactsComponent; 34 import com.android.incallui.ContactInfoCache.ContactCacheEntry; 35 import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback; 36 import com.android.incallui.call.CallList; 37 import com.android.incallui.call.DialerCall; 38 import java.lang.ref.WeakReference; 39 40 /** Dialog that shown to user when receiving RTT request mid call. */ 41 public class RttRequestDialogFragment extends DialogFragment { 42 43 /** 44 * Returns a new instance of {@link RttRequestDialogFragment} with the given callback. 45 * 46 * <p>Prefer this method over the default constructor. 47 */ newInstance(String callId, int rttRequestId)48 public static RttRequestDialogFragment newInstance(String callId, int rttRequestId) { 49 RttRequestDialogFragment fragment = new RttRequestDialogFragment(); 50 Bundle args = new Bundle(); 51 args.putString(ARG_CALL_ID, Assert.isNotNull(callId)); 52 args.putInt(ARG_RTT_REQUEST_ID, rttRequestId); 53 fragment.setArguments(args); 54 return fragment; 55 } 56 57 /** Key in the arguments bundle for call id. */ 58 private static final String ARG_CALL_ID = "call_id"; 59 60 private static final String ARG_RTT_REQUEST_ID = "rtt_request_id"; 61 62 private TextView detailsTextView; 63 64 @NonNull 65 @Override onCreateDialog(Bundle bundle)66 public Dialog onCreateDialog(Bundle bundle) { 67 super.onCreateDialog(bundle); 68 LogUtil.enterBlock("RttRequestDialogFragment.onCreateDialog"); 69 70 View dialogView = View.inflate(getActivity(), R.layout.frag_rtt_request_dialog, null); 71 detailsTextView = dialogView.findViewById(R.id.details); 72 73 ContactInfoCache cache = ContactInfoCache.getInstance(getContext()); 74 DialerCall dialerCall = 75 CallList.getInstance().getCallById(getArguments().getString(ARG_CALL_ID)); 76 cache.findInfo(dialerCall, false, new ContactLookupCallback(this)); 77 78 dialogView 79 .findViewById(R.id.rtt_button_decline_request) 80 .setOnClickListener(v -> onNegativeButtonClick()); 81 dialogView 82 .findViewById(R.id.rtt_button_accept_request) 83 .setOnClickListener(v -> onPositiveButtonClick()); 84 85 AlertDialog alertDialog = 86 new AlertDialog.Builder(getActivity()) 87 .setCancelable(false) 88 .setView(dialogView) 89 .setTitle(R.string.rtt_request_dialog_title) 90 .create(); 91 92 alertDialog.setCanceledOnTouchOutside(false); 93 return alertDialog; 94 } 95 onPositiveButtonClick()96 private void onPositiveButtonClick() { 97 LogUtil.enterBlock("RttRequestDialogFragment.onPositiveButtonClick"); 98 99 DialerCall call = CallList.getInstance().getCallById(getArguments().getString(ARG_CALL_ID)); 100 call.respondToRttRequest(true, getArguments().getInt(ARG_RTT_REQUEST_ID)); 101 dismiss(); 102 } 103 onNegativeButtonClick()104 private void onNegativeButtonClick() { 105 LogUtil.enterBlock("RttRequestDialogFragment.onNegativeButtonClick"); 106 107 DialerCall call = CallList.getInstance().getCallById(getArguments().getString(ARG_CALL_ID)); 108 call.respondToRttRequest(false, getArguments().getInt(ARG_RTT_REQUEST_ID)); 109 dismiss(); 110 } 111 setNameOrNumber(CharSequence nameOrNumber)112 private void setNameOrNumber(CharSequence nameOrNumber) { 113 detailsTextView.setText(getString(R.string.rtt_request_dialog_details, nameOrNumber)); 114 } 115 116 private static class ContactLookupCallback implements ContactInfoCacheCallback { 117 private final WeakReference<RttRequestDialogFragment> rttRequestDialogFragmentWeakReference; 118 ContactLookupCallback(RttRequestDialogFragment rttRequestDialogFragment)119 private ContactLookupCallback(RttRequestDialogFragment rttRequestDialogFragment) { 120 rttRequestDialogFragmentWeakReference = new WeakReference<>(rttRequestDialogFragment); 121 } 122 123 @Override onContactInfoComplete(String callId, ContactCacheEntry entry)124 public void onContactInfoComplete(String callId, ContactCacheEntry entry) { 125 RttRequestDialogFragment fragment = rttRequestDialogFragmentWeakReference.get(); 126 if (fragment != null) { 127 fragment.setNameOrNumber(getNameOrNumber(entry, fragment.getContext())); 128 } 129 } 130 getNameOrNumber(ContactCacheEntry entry, Context context)131 private CharSequence getNameOrNumber(ContactCacheEntry entry, Context context) { 132 String preferredName = 133 ContactsComponent.get(context) 134 .contactDisplayPreferences() 135 .getDisplayName(entry.namePrimary, entry.nameAlternative); 136 if (TextUtils.isEmpty(preferredName)) { 137 return TextUtils.isEmpty(entry.number) 138 ? null 139 : PhoneNumberUtils.createTtsSpannable( 140 BidiFormatter.getInstance().unicodeWrap(entry.number, TextDirectionHeuristics.LTR)); 141 } 142 return preferredName; 143 } 144 145 @Override onImageLoadComplete(String callId, ContactCacheEntry entry)146 public void onImageLoadComplete(String callId, ContactCacheEntry entry) {} 147 } 148 } 149