summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/main/impl/OldMainActivityPeer.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/main/impl/OldMainActivityPeer.java')
-rw-r--r--java/com/android/dialer/main/impl/OldMainActivityPeer.java815
1 files changed, 815 insertions, 0 deletions
diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
new file mode 100644
index 000000000..489de1a64
--- /dev/null
+++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
@@ -0,0 +1,815 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.dialer.main.impl;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.KeyguardManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.QuickContact;
+import android.support.annotation.Nullable;
+import android.support.design.widget.FloatingActionButton;
+import android.view.View;
+import android.widget.ImageView;
+import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
+import com.android.dialer.app.calllog.CallLogAdapter;
+import com.android.dialer.app.calllog.CallLogFragment;
+import com.android.dialer.app.calllog.CallLogFragment.CallLogFragmentListener;
+import com.android.dialer.app.calllog.CallLogNotificationsService;
+import com.android.dialer.app.calllog.VisualVoicemailCallLogFragment;
+import com.android.dialer.app.list.DragDropController;
+import com.android.dialer.app.list.OldSpeedDialFragment;
+import com.android.dialer.app.list.OnDragDropListener;
+import com.android.dialer.app.list.OnListFragmentScrolledListener;
+import com.android.dialer.app.list.PhoneFavoriteSquareTileView;
+import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.callintent.CallSpecificAppData;
+import com.android.dialer.common.FragmentUtils.FragmentUtilListener;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.common.concurrent.UiListener;
+import com.android.dialer.compat.CompatUtils;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.dialer.constants.ActivityRequestCodes;
+import com.android.dialer.contactsfragment.ContactsFragment;
+import com.android.dialer.contactsfragment.ContactsFragment.Header;
+import com.android.dialer.contactsfragment.ContactsFragment.OnContactSelectedListener;
+import com.android.dialer.database.CallLogQueryHandler;
+import com.android.dialer.database.Database;
+import com.android.dialer.dialpadview.DialpadFragment;
+import com.android.dialer.dialpadview.DialpadFragment.DialpadListener;
+import com.android.dialer.dialpadview.DialpadFragment.LastOutgoingCallCallback;
+import com.android.dialer.dialpadview.DialpadFragment.OnDialpadQueryChangedListener;
+import com.android.dialer.interactions.PhoneNumberInteraction;
+import com.android.dialer.main.MainActivityPeer;
+import com.android.dialer.main.impl.BottomNavBar.OnBottomNavTabSelectedListener;
+import com.android.dialer.main.impl.BottomNavBar.TabIndex;
+import com.android.dialer.main.impl.toolbar.MainToolbar;
+import com.android.dialer.postcall.PostCall;
+import com.android.dialer.precall.PreCall;
+import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener;
+import com.android.dialer.smartdial.util.SmartDialPrefix;
+import com.android.dialer.storage.StorageComponent;
+import com.android.dialer.telecom.TelecomUtil;
+import com.android.dialer.util.DialerUtils;
+import com.android.dialer.util.TransactionSafeActivity;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * OldMainActivityPeer which implements all of the old fragments we know and love <3
+ *
+ * <p>TODO(calderwoodra): Deprecate this class when we launch NewmainActivityPeer.
+ */
+public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListener {
+
+ private static final String KEY_SAVED_LANGUAGE_CODE = "saved_language_code";
+ private static final String KEY_CURRENT_TAB = "current_tab";
+ private static final String KEY_LAST_TAB = "last_tab";
+
+ private final MainActivity mainActivity;
+
+ // Contacts
+ private MainOnContactSelectedListener onContactSelectedListener;
+
+ // Dialpad and Search
+ private MainDialpadFragmentHost dialpadFragmentHostInterface;
+ private MainSearchController searchController;
+ private MainOnDialpadQueryChangedListener onDialpadQueryChangedListener;
+ private MainDialpadListener dialpadListener;
+ private MainSearchFragmentListener searchFragmentListener;
+
+ // Action Mode
+ private MainCallLogAdapterOnActionModeStateChangedListener
+ callLogAdapterOnActionModeStateChangedListener;
+
+ // Call Log
+ private MainCallLogHost callLogHostInterface;
+ private MainCallLogFragmentListener callLogFragmentListener;
+ private MainOnListFragmentScrolledListener onListFragmentScrolledListener;
+
+ // Speed Dial
+ private MainOnPhoneNumberPickerActionListener onPhoneNumberPickerActionListener;
+ private MainOldSpeedDialFragmentHostInterface oldSpeedDialFragmentHostInterface;
+ private MainOnDragDropListener onDragDropListener;
+
+ /** Language the device was in last time {@link #onSaveInstanceState(Bundle)} was called. */
+ private String savedLanguageCode;
+
+ private LastTabController lastTabController;
+
+ private BottomNavBar bottomNav;
+ private View snackbarContainer;
+ private UiListener<String> getLastOutgoingCallListener;
+
+ public OldMainActivityPeer(MainActivity mainActivity) {
+ this.mainActivity = mainActivity;
+ }
+
+ @Override
+ public void onActivityCreate(Bundle savedInstanceState) {
+ mainActivity.setContentView(R.layout.main_activity);
+ initUiListeners();
+ initLayout(savedInstanceState);
+ SmartDialPrefix.initializeNanpSettings(mainActivity);
+ }
+
+ private void initUiListeners() {
+ getLastOutgoingCallListener =
+ DialerExecutorComponent.get(mainActivity)
+ .createUiListener(mainActivity.getFragmentManager(), "Query last phone number");
+ }
+
+ private void initLayout(Bundle savedInstanceState) {
+ onContactSelectedListener = new MainOnContactSelectedListener(mainActivity);
+ dialpadFragmentHostInterface = new MainDialpadFragmentHost();
+
+ snackbarContainer = mainActivity.findViewById(R.id.coordinator_layout);
+
+ FloatingActionButton fab = mainActivity.findViewById(R.id.fab);
+ fab.setOnClickListener(v -> searchController.showDialpad(true));
+
+ MainToolbar toolbar = mainActivity.findViewById(R.id.toolbar);
+ mainActivity.setSupportActionBar(mainActivity.findViewById(R.id.toolbar));
+
+ bottomNav = mainActivity.findViewById(R.id.bottom_nav_bar);
+ MainBottomNavBarBottomNavTabListener bottomNavTabListener =
+ new MainBottomNavBarBottomNavTabListener(mainActivity.getFragmentManager());
+ bottomNav.addOnTabSelectedListener(bottomNavTabListener);
+
+ callLogFragmentListener =
+ new MainCallLogFragmentListener(mainActivity, mainActivity.getContentResolver(), bottomNav);
+ bottomNav.addOnTabSelectedListener(callLogFragmentListener);
+
+ searchController = new MainSearchController(mainActivity, bottomNav, fab, toolbar);
+ toolbar.setSearchBarListener(searchController);
+
+ onDialpadQueryChangedListener = new MainOnDialpadQueryChangedListener(searchController);
+ dialpadListener =
+ new MainDialpadListener(mainActivity, searchController, getLastOutgoingCallListener);
+ searchFragmentListener = new MainSearchFragmentListener(searchController);
+ callLogAdapterOnActionModeStateChangedListener =
+ new MainCallLogAdapterOnActionModeStateChangedListener();
+ callLogHostInterface = new MainCallLogHost(searchController, fab);
+
+ onListFragmentScrolledListener = new MainOnListFragmentScrolledListener(snackbarContainer);
+ onPhoneNumberPickerActionListener = new MainOnPhoneNumberPickerActionListener(mainActivity);
+ oldSpeedDialFragmentHostInterface =
+ new MainOldSpeedDialFragmentHostInterface(
+ bottomNav, mainActivity.findViewById(R.id.contact_tile_drag_shadow_overlay));
+ onDragDropListener = new MainOnDragDropListener();
+
+ lastTabController = new LastTabController(mainActivity, bottomNav);
+
+ // Restore our view state if needed, else initialize as if the app opened for the first time
+ if (savedInstanceState != null) {
+ savedLanguageCode = savedInstanceState.getString(KEY_SAVED_LANGUAGE_CODE);
+ searchController.onRestoreInstanceState(savedInstanceState);
+ bottomNav.selectTab(savedInstanceState.getInt(KEY_CURRENT_TAB));
+ } else {
+ lastTabController.selectLastTab();
+ }
+ }
+
+ @Override
+ public void onNewIntent(Intent intent) {
+ lastTabController.selectLastTab();
+ }
+
+ @Override
+ public void onActivityResume() {
+ callLogFragmentListener.onActivityResume();
+ // Start the thread that updates the smart dial database if the activity is recreated with a
+ // language change.
+ boolean forceUpdate =
+ !CompatUtils.getLocale(mainActivity).getISO3Language().equals(savedLanguageCode);
+ Database.get(mainActivity)
+ .getDatabaseHelper(mainActivity)
+ .startSmartDialUpdateThread(forceUpdate);
+ showPostCallPrompt();
+ }
+
+ @Override
+ public void onActivityStop() {
+ lastTabController.onActivityStop();
+ callLogFragmentListener.onActivityStop(
+ mainActivity.isChangingConfigurations(),
+ mainActivity.getSystemService(KeyguardManager.class).isKeyguardLocked());
+ }
+
+ private void showPostCallPrompt() {
+ if (TelecomUtil.isInManagedCall(mainActivity)) {
+ // No prompt to show if the user is in a call
+ return;
+ }
+
+ if (searchController.isInSearch()) {
+ // Don't show the prompt if we're in the search ui
+ return;
+ }
+
+ PostCall.promptUserForMessageIfNecessary(mainActivity, snackbarContainer);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle bundle) {
+ bundle.putString(
+ KEY_SAVED_LANGUAGE_CODE, CompatUtils.getLocale(mainActivity).getISO3Language());
+ bundle.putInt(KEY_CURRENT_TAB, bottomNav.getSelectedTab());
+ searchController.onSaveInstanceState(bundle);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == ActivityRequestCodes.DIALTACTS_VOICE_SEARCH) {
+ searchController.onVoiceResults(resultCode, data);
+ } else {
+ LogUtil.e("MainActivity.onActivityResult", "Unknown request code: " + requestCode);
+ }
+ }
+
+ @Override
+ public boolean onBackPressed() {
+ if (searchController.onBackPressed()) {
+ return true;
+ }
+ return false;
+ }
+
+ @Nullable
+ @Override
+ @SuppressWarnings("unchecked") // Casts are checked using runtime methods
+ public <T> T getImpl(Class<T> callbackInterface) {
+ if (callbackInterface.isInstance(onContactSelectedListener)) {
+ return (T) onContactSelectedListener;
+ } else if (callbackInterface.isInstance(onDialpadQueryChangedListener)) {
+ return (T) onDialpadQueryChangedListener;
+ } else if (callbackInterface.isInstance(dialpadListener)) {
+ return (T) dialpadListener;
+ } else if (callbackInterface.isInstance(dialpadFragmentHostInterface)) {
+ return (T) dialpadFragmentHostInterface;
+ } else if (callbackInterface.isInstance(searchFragmentListener)) {
+ return (T) searchFragmentListener;
+ } else if (callbackInterface.isInstance(callLogAdapterOnActionModeStateChangedListener)) {
+ return (T) callLogAdapterOnActionModeStateChangedListener;
+ } else if (callbackInterface.isInstance(callLogHostInterface)) {
+ return (T) callLogHostInterface;
+ } else if (callbackInterface.isInstance(callLogFragmentListener)) {
+ return (T) callLogFragmentListener;
+ } else if (callbackInterface.isInstance(onListFragmentScrolledListener)) {
+ return (T) onListFragmentScrolledListener;
+ } else if (callbackInterface.isInstance(onPhoneNumberPickerActionListener)) {
+ return (T) onPhoneNumberPickerActionListener;
+ } else if (callbackInterface.isInstance(oldSpeedDialFragmentHostInterface)) {
+ return (T) oldSpeedDialFragmentHostInterface;
+ } else if (callbackInterface.isInstance(onDragDropListener)) {
+ return (T) onDragDropListener;
+ } else {
+ return null;
+ }
+ }
+
+ /** @see OnContactSelectedListener */
+ private static final class MainOnContactSelectedListener implements OnContactSelectedListener {
+
+ private final Context context;
+
+ MainOnContactSelectedListener(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public void onContactSelected(ImageView photo, Uri contactUri, long contactId) {
+ // TODO(calderwoodra): Add impression logging
+ QuickContact.showQuickContact(
+ context, photo, contactUri, QuickContact.MODE_LARGE, null /* excludeMimes */);
+ }
+ }
+
+ /** @see OnDialpadQueryChangedListener */
+ private static final class MainOnDialpadQueryChangedListener
+ implements OnDialpadQueryChangedListener {
+
+ private final MainSearchController searchController;
+
+ MainOnDialpadQueryChangedListener(MainSearchController searchController) {
+ this.searchController = searchController;
+ }
+
+ @Override
+ public void onDialpadQueryChanged(String query) {
+ searchController.onDialpadQueryChanged(query);
+ }
+ }
+
+ /** @see DialpadListener */
+ private static final class MainDialpadListener implements DialpadListener {
+
+ private final MainSearchController searchController;
+ private final Context context;
+ private final UiListener<String> listener;
+
+ MainDialpadListener(
+ Context context, MainSearchController searchController, UiListener<String> uiListener) {
+ this.context = context;
+ this.searchController = searchController;
+ this.listener = uiListener;
+ }
+
+ @Override
+ public void getLastOutgoingCall(LastOutgoingCallCallback callback) {
+ ListenableFuture<String> listenableFuture =
+ DialerExecutorComponent.get(context)
+ .backgroundExecutor()
+ .submit(() -> Calls.getLastOutgoingCall(context));
+ listener.listen(context, listenableFuture, callback::lastOutgoingCall, throwable -> {});
+ }
+
+ @Override
+ public void onDialpadShown() {
+ searchController.onDialpadShown();
+ }
+
+ @Override
+ public void onCallPlacedFromDialpad() {
+ // TODO(calderwoodra): logging
+ }
+ }
+
+ /** @see SearchFragmentListener */
+ private static final class MainSearchFragmentListener implements SearchFragmentListener {
+
+ private final MainSearchController searchController;
+
+ MainSearchFragmentListener(MainSearchController searchController) {
+ this.searchController = searchController;
+ }
+
+ @Override
+ public void onSearchListTouch() {
+ searchController.onSearchListTouch();
+ }
+
+ @Override
+ public void onCallPlacedFromSearch() {
+ // TODO(calderwoodra): logging
+ }
+ }
+
+ /** @see DialpadFragment.HostInterface */
+ private static final class MainDialpadFragmentHost implements DialpadFragment.HostInterface {
+
+ @Override
+ public boolean onDialpadSpacerTouchWithEmptyQuery() {
+ // No-op, just let the clicks fall through to the search list
+ return false;
+ }
+ }
+
+ /** @see CallLogAdapter.OnActionModeStateChangedListener */
+ // TODO(a bug): handle multiselect mode
+ private static final class MainCallLogAdapterOnActionModeStateChangedListener
+ implements CallLogAdapter.OnActionModeStateChangedListener {
+
+ @Override
+ public void onActionModeStateChanged(boolean isEnabled) {}
+
+ @Override
+ public boolean isActionModeStateEnabled() {
+ return false;
+ }
+ }
+
+ /** @see CallLogFragment.HostInterface */
+ private static final class MainCallLogHost implements CallLogFragment.HostInterface {
+
+ private final FloatingActionButton fab;
+ private final MainSearchController searchController;
+
+ MainCallLogHost(MainSearchController searchController, FloatingActionButton fab) {
+ this.searchController = searchController;
+ this.fab = fab;
+ }
+
+ @Override
+ public void showDialpad() {
+ searchController.showDialpad(true);
+ }
+
+ @Override
+ public void enableFloatingButton(boolean enabled) {
+ if (enabled) {
+ fab.show();
+ } else {
+ fab.hide();
+ }
+ }
+ }
+
+ /**
+ * Handles the logic for callbacks from:
+ *
+ * <ul>
+ * <li>{@link CallLogFragment}
+ * <li>{@link CallLogQueryHandler}
+ * <li>{@link BottomNavBar}
+ * </ul>
+ *
+ * This mainly entails:
+ *
+ * <ul>
+ * <li>Handling querying for missed calls/unread voicemails.
+ * <li>Displaying a badge to the user in the bottom nav when there are missed calls/unread
+ * voicemails present.
+ * <li>Marking missed calls as read when appropriate. See {@link
+ * #markMissedCallsAsReadAndRemoveNotification()}
+ * <li>TODO(calderwoodra): multiselect
+ * <li>TODO(calderwoodra): voicemail status
+ * </ul>
+ *
+ * @see CallLogFragmentListener
+ * @see CallLogQueryHandler.Listener
+ * @see OnBottomNavTabSelectedListener
+ */
+ private static final class MainCallLogFragmentListener
+ implements CallLogFragmentListener,
+ CallLogQueryHandler.Listener,
+ OnBottomNavTabSelectedListener {
+
+ private final CallLogQueryHandler callLogQueryHandler;
+ private final BottomNavBar bottomNavBar;
+ private final Context context;
+
+ private @TabIndex int currentTab = TabIndex.SPEED_DIAL;
+ private long timeSelected = -1;
+ private boolean activityIsAlive;
+
+ MainCallLogFragmentListener(
+ Context context, ContentResolver contentResolver, BottomNavBar bottomNavBar) {
+ callLogQueryHandler = new CallLogQueryHandler(context, contentResolver, this);
+ this.bottomNavBar = bottomNavBar;
+ this.context = context;
+ }
+
+ @Override
+ public void updateTabUnreadCounts() {
+ callLogQueryHandler.fetchMissedCallsUnreadCount();
+ callLogQueryHandler.fetchVoicemailUnreadCount();
+ }
+
+ @Override
+ public void showMultiSelectRemoveView(boolean show) {
+ // TODO(a bug): handle multiselect mode
+ }
+
+ @Override
+ public void onVoicemailStatusFetched(Cursor statusCursor) {
+ // TODO(calderwoodra): handle this when voicemail is implemented
+ }
+
+ @Override
+ public void onVoicemailUnreadCountFetched(Cursor cursor) {
+ if (activityIsAlive) {
+ bottomNavBar.setNotificationCount(TabIndex.VOICEMAIL, cursor.getCount());
+ }
+ cursor.close();
+ }
+
+ @Override
+ public void onMissedCallsUnreadCountFetched(Cursor cursor) {
+ if (activityIsAlive) {
+ bottomNavBar.setNotificationCount(TabIndex.CALL_LOG, cursor.getCount());
+ }
+ cursor.close();
+ }
+
+ @Override
+ public boolean onCallsFetched(Cursor combinedCursor) {
+ // Return false; did not take ownership of cursor
+ return false;
+ }
+
+ @Override
+ public void onSpeedDialSelected() {
+ setCurrentTab(TabIndex.SPEED_DIAL);
+ }
+
+ @Override
+ public void onCallLogSelected() {
+ setCurrentTab(TabIndex.CALL_LOG);
+ }
+
+ @Override
+ public void onContactsSelected() {
+ setCurrentTab(TabIndex.CONTACTS);
+ }
+
+ @Override
+ public void onVoicemailSelected() {
+ setCurrentTab(TabIndex.VOICEMAIL);
+ }
+
+ private void markMissedCallsAsReadAndRemoveNotification() {
+ callLogQueryHandler.markMissedCallsAsRead();
+ CallLogNotificationsService.cancelAllMissedCalls(context);
+ }
+
+ private void setCurrentTab(@TabIndex int tabIndex) {
+ if (currentTab == TabIndex.CALL_LOG && tabIndex != TabIndex.CALL_LOG) {
+ markMissedCallsAsReadAndRemoveNotification();
+ }
+ currentTab = tabIndex;
+ timeSelected = System.currentTimeMillis();
+ }
+
+ public void onActivityResume() {
+ activityIsAlive = true;
+ callLogQueryHandler.fetchVoicemailStatus();
+ callLogQueryHandler.fetchMissedCallsUnreadCount();
+ // Reset the tab on resume to restart the timer
+ setCurrentTab(bottomNavBar.getSelectedTab());
+ }
+
+ /** Should be called when {@link Activity#onStop()} is called. */
+ public void onActivityStop(boolean changingConfigurations, boolean keyguardLocked) {
+ activityIsAlive = false;
+ if (viewedCallLogTabPastTimeThreshold() && !changingConfigurations && !keyguardLocked) {
+ markMissedCallsAsReadAndRemoveNotification();
+ }
+ }
+
+ /**
+ * Returns true if the user has been (and still is) on the history tab for long than the
+ * threshold.
+ */
+ private boolean viewedCallLogTabPastTimeThreshold() {
+ return currentTab == TabIndex.CALL_LOG
+ && timeSelected != -1
+ && System.currentTimeMillis() - timeSelected > TimeUnit.SECONDS.toMillis(3);
+ }
+ }
+
+ /** @see OnListFragmentScrolledListener */
+ private static final class MainOnListFragmentScrolledListener
+ implements OnListFragmentScrolledListener {
+
+ private final View parentLayout;
+
+ MainOnListFragmentScrolledListener(View parentLayout) {
+ this.parentLayout = parentLayout;
+ }
+
+ @Override
+ public void onListFragmentScrollStateChange(int scrollState) {
+ DialerUtils.hideInputMethod(parentLayout);
+ }
+
+ @Override
+ public void onListFragmentScroll(
+ int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ // TODO: No-op for now. This should eventually show/hide the actionBar based on
+ // interactions with the ListsFragments.
+ }
+ }
+
+ /** @see OnPhoneNumberPickerActionListener */
+ private static final class MainOnPhoneNumberPickerActionListener
+ implements OnPhoneNumberPickerActionListener {
+
+ private final TransactionSafeActivity activity;
+
+ MainOnPhoneNumberPickerActionListener(TransactionSafeActivity activity) {
+ this.activity = activity;
+ }
+
+ @Override
+ public void onPickDataUri(
+ Uri dataUri, boolean isVideoCall, CallSpecificAppData callSpecificAppData) {
+ PhoneNumberInteraction.startInteractionForPhoneCall(
+ activity, dataUri, isVideoCall, callSpecificAppData);
+ }
+
+ @Override
+ public void onPickPhoneNumber(
+ String phoneNumber, boolean isVideoCall, CallSpecificAppData callSpecificAppData) {
+ if (phoneNumber == null) {
+ // Invalid phone number, but let the call go through so that InCallUI can show
+ // an error message.
+ phoneNumber = "";
+ }
+ PreCall.start(
+ activity,
+ new CallIntentBuilder(phoneNumber, callSpecificAppData)
+ .setIsVideoCall(isVideoCall)
+ .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()));
+ }
+
+ @Override
+ public void onHomeInActionBarSelected() {
+ // TODO(calderwoodra): investigate if we need to exit search here
+ // PhoneNumberPickerFragment#onOptionsItemSelected
+ }
+ }
+
+ /** @see OldSpeedDialFragment.HostInterface */
+ private static final class MainOldSpeedDialFragmentHostInterface
+ implements OldSpeedDialFragment.HostInterface {
+
+ private final BottomNavBar bottomNavBar;
+ private final ImageView dragShadowOverlay;
+
+ // TODO(calderwoodra): Use this for drag and drop
+ @SuppressWarnings("unused")
+ private DragDropController dragDropController;
+
+ MainOldSpeedDialFragmentHostInterface(BottomNavBar bottomNavBar, ImageView dragShadowOverlay) {
+ this.bottomNavBar = bottomNavBar;
+ this.dragShadowOverlay = dragShadowOverlay;
+ }
+
+ @Override
+ public void setDragDropController(DragDropController dragDropController) {
+ this.dragDropController = dragDropController;
+ }
+
+ @Override
+ public void showAllContactsTab() {
+ bottomNavBar.selectTab(TabIndex.CONTACTS);
+ }
+
+ @Override
+ public ImageView getDragShadowOverlay() {
+ return dragShadowOverlay;
+ }
+ }
+
+ /** @see com.android.dialer.app.list.OnDragDropListener */
+ // TODO(calderwoodra): implement drag and drop
+ private static final class MainOnDragDropListener implements OnDragDropListener {
+
+ @Override
+ public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {}
+
+ @Override
+ public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {}
+
+ @Override
+ public void onDragFinished(int x, int y) {}
+
+ @Override
+ public void onDroppedOnRemove() {}
+ }
+
+ /**
+ * Implementation of {@link OnBottomNavTabSelectedListener} that handles logic for showing each of
+ * the main tabs.
+ */
+ private static final class MainBottomNavBarBottomNavTabListener
+ implements OnBottomNavTabSelectedListener {
+
+ private static final String SPEED_DIAL_TAG = "speed_dial";
+ private static final String CALL_LOG_TAG = "call_log";
+ private static final String CONTACTS_TAG = "contacts";
+ private static final String VOICEMAIL_TAG = "voicemail";
+
+ private final FragmentManager fragmentManager;
+
+ private MainBottomNavBarBottomNavTabListener(FragmentManager fragmentManager) {
+ this.fragmentManager = fragmentManager;
+ }
+
+ @Override
+ public void onSpeedDialSelected() {
+ hideAllFragments();
+ Fragment fragment = fragmentManager.findFragmentByTag(SPEED_DIAL_TAG);
+ if (fragment == null) {
+ fragmentManager
+ .beginTransaction()
+ .add(R.id.fragment_container, new OldSpeedDialFragment(), SPEED_DIAL_TAG)
+ .commit();
+ } else {
+ fragmentManager.beginTransaction().show(fragment).commit();
+ }
+ }
+
+ @Override
+ public void onCallLogSelected() {
+ hideAllFragments();
+ CallLogFragment fragment = (CallLogFragment) fragmentManager.findFragmentByTag(CALL_LOG_TAG);
+ if (fragment == null) {
+ fragmentManager
+ .beginTransaction()
+ .add(R.id.fragment_container, new CallLogFragment(), CALL_LOG_TAG)
+ .commit();
+ } else {
+ fragmentManager.beginTransaction().show(fragment).commit();
+ }
+ }
+
+ @Override
+ public void onContactsSelected() {
+ hideAllFragments();
+ ContactsFragment fragment =
+ (ContactsFragment) fragmentManager.findFragmentByTag(CONTACTS_TAG);
+ if (fragment == null) {
+ fragmentManager
+ .beginTransaction()
+ .add(
+ R.id.fragment_container,
+ ContactsFragment.newInstance(Header.ADD_CONTACT),
+ CONTACTS_TAG)
+ .commit();
+ } else {
+ fragmentManager.beginTransaction().show(fragment).commit();
+ }
+ }
+
+ @Override
+ public void onVoicemailSelected() {
+ hideAllFragments();
+ VisualVoicemailCallLogFragment fragment =
+ (VisualVoicemailCallLogFragment) fragmentManager.findFragmentByTag(VOICEMAIL_TAG);
+ if (fragment == null) {
+ fragmentManager
+ .beginTransaction()
+ .add(R.id.fragment_container, new VisualVoicemailCallLogFragment(), VOICEMAIL_TAG)
+ .commit();
+ } else {
+ fragmentManager.beginTransaction().show(fragment).commit();
+ }
+ }
+
+ private void hideAllFragments() {
+ android.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
+ if (fragmentManager.findFragmentByTag(SPEED_DIAL_TAG) != null) {
+ transaction.hide(fragmentManager.findFragmentByTag(SPEED_DIAL_TAG));
+ }
+ if (fragmentManager.findFragmentByTag(CALL_LOG_TAG) != null) {
+ // Old CallLogFragment
+ transaction.hide(fragmentManager.findFragmentByTag(CALL_LOG_TAG));
+ }
+ if (fragmentManager.findFragmentByTag(CONTACTS_TAG) != null) {
+ transaction.hide(fragmentManager.findFragmentByTag(CONTACTS_TAG));
+ }
+ if (fragmentManager.findFragmentByTag(VOICEMAIL_TAG) != null) {
+ // Old VisualVoicemailFragment
+ transaction.hide(fragmentManager.findFragmentByTag(VOICEMAIL_TAG));
+ }
+ transaction.commit();
+ }
+ }
+
+ private static final class LastTabController {
+
+ private final Context context;
+ private final BottomNavBar bottomNavBar;
+ private final boolean isEnabled;
+
+ LastTabController(Context context, BottomNavBar bottomNavBar) {
+ this.context = context;
+ this.bottomNavBar = bottomNavBar;
+ isEnabled = ConfigProviderBindings.get(context).getBoolean("last_tab_enabled", false);
+ }
+
+ /** Sets the last tab if the feature is enabled, otherwise defaults to speed dial. */
+ void selectLastTab() {
+ @TabIndex int tabIndex = TabIndex.SPEED_DIAL;
+ if (isEnabled) {
+ tabIndex =
+ StorageComponent.get(context)
+ .unencryptedSharedPrefs()
+ .getInt(KEY_LAST_TAB, TabIndex.SPEED_DIAL);
+ }
+ bottomNavBar.selectTab(tabIndex);
+ }
+
+ void onActivityStop() {
+ StorageComponent.get(context)
+ .unencryptedSharedPrefs()
+ .edit()
+ .putInt(KEY_LAST_TAB, bottomNavBar.getSelectedTab())
+ .apply();
+ }
+ }
+}