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