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