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.dialer.main.impl.bottomnav;
18 
19 import android.content.Context;
20 import android.support.annotation.IntDef;
21 import android.support.annotation.Nullable;
22 import android.util.AttributeSet;
23 import android.view.View;
24 import android.widget.LinearLayout;
25 import com.android.dialer.common.Assert;
26 import com.android.dialer.common.LogUtil;
27 import com.android.dialer.logging.DialerImpression;
28 import com.android.dialer.logging.Logger;
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.ArrayList;
32 import java.util.List;
33 
34 /** Dialer Bottom Nav Bar for {@link MainActivity}. */
35 public final class BottomNavBar extends LinearLayout {
36 
37   /** Index for each tab in the bottom nav. */
38   @Retention(RetentionPolicy.SOURCE)
39   @IntDef({
40     TabIndex.SPEED_DIAL,
41     TabIndex.CALL_LOG,
42     TabIndex.CONTACTS,
43     TabIndex.VOICEMAIL,
44   })
45   public @interface TabIndex {
46     int SPEED_DIAL = 0;
47     int CALL_LOG = 1;
48     int CONTACTS = 2;
49     int VOICEMAIL = 3;
50   }
51 
52   private final List<OnBottomNavTabSelectedListener> listeners = new ArrayList<>();
53 
54   private BottomNavItem speedDial;
55   private BottomNavItem callLog;
56   private BottomNavItem contacts;
57   private BottomNavItem voicemail;
58   private @TabIndex int selectedTab;
59 
BottomNavBar(Context context, @Nullable AttributeSet attrs)60   public BottomNavBar(Context context, @Nullable AttributeSet attrs) {
61     super(context, attrs);
62   }
63 
64   @Override
onFinishInflate()65   protected void onFinishInflate() {
66     super.onFinishInflate();
67     speedDial = findViewById(R.id.speed_dial_tab);
68     callLog = findViewById(R.id.call_log_tab);
69     contacts = findViewById(R.id.contacts_tab);
70     voicemail = findViewById(R.id.voicemail_tab);
71 
72     speedDial.setup(R.string.tab_title_speed_dial, R.drawable.quantum_ic_star_vd_theme_24);
73     callLog.setup(R.string.tab_title_call_history, R.drawable.quantum_ic_access_time_vd_theme_24);
74     contacts.setup(R.string.tab_title_contacts, R.drawable.quantum_ic_people_vd_theme_24);
75     voicemail.setup(R.string.tab_title_voicemail, R.drawable.quantum_ic_voicemail_vd_theme_24);
76 
77     speedDial.setOnClickListener(
78         v -> {
79           if (selectedTab != TabIndex.SPEED_DIAL) {
80             Logger.get(getContext())
81                 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_FAVORITE);
82           }
83           selectTab(TabIndex.SPEED_DIAL);
84         });
85     callLog.setOnClickListener(
86         v -> {
87           if (selectedTab != TabIndex.CALL_LOG) {
88             Logger.get(getContext())
89                 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_CALL_LOG);
90           }
91           selectTab(TabIndex.CALL_LOG);
92         });
93     contacts.setOnClickListener(
94         v -> {
95           if (selectedTab != TabIndex.CONTACTS) {
96             Logger.get(getContext())
97                 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_CONTACTS);
98           }
99           selectTab(TabIndex.CONTACTS);
100         });
101     voicemail.setOnClickListener(
102         v -> {
103           if (selectedTab != TabIndex.VOICEMAIL) {
104             Logger.get(getContext())
105                 .logImpression(DialerImpression.Type.MAIN_SWITCH_TAB_TO_VOICEMAIL);
106           }
107           selectTab(TabIndex.VOICEMAIL);
108         });
109   }
110 
setSelected(View view)111   private void setSelected(View view) {
112     speedDial.setSelected(view == speedDial);
113     callLog.setSelected(view == callLog);
114     contacts.setSelected(view == contacts);
115     voicemail.setSelected(view == voicemail);
116   }
117 
118   /**
119    * Select tab for uesr and non-user click.
120    *
121    * @param tab {@link TabIndex}
122    */
selectTab(@abIndex int tab)123   public void selectTab(@TabIndex int tab) {
124     if (tab == TabIndex.SPEED_DIAL) {
125       selectedTab = TabIndex.SPEED_DIAL;
126       setSelected(speedDial);
127     } else if (tab == TabIndex.CALL_LOG) {
128       selectedTab = TabIndex.CALL_LOG;
129       setSelected(callLog);
130     } else if (tab == TabIndex.CONTACTS) {
131       selectedTab = TabIndex.CONTACTS;
132       setSelected(contacts);
133     } else if (tab == TabIndex.VOICEMAIL) {
134       selectedTab = TabIndex.VOICEMAIL;
135       setSelected(voicemail);
136     } else {
137       throw new IllegalStateException("Invalid tab: " + tab);
138     }
139 
140     updateListeners(selectedTab);
141   }
142 
143   /**
144    * Displays or hides the voicemail tab.
145    *
146    * <p>In the event that the voicemail tab was earlier visible but is now no longer visible, we
147    * move to the speed dial tab.
148    *
149    * @param showTab whether to hide or show the voicemail
150    */
showVoicemail(boolean showTab)151   public void showVoicemail(boolean showTab) {
152     LogUtil.i("OldMainActivityPeer.showVoicemail", "showing Tab:%b", showTab);
153     int voicemailpreviousVisibility = voicemail.getVisibility();
154     voicemail.setVisibility(showTab ? View.VISIBLE : View.GONE);
155     int voicemailcurrentVisibility = voicemail.getVisibility();
156 
157     if (voicemailpreviousVisibility != voicemailcurrentVisibility
158         && voicemailpreviousVisibility == View.VISIBLE
159         && getSelectedTab() == TabIndex.VOICEMAIL) {
160       LogUtil.i("OldMainActivityPeer.showVoicemail", "hid VM tab and moved to speed dial tab");
161       selectTab(TabIndex.SPEED_DIAL);
162     }
163   }
164 
setNotificationCount(@abIndex int tab, int count)165   public void setNotificationCount(@TabIndex int tab, int count) {
166     if (tab == TabIndex.SPEED_DIAL) {
167       speedDial.setNotificationCount(count);
168     } else if (tab == TabIndex.CALL_LOG) {
169       callLog.setNotificationCount(count);
170     } else if (tab == TabIndex.CONTACTS) {
171       contacts.setNotificationCount(count);
172     } else if (tab == TabIndex.VOICEMAIL) {
173       voicemail.setNotificationCount(count);
174     } else {
175       throw new IllegalStateException("Invalid tab: " + tab);
176     }
177   }
178 
addOnTabSelectedListener(OnBottomNavTabSelectedListener listener)179   public void addOnTabSelectedListener(OnBottomNavTabSelectedListener listener) {
180     listeners.add(listener);
181   }
182 
updateListeners(@abIndex int tabIndex)183   private void updateListeners(@TabIndex int tabIndex) {
184     for (OnBottomNavTabSelectedListener listener : listeners) {
185       switch (tabIndex) {
186         case TabIndex.SPEED_DIAL:
187           listener.onSpeedDialSelected();
188           break;
189         case TabIndex.CALL_LOG:
190           listener.onCallLogSelected();
191           break;
192         case TabIndex.CONTACTS:
193           listener.onContactsSelected();
194           break;
195         case TabIndex.VOICEMAIL:
196           listener.onVoicemailSelected();
197           break;
198         default:
199           throw Assert.createIllegalStateFailException("Invalid tab: " + tabIndex);
200       }
201     }
202   }
203 
204   @TabIndex
getSelectedTab()205   public int getSelectedTab() {
206     return selectedTab;
207   }
208 
209   /** Listener for bottom nav tab's on click events. */
210   public interface OnBottomNavTabSelectedListener {
211 
212     /** Speed dial tab was clicked. */
onSpeedDialSelected()213     void onSpeedDialSelected();
214 
215     /** Call Log tab was clicked. */
onCallLogSelected()216     void onCallLogSelected();
217 
218     /** Contacts tab was clicked. */
onContactsSelected()219     void onContactsSelected();
220 
221     /** Voicemail tab was clicked. */
onVoicemailSelected()222     void onVoicemailSelected();
223   }
224 }
225