/* * Copyright (C) 2016 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.incallui.incall.impl; import android.support.annotation.NonNull; import com.android.dialer.common.Assert; import com.android.incallui.incall.impl.MappedButtonConfig.MappingInfo; import com.android.incallui.incall.protocol.InCallButtonIds; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import javax.annotation.concurrent.Immutable; /** * Determines where logical buttons should be placed in the {@link InCallFragment} based on the * provided mapping. * *

The button placement returned by a call to {@link #getButtonPlacement(int, Set)} is created as * follows: one button is placed at each UI slot, using the provided mapping to resolve conflicts. * Any allowed buttons that were not chosen for their desired slot are filled in at the end of the * list until it becomes the proper size. */ @Immutable final class ButtonChooser { private final MappedButtonConfig config; public ButtonChooser(@NonNull MappedButtonConfig config) { this.config = Assert.isNotNull(config); } /** * Returns the buttons that should be shown in the {@link InCallFragment}, ordered appropriately. * * @param numUiButtons the number of ui buttons available. * @param allowedButtons the {@link InCallButtonIds} that can be shown. * @param disabledButtons the {@link InCallButtonIds} that can be shown but in disabled stats. * @return an immutable list whose size is at most {@code numUiButtons}, containing the buttons to * show. */ @NonNull public List getButtonPlacement( int numUiButtons, @NonNull Set allowedButtons, @NonNull Set disabledButtons) { Assert.isNotNull(allowedButtons); Assert.checkArgument(numUiButtons >= 0); if (numUiButtons == 0 || allowedButtons.isEmpty()) { return Collections.emptyList(); } List placedButtons = new ArrayList<>(); List conflicts = new ArrayList<>(); placeButtonsInSlots(numUiButtons, allowedButtons, placedButtons, conflicts); placeConflictsInOpenSlots( numUiButtons, allowedButtons, disabledButtons, placedButtons, conflicts); return Collections.unmodifiableList(placedButtons); } private void placeButtonsInSlots( int numUiButtons, @NonNull Set allowedButtons, @NonNull List placedButtons, @NonNull List conflicts) { List configuredSlots = config.getOrderedMappedSlots(); for (int i = 0; i < configuredSlots.size() && placedButtons.size() < numUiButtons; ++i) { int slotNumber = configuredSlots.get(i); List potentialButtons = config.getButtonsForSlot(slotNumber); Collections.sort(potentialButtons, config.getSlotComparator()); for (int j = 0; j < potentialButtons.size(); ++j) { if (allowedButtons.contains(potentialButtons.get(j))) { placedButtons.add(potentialButtons.get(j)); conflicts.addAll(potentialButtons.subList(j + 1, potentialButtons.size())); break; } } } } private void placeConflictsInOpenSlots( int numUiButtons, @NonNull Set allowedButtons, @NonNull Set disabledButtons, @NonNull List placedButtons, @NonNull List conflicts) { Collections.sort(conflicts, config.getConflictComparator()); for (Integer conflict : conflicts) { if (placedButtons.size() >= numUiButtons) { return; } // If the conflict button is allowed but disabled, don't place it since it probably will // move when it's enabled. if (!allowedButtons.contains(conflict) || disabledButtons.contains(conflict)) { continue; } if (isMutuallyExclusiveButtonAvailable( config.lookupMappingInfo(conflict).getMutuallyExclusiveButton(), allowedButtons)) { continue; } placedButtons.add(conflict); } } private boolean isMutuallyExclusiveButtonAvailable( int mutuallyExclusiveButton, @NonNull Set allowedButtons) { if (mutuallyExclusiveButton == MappingInfo.NO_MUTUALLY_EXCLUSIVE_BUTTON_SET) { return false; } if (allowedButtons.contains(mutuallyExclusiveButton)) { return true; } return false; } }