1 /*
2  * Copyright (C) 2019 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.car.dialer.ui;
18 
19 import android.content.Context;
20 import android.graphics.drawable.Drawable;
21 
22 import androidx.annotation.Nullable;
23 import androidx.annotation.StringDef;
24 import androidx.fragment.app.Fragment;
25 import androidx.fragment.app.FragmentManager;
26 
27 import com.android.car.dialer.R;
28 import com.android.car.dialer.ui.calllog.CallHistoryFragment;
29 import com.android.car.dialer.ui.contact.ContactListFragment;
30 import com.android.car.dialer.ui.dialpad.DialpadFragment;
31 import com.android.car.dialer.ui.favorite.FavoriteFragment;
32 import com.android.car.ui.toolbar.TabLayout;
33 
34 import com.google.common.collect.ImmutableMap;
35 
36 import java.util.HashMap;
37 import java.util.Map;
38 
39 /**
40  * Tab presenting fragments.
41  */
42 public class TelecomPageTab extends TabLayout.Tab {
43 
44     /**
45      * Note: the strings must be consist with the items in string array tabs_config
46      */
47     @StringDef({
48             TelecomPageTab.Page.FAVORITES,
49             TelecomPageTab.Page.CALL_HISTORY,
50             TelecomPageTab.Page.CONTACTS,
51             TelecomPageTab.Page.DIAL_PAD
52     })
53     public @interface Page {
54         String FAVORITES = "FAVORITE";
55         String CALL_HISTORY = "CALL_HISTORY";
56         String CONTACTS = "CONTACTS";
57         String DIAL_PAD = "DIAL_PAD";
58     }
59 
60     private final Factory mFactory;
61     private Fragment mFragment;
62     private String mFragmentTag;
63     private boolean mWasFragmentRestored;
64 
TelecomPageTab(@ullable Drawable icon, @Nullable CharSequence text, Factory factory)65     private TelecomPageTab(@Nullable Drawable icon, @Nullable CharSequence text, Factory factory) {
66         super(icon, text);
67         mFactory = factory;
68     }
69 
70     /**
71      * Either restore fragment from saved state or create new instance.
72      */
initFragment(FragmentManager fragmentManager, @Page String page)73     private void initFragment(FragmentManager fragmentManager, @Page String page) {
74         mFragmentTag = makeFragmentTag(page);
75         mFragment = fragmentManager.findFragmentByTag(mFragmentTag);
76         if (mFragment == null) {
77             mFragment = mFactory.createFragment(page);
78             mWasFragmentRestored = false;
79             return;
80         }
81         mWasFragmentRestored = true;
82     }
83 
84     /**
85      * Returns true if the fragment for this tab is restored from a saved state.
86      */
wasFragmentRestored()87     public boolean wasFragmentRestored() {
88         return mWasFragmentRestored;
89     }
90 
91     /**
92      * Returns the fragment for this tab.
93      */
getFragment()94     public Fragment getFragment() {
95         return mFragment;
96     }
97 
98     /**
99      * Returns the fragment tag for this tab.
100      */
getFragmentTag()101     public String getFragmentTag() {
102         return mFragmentTag;
103     }
104 
makeFragmentTag(@age String page)105     private String makeFragmentTag(@Page String page) {
106         return String.format("%s:%s", getClass().getSimpleName(), page);
107     }
108 
109     /**
110      * Responsible for creating the top tab items and their fragments.
111      */
112     public static class Factory {
113 
114         private static final ImmutableMap<String, Integer> TAB_LABELS =
115                 ImmutableMap.<String, Integer>builder()
116                         .put(Page.FAVORITES, R.string.favorites_title)
117                         .put(Page.CALL_HISTORY, R.string.call_history_title)
118                         .put(Page.CONTACTS, R.string.contacts_title)
119                         .put(Page.DIAL_PAD, R.string.dialpad_title)
120                         .build();
121 
122         private static final ImmutableMap<String, Integer> TAB_ICONS =
123                 ImmutableMap.<String, Integer>builder()
124                         .put(Page.FAVORITES, R.drawable.ic_favorite)
125                         .put(Page.CALL_HISTORY, R.drawable.ic_history)
126                         .put(Page.CONTACTS, R.drawable.ic_contact)
127                         .put(Page.DIAL_PAD, R.drawable.ic_dialpad)
128                         .build();
129 
130         private final FragmentManager mFragmentManager;
131         private final Map<String, Integer> mTabPageIndexMap;
132         private final String[] mTabs;
133 
Factory(Context context, FragmentManager fragmentManager)134         public Factory(Context context, FragmentManager fragmentManager) {
135             mFragmentManager = fragmentManager;
136 
137             mTabs = context.getResources().getStringArray(R.array.tabs_config);
138 
139             mTabPageIndexMap = new HashMap<>();
140             for (int i = 0; i < getTabCount(); i++) {
141                 mTabPageIndexMap.put(mTabs[i], i);
142             }
143         }
144 
createFragment(@age String page)145         private Fragment createFragment(@Page String page) {
146             switch (page) {
147                 case Page.FAVORITES:
148                     return FavoriteFragment.newInstance();
149                 case Page.CALL_HISTORY:
150                     return CallHistoryFragment.newInstance();
151                 case Page.CONTACTS:
152                     return ContactListFragment.newInstance();
153                 case Page.DIAL_PAD:
154                     return DialpadFragment.newPlaceCallDialpad();
155                 default:
156                     throw new UnsupportedOperationException("Tab is not supported.");
157             }
158         }
159 
160         /**
161          * Create the tab for the given {@param tabIndex}
162          */
createTab(Context context, int tabIndex)163         public TelecomPageTab createTab(Context context, int tabIndex) {
164             String page = mTabs[tabIndex];
165             TelecomPageTab telecomPageTab = new TelecomPageTab(
166                     context.getDrawable(TAB_ICONS.get(page)),
167                     context.getString(TAB_LABELS.get(page)), this);
168             telecomPageTab.initFragment(mFragmentManager, page);
169             return telecomPageTab;
170         }
171 
getTabCount()172         public int getTabCount() {
173             return mTabs.length;
174         }
175 
176         /**
177          * Returns the index for the given {@param page}
178          */
getTabIndex(@age String page)179         public int getTabIndex(@Page String page) {
180             return mTabPageIndexMap.containsKey(page) ? mTabPageIndexMap.get(page) : -1;
181         }
182     }
183 }
184