• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.contactgrid;
18 
19 import android.content.Context;
20 import android.support.annotation.Nullable;
21 import android.telephony.PhoneNumberUtils;
22 import android.text.BidiFormatter;
23 import android.text.TextDirectionHeuristics;
24 import android.text.TextUtils;
25 import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
26 import com.android.incallui.call.DialerCall.State;
27 import com.android.incallui.incall.protocol.PrimaryCallState;
28 import com.android.incallui.incall.protocol.PrimaryInfo;
29 
30 /**
31  * Gets the content of the bottom row. For example:
32  *
33  * <ul>
34  *   <li>Mobile +1 (650) 253-0000
35  *   <li>[HD attempting icon]/[HD icon] 00:15
36  *   <li>Call ended
37  *   <li>Hanging up
38  * </ul>
39  */
40 public class BottomRow {
41 
42   /** Content of the bottom row. */
43   public static class Info {
44 
45     @Nullable public final CharSequence label;
46     public final boolean isTimerVisible;
47     public final boolean isWorkIconVisible;
48     public final boolean isHdAttemptingIconVisible;
49     public final boolean isHdIconVisible;
50     public final boolean isForwardIconVisible;
51     public final boolean isSpamIconVisible;
52     public final boolean shouldPopulateAccessibilityEvent;
53 
Info( @ullable CharSequence label, boolean isTimerVisible, boolean isWorkIconVisible, boolean isHdAttemptingIconVisible, boolean isHdIconVisible, boolean isForwardIconVisible, boolean isSpamIconVisible, boolean shouldPopulateAccessibilityEvent)54     public Info(
55         @Nullable CharSequence label,
56         boolean isTimerVisible,
57         boolean isWorkIconVisible,
58         boolean isHdAttemptingIconVisible,
59         boolean isHdIconVisible,
60         boolean isForwardIconVisible,
61         boolean isSpamIconVisible,
62         boolean shouldPopulateAccessibilityEvent) {
63       this.label = label;
64       this.isTimerVisible = isTimerVisible;
65       this.isWorkIconVisible = isWorkIconVisible;
66       this.isHdAttemptingIconVisible = isHdAttemptingIconVisible;
67       this.isHdIconVisible = isHdIconVisible;
68       this.isForwardIconVisible = isForwardIconVisible;
69       this.isSpamIconVisible = isSpamIconVisible;
70       this.shouldPopulateAccessibilityEvent = shouldPopulateAccessibilityEvent;
71     }
72   }
73 
BottomRow()74   private BottomRow() {}
75 
getInfo(Context context, PrimaryCallState state, PrimaryInfo primaryInfo)76   public static Info getInfo(Context context, PrimaryCallState state, PrimaryInfo primaryInfo) {
77     CharSequence label;
78     boolean isTimerVisible = state.state == State.ACTIVE;
79     boolean isForwardIconVisible = state.isForwardedNumber;
80     boolean isWorkIconVisible = state.isWorkCall;
81     boolean isHdIconVisible = state.isHdAudioCall && !isForwardIconVisible;
82     boolean isHdAttemptingIconVisible = state.isHdAttempting;
83     boolean isSpamIconVisible = false;
84     boolean shouldPopulateAccessibilityEvent = true;
85 
86     if (isIncoming(state) && primaryInfo.isSpam) {
87       label = context.getString(R.string.contact_grid_incoming_suspected_spam);
88       isSpamIconVisible = true;
89       isHdIconVisible = false;
90     } else if (state.state == State.DISCONNECTING) {
91       // While in the DISCONNECTING state we display a "Hanging up" message in order to make the UI
92       // feel more responsive.  (In GSM it's normal to see a delay of a couple of seconds while
93       // negotiating the disconnect with the network, so the "Hanging up" state at least lets the
94       // user know that we're doing something.  This state is currently not used with CDMA.)
95       label = context.getString(R.string.incall_hanging_up);
96     } else if (state.state == State.DISCONNECTED) {
97       label = state.disconnectCause.getLabel();
98       if (TextUtils.isEmpty(label)) {
99         label = context.getString(R.string.incall_call_ended);
100       }
101     } else if (!TextUtils.isEmpty(state.callbackNumber)) {
102       // This is used for carriers like Project Fi to show the callback number for emergency calls.
103       label =
104           context.getString(
105               R.string.contact_grid_callback_number,
106               PhoneNumberUtils.formatNumber(state.callbackNumber));
107       isTimerVisible = false;
108     } else {
109       label = getLabelForPhoneNumber(primaryInfo);
110       shouldPopulateAccessibilityEvent = primaryInfo.nameIsNumber;
111     }
112 
113     return new Info(
114         label,
115         isTimerVisible,
116         isWorkIconVisible,
117         isHdAttemptingIconVisible,
118         isHdIconVisible,
119         isForwardIconVisible,
120         isSpamIconVisible,
121         shouldPopulateAccessibilityEvent);
122   }
123 
getLabelForPhoneNumber(PrimaryInfo primaryInfo)124   private static CharSequence getLabelForPhoneNumber(PrimaryInfo primaryInfo) {
125     if (primaryInfo.location != null) {
126       return primaryInfo.location;
127     }
128     if (!TextUtils.isEmpty(primaryInfo.number)) {
129       CharSequence spannedNumber = spanDisplayNumber(primaryInfo.number);
130       if (primaryInfo.label == null) {
131         return spannedNumber;
132       } else {
133         return TextUtils.concat(primaryInfo.label, " ", spannedNumber);
134       }
135     }
136     return null;
137   }
138 
spanDisplayNumber(String displayNumber)139   private static CharSequence spanDisplayNumber(String displayNumber) {
140     return PhoneNumberUtilsCompat.createTtsSpannable(
141         BidiFormatter.getInstance().unicodeWrap(displayNumber, TextDirectionHeuristics.LTR));
142   }
143 
isIncoming(PrimaryCallState state)144   private static boolean isIncoming(PrimaryCallState state) {
145     return state.state == State.INCOMING || state.state == State.CALL_WAITING;
146   }
147 }
148