1 /* 2 * Copyright (C) 2017 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.app.list; 18 19 import android.app.Fragment; 20 import android.app.FragmentManager; 21 import android.support.annotation.IntDef; 22 import android.support.v13.app.FragmentPagerAdapter; 23 import android.view.ViewGroup; 24 import com.android.dialer.app.calllog.CallLogFragment; 25 import com.android.dialer.app.calllog.VisualVoicemailCallLogFragment; 26 import com.android.dialer.common.Assert; 27 import com.android.dialer.common.LogUtil; 28 import com.android.dialer.contactsfragment.ContactsFragment; 29 import com.android.dialer.contactsfragment.ContactsFragment.Header; 30 import com.android.dialer.database.CallLogQueryHandler; 31 import com.android.dialer.util.ViewUtil; 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import java.util.List; 37 38 /** ViewPager adapter for {@link com.android.dialer.app.DialtactsActivity}. */ 39 public class DialtactsPagerAdapter extends FragmentPagerAdapter { 40 41 /** IntDef for indices of ViewPager tabs. */ 42 @Retention(RetentionPolicy.SOURCE) 43 @IntDef({TAB_INDEX_SPEED_DIAL, TAB_INDEX_HISTORY, TAB_INDEX_ALL_CONTACTS, TAB_INDEX_VOICEMAIL}) 44 public @interface TabIndex {} 45 46 public static final int TAB_INDEX_SPEED_DIAL = 0; 47 public static final int TAB_INDEX_HISTORY = 1; 48 public static final int TAB_INDEX_ALL_CONTACTS = 2; 49 public static final int TAB_INDEX_VOICEMAIL = 3; 50 public static final int TAB_COUNT_DEFAULT = 3; 51 public static final int TAB_COUNT_WITH_VOICEMAIL = 4; 52 53 private final List<Fragment> fragments = new ArrayList<>(); 54 private final String[] tabTitles; 55 private OldSpeedDialFragment oldSpeedDialFragment; 56 private CallLogFragment callLogFragment; 57 private ContactsFragment contactsFragment; 58 private CallLogFragment voicemailFragment; 59 60 private boolean hasActiveVoicemailProvider; 61 DialtactsPagerAdapter( FragmentManager fm, String[] tabTitles, boolean hasVoicemailProvider)62 public DialtactsPagerAdapter( 63 FragmentManager fm, String[] tabTitles, boolean hasVoicemailProvider) { 64 super(fm); 65 this.tabTitles = tabTitles; 66 hasActiveVoicemailProvider = hasVoicemailProvider; 67 fragments.addAll(Collections.nCopies(TAB_COUNT_WITH_VOICEMAIL, null)); 68 } 69 70 @Override getItemId(int position)71 public long getItemId(int position) { 72 return getRtlPosition(position); 73 } 74 75 @Override getItem(int position)76 public Fragment getItem(int position) { 77 LogUtil.d("ViewPagerAdapter.getItem", "position: %d", position); 78 switch (getRtlPosition(position)) { 79 case TAB_INDEX_SPEED_DIAL: 80 if (oldSpeedDialFragment == null) { 81 oldSpeedDialFragment = new OldSpeedDialFragment(); 82 } 83 return oldSpeedDialFragment; 84 case TAB_INDEX_HISTORY: 85 if (callLogFragment == null) { 86 callLogFragment = new CallLogFragment(CallLogQueryHandler.CALL_TYPE_ALL); 87 } 88 return callLogFragment; 89 case TAB_INDEX_ALL_CONTACTS: 90 if (contactsFragment == null) { 91 contactsFragment = ContactsFragment.newInstance(Header.ADD_CONTACT); 92 } 93 return contactsFragment; 94 case TAB_INDEX_VOICEMAIL: 95 if (voicemailFragment == null) { 96 voicemailFragment = new VisualVoicemailCallLogFragment(); 97 LogUtil.v( 98 "ViewPagerAdapter.getItem", 99 "new VisualVoicemailCallLogFragment: %s", 100 voicemailFragment); 101 } 102 return voicemailFragment; 103 default: 104 throw Assert.createIllegalStateFailException("No fragment at position " + position); 105 } 106 } 107 108 @Override instantiateItem(ViewGroup container, int position)109 public Fragment instantiateItem(ViewGroup container, int position) { 110 LogUtil.d("ViewPagerAdapter.instantiateItem", "position: %d", position); 111 // On rotation the FragmentManager handles rotation. Therefore getItem() isn't called. 112 // Copy the fragments that the FragmentManager finds so that we can store them in 113 // instance variables for later. 114 final Fragment fragment = (Fragment) super.instantiateItem(container, position); 115 if (fragment instanceof OldSpeedDialFragment) { 116 oldSpeedDialFragment = (OldSpeedDialFragment) fragment; 117 } else if (fragment instanceof CallLogFragment && position == TAB_INDEX_HISTORY) { 118 callLogFragment = (CallLogFragment) fragment; 119 } else if (fragment instanceof ContactsFragment) { 120 contactsFragment = (ContactsFragment) fragment; 121 } else if (fragment instanceof CallLogFragment && position == TAB_INDEX_VOICEMAIL) { 122 voicemailFragment = (CallLogFragment) fragment; 123 LogUtil.v("ViewPagerAdapter.instantiateItem", voicemailFragment.toString()); 124 } 125 fragments.set(position, fragment); 126 return fragment; 127 } 128 129 /** 130 * When {@link android.support.v4.view.PagerAdapter#notifyDataSetChanged} is called, this method 131 * is called on all pages to determine whether they need to be recreated. When the voicemail tab 132 * is removed, the view needs to be recreated by returning POSITION_NONE. If notifyDataSetChanged 133 * is called for some other reason, the voicemail tab is recreated only if it is active. All other 134 * tabs do not need to be recreated and POSITION_UNCHANGED is returned. 135 */ 136 @Override getItemPosition(Object object)137 public int getItemPosition(Object object) { 138 return !hasActiveVoicemailProvider && fragments.indexOf(object) == TAB_INDEX_VOICEMAIL 139 ? POSITION_NONE 140 : POSITION_UNCHANGED; 141 } 142 143 @Override getCount()144 public int getCount() { 145 return hasActiveVoicemailProvider ? TAB_COUNT_WITH_VOICEMAIL : TAB_COUNT_DEFAULT; 146 } 147 148 @Override getPageTitle(@abIndex int position)149 public CharSequence getPageTitle(@TabIndex int position) { 150 return tabTitles[position]; 151 } 152 getRtlPosition(int position)153 public int getRtlPosition(int position) { 154 if (ViewUtil.isRtl()) { 155 return getCount() - 1 - position; 156 } 157 return position; 158 } 159 removeVoicemailFragment(FragmentManager manager)160 public void removeVoicemailFragment(FragmentManager manager) { 161 if (voicemailFragment != null) { 162 manager.beginTransaction().remove(voicemailFragment).commitAllowingStateLoss(); 163 voicemailFragment = null; 164 } 165 } 166 hasActiveVoicemailProvider()167 public boolean hasActiveVoicemailProvider() { 168 return hasActiveVoicemailProvider; 169 } 170 setHasActiveVoicemailProvider(boolean hasActiveVoicemailProvider)171 public void setHasActiveVoicemailProvider(boolean hasActiveVoicemailProvider) { 172 this.hasActiveVoicemailProvider = hasActiveVoicemailProvider; 173 } 174 } 175